pimath 0.0.132 → 0.0.133
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.d.ts +39 -1
- package/package.json +2 -3
- package/dist/pimath.d.ts +0 -39
- package/lib/main.ts +0 -1
- package/lib/maths/algebra/equation.ts +0 -891
- package/lib/maths/algebra/linearSystem.ts +0 -369
- package/lib/maths/algebra/logicalset.ts +0 -183
- package/lib/maths/algebra/monom.ts +0 -1027
- package/lib/maths/algebra/polynom.ts +0 -1537
- package/lib/maths/algebra/rational.ts +0 -244
- package/lib/maths/algebra/study/rationalStudy.ts +0 -287
- package/lib/maths/algebra/study.ts +0 -506
- package/lib/maths/coefficients/fraction.ts +0 -593
- package/lib/maths/coefficients/nthRoot.ts +0 -148
- package/lib/maths/geometry/circle.ts +0 -379
- package/lib/maths/geometry/line.ts +0 -604
- package/lib/maths/geometry/point.ts +0 -215
- package/lib/maths/geometry/triangle.ts +0 -368
- package/lib/maths/geometry/vector.ts +0 -243
- package/lib/maths/numeric.ts +0 -162
- package/lib/maths/numexp.ts +0 -198
- package/lib/maths/randomization/random.ts +0 -80
- package/lib/maths/randomization/randomCore.ts +0 -19
- package/lib/maths/randomization/rndFraction.ts +0 -47
- package/lib/maths/randomization/rndGeometryCircle.ts +0 -50
- package/lib/maths/randomization/rndGeometryLine.ts +0 -53
- package/lib/maths/randomization/rndGeometryPoint.ts +0 -69
- package/lib/maths/randomization/rndHelpers.ts +0 -107
- package/lib/maths/randomization/rndMonom.ts +0 -57
- package/lib/maths/randomization/rndPolynom.ts +0 -90
- package/lib/maths/randomization/rndTypes.ts +0 -43
- package/lib/maths/shutingyard.ts +0 -496
- package/lib/pimath.ts +0 -40
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* NthRoot is something like "a+b\sqrt{3}
|
|
3
|
-
*/
|
|
4
|
-
export class NthRoot {
|
|
5
|
-
private _radical: number;
|
|
6
|
-
private _nth: number;
|
|
7
|
-
private _coefficient: number;
|
|
8
|
-
private _isValid:boolean;
|
|
9
|
-
|
|
10
|
-
constructor(...values: number[]) {
|
|
11
|
-
this._radical = 1;
|
|
12
|
-
this._coefficient = 1;
|
|
13
|
-
this._nth = 2;
|
|
14
|
-
this._isValid = true;
|
|
15
|
-
|
|
16
|
-
if(values !== undefined){
|
|
17
|
-
this.parse(values[0], values[1], values[2])
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// ------------------------------------------
|
|
22
|
-
// Getter and setter
|
|
23
|
-
// ------------------------------------------
|
|
24
|
-
get radical(): number {
|
|
25
|
-
return this._radical;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
set radical(value: number) {
|
|
29
|
-
this._radical = value;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
get nth(): number {
|
|
33
|
-
return this._nth;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
set nth(value: number) {
|
|
37
|
-
if (Number.isSafeInteger(value) && value >= 2) {
|
|
38
|
-
this._nth = value;
|
|
39
|
-
} else {
|
|
40
|
-
// Error setting the nth root.
|
|
41
|
-
console.log('Error setting the nth root');
|
|
42
|
-
this._nth = 2;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
get coefficient(): number {
|
|
47
|
-
return this._coefficient;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
set coefficient(value: number) {
|
|
51
|
-
this._coefficient = value;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
get tex(): string {
|
|
55
|
-
let C: string;
|
|
56
|
-
|
|
57
|
-
if (this._coefficient === 1) {
|
|
58
|
-
C = '';
|
|
59
|
-
} else if (this._coefficient === -1) {
|
|
60
|
-
C = '-';
|
|
61
|
-
} else {
|
|
62
|
-
C = this._coefficient.toString();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (this._radical === 1) {
|
|
66
|
-
return `${this._coefficient}`;
|
|
67
|
-
} else {
|
|
68
|
-
if (this._nth === 2) {
|
|
69
|
-
return `${C}\\sqrt{${this._radical}}`
|
|
70
|
-
} else {
|
|
71
|
-
return `${C}\\sqrt[${this._nth}]{${this._radical}}`
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
get display(): string {
|
|
77
|
-
let C: string;
|
|
78
|
-
|
|
79
|
-
if (this._coefficient === 1) {
|
|
80
|
-
C = '';
|
|
81
|
-
} else if (this._coefficient === -1) {
|
|
82
|
-
C = '-';
|
|
83
|
-
} else {
|
|
84
|
-
C = this._coefficient.toString();
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (this._radical === 1) {
|
|
88
|
-
return `${this._coefficient}`;
|
|
89
|
-
} else {
|
|
90
|
-
if (this._nth === 2) {
|
|
91
|
-
return `${C}sqrt{${this._radical}}`
|
|
92
|
-
} else {
|
|
93
|
-
return `${C}root(${this._nth}){${this._radical}}`
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
get value(): number {
|
|
99
|
-
return this._coefficient * Math.pow(this._radical, 1 / this._nth);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// ------------------------------------------
|
|
103
|
-
// Creation / parsing functions
|
|
104
|
-
// ------------------------------------------
|
|
105
|
-
parse = (radical: number, nthroot?: number, coefficient?: number): NthRoot => {
|
|
106
|
-
this._coefficient = (coefficient === undefined) ? 1 : coefficient;
|
|
107
|
-
this._nth = (nthroot === undefined) ? 2 : nthroot;
|
|
108
|
-
this._radical = (radical === undefined) ? 1 : radical;
|
|
109
|
-
|
|
110
|
-
if(this._nth%2===0 && this._radical<0){
|
|
111
|
-
this._isValid = false;
|
|
112
|
-
}
|
|
113
|
-
return this;
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
// ------------------------------------------
|
|
117
|
-
// Mathematical operations
|
|
118
|
-
// ------------------------------------------
|
|
119
|
-
reduce = (): NthRoot => {
|
|
120
|
-
// Max value to test.
|
|
121
|
-
let V = Math.floor(Math.pow(this._radical, 1 / this._nth));
|
|
122
|
-
while (V > 1) {
|
|
123
|
-
if (this._radical % Math.pow(V, this._nth) === 0) {
|
|
124
|
-
// It's dividable by V^n
|
|
125
|
-
this._coefficient *= V;
|
|
126
|
-
this._radical = this._radical / Math.pow(V, this._nth);
|
|
127
|
-
|
|
128
|
-
// Redifine the new testing value (this is optimization)
|
|
129
|
-
V = Math.floor(Math.pow(this._radical, 1 / this._nth));
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
V--;
|
|
133
|
-
}
|
|
134
|
-
return this;
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
multiply = (N: NthRoot): NthRoot => {
|
|
138
|
-
this._radical *= N.radical;
|
|
139
|
-
return this.reduce();
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
// ------------------------------------------
|
|
143
|
-
// Help functions
|
|
144
|
-
// ------------------------------------------
|
|
145
|
-
hasRadical = ():boolean => {
|
|
146
|
-
return !(this._radical===1 || this._radical===0 || this._isValid===false)
|
|
147
|
-
};
|
|
148
|
-
}
|
|
@@ -1,379 +0,0 @@
|
|
|
1
|
-
import {Point} from "./point";
|
|
2
|
-
import {Line, LinePropriety} from "./line";
|
|
3
|
-
import {Vector} from "./vector";
|
|
4
|
-
import {Triangle} from "./triangle";
|
|
5
|
-
import {Numeric} from "../numeric.ts";
|
|
6
|
-
import {Fraction} from "../coefficients/fraction";
|
|
7
|
-
import {Equation} from "../algebra/equation";
|
|
8
|
-
import {Polynom} from "../algebra/polynom";
|
|
9
|
-
import {Monom} from "../algebra/monom";
|
|
10
|
-
|
|
11
|
-
export class Circle {
|
|
12
|
-
private _center: Point;
|
|
13
|
-
private _squareRadius: Fraction;
|
|
14
|
-
private _cartesian: Equation;
|
|
15
|
-
private _exists: boolean;
|
|
16
|
-
|
|
17
|
-
constructor(...values: unknown[]) {
|
|
18
|
-
this._exists = false
|
|
19
|
-
|
|
20
|
-
if (values !== undefined) {
|
|
21
|
-
this.parse(...values)
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
get center(): Point {
|
|
26
|
-
return this._center;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
get squareRadius(): Fraction {
|
|
30
|
-
return this._squareRadius
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
get cartesian(): Equation {
|
|
34
|
-
return this._cartesian
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
get exists(): boolean {
|
|
38
|
-
return this._exists;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
get radius(): { tex: string, display: string, value: number } {
|
|
42
|
-
if (this._squareRadius.isSquare()) {
|
|
43
|
-
return {
|
|
44
|
-
tex: this._squareRadius.clone().sqrt().tex,
|
|
45
|
-
display: this._squareRadius.clone().sqrt().display,
|
|
46
|
-
value: this._squareRadius.clone().sqrt().value
|
|
47
|
-
}
|
|
48
|
-
} else {
|
|
49
|
-
return {
|
|
50
|
-
tex: `\\sqrt{${this._squareRadius.tex}}`,
|
|
51
|
-
display: `sqrt(${this._squareRadius.display})`,
|
|
52
|
-
value: this._squareRadius.clone().sqrt().value
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return this._squareRadius
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
get tex(): string {
|
|
59
|
-
if (this._exists) {
|
|
60
|
-
let cx, cy
|
|
61
|
-
if (this._center.x.isZero()) {
|
|
62
|
-
cx = 'x^2'
|
|
63
|
-
} else {
|
|
64
|
-
cx = `\\left(x${this._center.x.isNegative() ? '+' : '-'}${this._center.x.clone().abs().tex}\\right)^2`
|
|
65
|
-
}
|
|
66
|
-
if (this._center.y.isZero()) {
|
|
67
|
-
cy = 'y^2'
|
|
68
|
-
} else {
|
|
69
|
-
cy = `\\left(y${this._center.y.isNegative() ? '+' : '-'}${this._center.y.clone().abs().tex}\\right)^2`
|
|
70
|
-
}
|
|
71
|
-
return `${cx}+${cy}=${this._squareRadius.tex}`
|
|
72
|
-
} else {
|
|
73
|
-
return `\\text{le cercle n'existe pas.}`
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
get developed(): string {
|
|
78
|
-
return this._cartesian.tex
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
get display(): string {
|
|
82
|
-
if (this._exists) {
|
|
83
|
-
let cx, cy
|
|
84
|
-
if (this._center.x.isZero()) {
|
|
85
|
-
cx = 'x^2'
|
|
86
|
-
} else {
|
|
87
|
-
cx = `(x${this._center.x.isNegative() ? '+' : '-'}${this._center.x.clone().abs().tex})^2`
|
|
88
|
-
}
|
|
89
|
-
if (this._center.y.isZero()) {
|
|
90
|
-
cy = 'y^2'
|
|
91
|
-
} else {
|
|
92
|
-
cy = `(y${this._center.y.isNegative() ? '+' : '-'}${this._center.y.clone().abs().tex})^2`
|
|
93
|
-
}
|
|
94
|
-
return `${cx}+${cy}=${this._squareRadius.display}`
|
|
95
|
-
} else {
|
|
96
|
-
return `\\text{le cercle n'existe pas.}`
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Get the relative position between circle and line. It corresponds to the number of intersection.
|
|
102
|
-
* @param {Line} L
|
|
103
|
-
* @returns {number}
|
|
104
|
-
*/
|
|
105
|
-
relativePosition = (L: Line): number => {
|
|
106
|
-
let distance = L.distanceTo(this.center), radius = Math.sqrt(this._squareRadius.value)
|
|
107
|
-
|
|
108
|
-
if (distance.value - radius > 0.0000000001) {
|
|
109
|
-
return 0 // external
|
|
110
|
-
} else if (Math.abs(distance.value - radius) < 0.0000000001) {
|
|
111
|
-
return 1 // tangent
|
|
112
|
-
} else {
|
|
113
|
-
return 2 // external
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
lineIntersection = (L: Line): Point[] => {
|
|
118
|
-
let intersectionPoints: Point[] = [], solX: Fraction
|
|
119
|
-
|
|
120
|
-
if (this._cartesian === null) {
|
|
121
|
-
return []
|
|
122
|
-
}
|
|
123
|
-
const equX = this._cartesian.clone(), lineX = L.equation.clone().isolate('x'),
|
|
124
|
-
lineY = L.equation.clone().isolate('y')
|
|
125
|
-
|
|
126
|
-
if (lineX instanceof Equation && lineY instanceof Equation) {
|
|
127
|
-
equX.replaceBy('y', lineY.right).simplify()
|
|
128
|
-
equX.solve()
|
|
129
|
-
|
|
130
|
-
for (let x of equX.solutions) {
|
|
131
|
-
if (x.exact === false && isNaN(x.value)) {
|
|
132
|
-
continue
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
solX = new Fraction(x.exact === false ? x.value : x.exact)
|
|
136
|
-
intersectionPoints.push(new Point(solX.clone(), lineY.right.evaluate(solX)))
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return intersectionPoints
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
tangents = (P: Point | Fraction): Line[] => {
|
|
144
|
-
if (P instanceof Fraction) {
|
|
145
|
-
return this._tangentsWithSlope(P)
|
|
146
|
-
} else if (this.isPointOnCircle(P)) {
|
|
147
|
-
return this._tangentsThroughOnePointOnTheCircle(P)
|
|
148
|
-
} else if (this.center.distanceTo(P).value > this.radius.value) {
|
|
149
|
-
//TODO: Must check it's outside the circle
|
|
150
|
-
return this._tangentsThroughOnePointOutsideTheCircle(P)
|
|
151
|
-
} else {
|
|
152
|
-
console.log('No tangents as the point is inside !')
|
|
153
|
-
}
|
|
154
|
-
return []
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
isPointOnCircle = (P: Point): Boolean => {
|
|
158
|
-
return this._cartesian.test({x: P.x, y: P.y})
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
getPointsOnCircle = (numberIsInteger?: boolean): Point[] => {
|
|
162
|
-
if (numberIsInteger === undefined) {
|
|
163
|
-
numberIsInteger = false
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// It means searching for pythagorician triples that make a perfect square.
|
|
167
|
-
// (x-4)^2 + (y+3)^2 = 15
|
|
168
|
-
|
|
169
|
-
let triplets = Numeric.pythagoricianTripletsWithTarget(this._squareRadius.value, true)
|
|
170
|
-
|
|
171
|
-
let points: Point[] = [], pt
|
|
172
|
-
triplets.forEach(triplet => {
|
|
173
|
-
// Allow positive / negative values
|
|
174
|
-
// x-a = t => x = a + t
|
|
175
|
-
// x-a = -t => x = a - t
|
|
176
|
-
|
|
177
|
-
for (let k of [[1, 1], [-1, 1], [-1, -1], [1, -1]]) {
|
|
178
|
-
pt = new Point(
|
|
179
|
-
this.center.x.clone().add(k[0] * triplet[0]),
|
|
180
|
-
this.center.y.clone().add(k[1] * triplet[1])
|
|
181
|
-
)
|
|
182
|
-
// Check if the point is not already in points.
|
|
183
|
-
if (!pt.isInListOfPoints(points)) {
|
|
184
|
-
points.push(pt)
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
})
|
|
188
|
-
return points
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
clone(): Circle {
|
|
192
|
-
this._center = this._center.clone()
|
|
193
|
-
this._squareRadius = this._squareRadius.clone()
|
|
194
|
-
this._calculateCartesian()
|
|
195
|
-
return this
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
private _tangentsThroughOnePointOnTheCircle = (P: Point): Line[] => {
|
|
199
|
-
let CT = new Vector(this._center, P)
|
|
200
|
-
return [new Line(P, CT, LinePropriety.Perpendicular)]
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
private _tangentsThroughOnePointOutsideTheCircle = (P: Point): Line[] => {
|
|
204
|
-
// y = mx + h
|
|
205
|
-
// px, py => h = -m px + py => mx - y -m.px + py = 0 =>
|
|
206
|
-
// Centre: cx, cy, radius: r
|
|
207
|
-
// (m.cx - cy -m.px + py)^2 = r^2 * (m^2 + 1)
|
|
208
|
-
// (m(cx-py) - (cy - py))^2 = r^2 * (m^2 + 1)
|
|
209
|
-
|
|
210
|
-
let cx_px = this.center.x.clone().subtract(P.x), cy_py = this.center.y.clone().subtract(P.y),
|
|
211
|
-
polyLeft = new Polynom('x'), polyRight = new Polynom('x^2+1')
|
|
212
|
-
|
|
213
|
-
polyLeft.multiply(cx_px).subtract(cy_py).pow(2)
|
|
214
|
-
polyRight.multiply(this.squareRadius)
|
|
215
|
-
|
|
216
|
-
let equ = new Equation(polyLeft, polyRight)
|
|
217
|
-
equ.moveLeft().simplify().solve()
|
|
218
|
-
|
|
219
|
-
return equ.solutions.map(sol => {
|
|
220
|
-
// h = -m px + py
|
|
221
|
-
let h, equ = new Equation('y', 'x')
|
|
222
|
-
|
|
223
|
-
if (sol.exact instanceof Fraction) {
|
|
224
|
-
h = P.x.clone().opposed().multiply(sol.exact).add(P.y)
|
|
225
|
-
equ.right.multiply(sol.exact).add(h)
|
|
226
|
-
} else {
|
|
227
|
-
h = P.x.clone().opposed().multiply(sol.value).add(P.y)
|
|
228
|
-
equ.right.multiply(sol.value).add(h)
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return new Line(equ)
|
|
232
|
-
})
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
private _tangentsWithSlope = (slope: Fraction): Line[] => {
|
|
237
|
-
// d(C;t)=r => ac1+bc2 + x = +- sqrt(a^2 + b^2)*r
|
|
238
|
-
// x = -ac1-bc2 +- sqrt(a^2 + b^2)*r
|
|
239
|
-
// y = a/bx + h => ax-by + H = 0
|
|
240
|
-
|
|
241
|
-
const a = slope.numerator, b = -slope.denominator, c1 = this._center.x.clone(), c2 = this._center.y.clone(),
|
|
242
|
-
r = this._squareRadius
|
|
243
|
-
|
|
244
|
-
let sq = this._squareRadius.clone().multiply(slope.numerator ** 2 + slope.denominator ** 2),
|
|
245
|
-
x1 = c1.clone().multiply(a).opposed().subtract(c2.clone().multiply(b)).add(sq.clone().sqrt()),
|
|
246
|
-
x2 = c1.clone().multiply(a).opposed().subtract(c2.clone().multiply(b)).subtract(sq.clone().sqrt())
|
|
247
|
-
|
|
248
|
-
return [new Line(a, b, x1), new Line(a, b, x2)]
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
private _reset(): Circle {
|
|
252
|
-
this._center = null
|
|
253
|
-
this._squareRadius = null
|
|
254
|
-
this._cartesian = null
|
|
255
|
-
this._exists = false
|
|
256
|
-
|
|
257
|
-
return this
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
private parse(...values: unknown[]): Circle {
|
|
261
|
-
// Data can be given in these formats:
|
|
262
|
-
// one value, a string -> make it an Equation
|
|
263
|
-
// one value, an Equation
|
|
264
|
-
// one value, a circle -> clone it
|
|
265
|
-
// two values: two points (center and pointThrough)
|
|
266
|
-
// two values: point and Fraction (center and radius)
|
|
267
|
-
// three values: Point, Fraction, Boolean (center, square radius, true)
|
|
268
|
-
|
|
269
|
-
this._reset()
|
|
270
|
-
|
|
271
|
-
if (typeof values[0] === 'string') {
|
|
272
|
-
this._parseEquation(new Equation(values[0]))
|
|
273
|
-
} else if (values[0] instanceof Equation) {
|
|
274
|
-
this._parseEquation(values[0])
|
|
275
|
-
} else if (values[0] instanceof Circle) {
|
|
276
|
-
this._parseCopyCircle(values[0])
|
|
277
|
-
} else if (values[0] instanceof Point && values.length > 1) {
|
|
278
|
-
if (values[1] instanceof Point) {
|
|
279
|
-
if (values[2] instanceof Point) {
|
|
280
|
-
this._parseThroughtThreePoints(values[0], values[1], values[2])
|
|
281
|
-
} else {
|
|
282
|
-
this._parseCenterAndPointThrough(values[0], values[1])
|
|
283
|
-
}
|
|
284
|
-
} else if (values[1] instanceof Fraction || typeof values[1] === 'number') {
|
|
285
|
-
this._parseCenterAndRadius(values[0], values[1], (typeof values[2] === "boolean") ? values[2] : false)
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
// Calculate once the different values.
|
|
290
|
-
if (this._exists) {
|
|
291
|
-
this._calculateCartesian()
|
|
292
|
-
|
|
293
|
-
// If the square radius is zero or positive, the circle exists.
|
|
294
|
-
if (this._squareRadius !== undefined && this._squareRadius.isNegative()) {
|
|
295
|
-
this._exists = false
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
return this
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
private _calculateCartesian() {
|
|
303
|
-
this._cartesian = (new Equation(new Polynom(`(x-(${this._center.x.display}))^2+(y-(${this._center.y.display}))^2`), new Polynom(`${this._squareRadius.display}`))).moveLeft()
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
private _parseCopyCircle(circle: Circle): Circle {
|
|
307
|
-
this._center = circle.center.clone()
|
|
308
|
-
this._squareRadius = circle.squareRadius.clone()
|
|
309
|
-
this._calculateCartesian()
|
|
310
|
-
this._exists = circle.exists
|
|
311
|
-
return this
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
private _parseCenterAndRadius(center: Point, radius: Fraction | number, square?: boolean): Circle {
|
|
315
|
-
this._center = center.clone()
|
|
316
|
-
|
|
317
|
-
if (square) {
|
|
318
|
-
this._squareRadius = (new Fraction(radius))
|
|
319
|
-
} else {
|
|
320
|
-
this._squareRadius = new Fraction(radius).pow(2)
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
this._exists = true
|
|
324
|
-
return this
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
private _parseCenterAndPointThrough(center: Point, pointThrough: Point): Circle {
|
|
328
|
-
this._center = center.clone()
|
|
329
|
-
this._squareRadius = new Vector(this._center, pointThrough).normSquare
|
|
330
|
-
this._exists = true
|
|
331
|
-
return this
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
private _parseEquation(equ: Equation): Circle {
|
|
335
|
-
this._exists = false
|
|
336
|
-
|
|
337
|
-
// Move everything to the left.
|
|
338
|
-
equ.moveLeft()
|
|
339
|
-
|
|
340
|
-
if (equ.degree('x').value === 2 && equ.degree('y').value === 2) {
|
|
341
|
-
// Both must be of degree 2.
|
|
342
|
-
let x2 = equ.left.monomByDegree(2, 'x'), y2 = equ.left.monomByDegree(2, 'y'), x1: Monom, y1: Monom, c: Monom
|
|
343
|
-
|
|
344
|
-
// Both square monoms must have the same coefficient.
|
|
345
|
-
if (x2.coefficient.isEqual(y2.coefficient)) {
|
|
346
|
-
equ.divide(x2.coefficient)
|
|
347
|
-
|
|
348
|
-
x1 = equ.left.monomByDegree(1, 'x')
|
|
349
|
-
y1 = equ.left.monomByDegree(1, 'y')
|
|
350
|
-
|
|
351
|
-
c = equ.left.monomByDegree(0)
|
|
352
|
-
|
|
353
|
-
this._center = new Point(x1.coefficient.clone().divide(2).opposed(), y1.coefficient.clone().divide(2).opposed())
|
|
354
|
-
|
|
355
|
-
this._squareRadius = c.coefficient.clone().opposed()
|
|
356
|
-
.add(this._center.x.clone().pow(2))
|
|
357
|
-
.add(this._center.y.clone().pow(2))
|
|
358
|
-
|
|
359
|
-
this._calculateCartesian()
|
|
360
|
-
this._exists = true
|
|
361
|
-
} else {
|
|
362
|
-
// The circle is not a valid circle
|
|
363
|
-
this._center = null
|
|
364
|
-
this._squareRadius = null
|
|
365
|
-
this._exists = false
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
return this
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
private _parseThroughtThreePoints(A: Point, B: Point, C: Point): Circle {
|
|
372
|
-
let T = new Triangle(A, B, C), mAB = T.remarquables.mediators.AB.clone(),
|
|
373
|
-
mAC = T.remarquables.mediators.AC.clone()
|
|
374
|
-
this.parse(mAB.intersection(mAC).point, A)
|
|
375
|
-
|
|
376
|
-
return this
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
}
|