pimath 0.0.21 → 0.0.25
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/dev/demo.css +3 -0
- package/dev/index.html +216 -53
- package/dev/pi.js +374 -132
- package/dev/pi.js.map +1 -1
- package/dist/pi.js +1 -1
- package/dist/pi.js.map +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/algebra.Equation.html +11 -13
- package/docs/classes/algebra.LinearSystem.html +1 -1
- package/docs/classes/algebra.Logicalset.html +3 -3
- package/docs/classes/algebra.Monom.html +42 -42
- package/docs/classes/algebra.Polynom.html +12 -25
- package/docs/classes/algebra.Rational.html +3 -3
- package/docs/classes/coefficients.Fraction.html +10 -6
- package/docs/classes/coefficients.Nthroot.html +3 -1
- package/docs/classes/geometry.Circle.html +3 -1
- package/docs/classes/geometry.Line.html +3 -1
- package/docs/classes/geometry.Point.html +1 -1
- package/docs/classes/geometry.Triangle.html +6 -6
- package/docs/classes/geometry.Vector.html +1 -1
- package/docs/classes/numeric.Numeric.html +5 -5
- package/docs/classes/shutingyard.Shutingyard.html +5 -5
- package/docs/index.html +1 -1
- package/docs/interfaces/geometry.remarquableLines.html +1 -1
- package/docs/modules/algebra.html +1 -1
- package/docs/modules/coefficients.html +1 -1
- package/docs/modules/geometry.html +1 -1
- package/docs/modules/numeric.html +1 -1
- package/docs/modules/random.Random.html +1 -1
- package/docs/modules/random.html +1 -1
- package/docs/modules/shutingyard.html +1 -1
- package/docs/modules.html +1 -1
- package/esm/maths/algebra/equation.d.ts +11 -5
- package/esm/maths/algebra/equation.js +159 -52
- package/esm/maths/algebra/equation.js.map +1 -1
- package/esm/maths/algebra/linearSystem.d.ts +3 -4
- package/esm/maths/algebra/linearSystem.js +2 -5
- package/esm/maths/algebra/linearSystem.js.map +1 -1
- package/esm/maths/algebra/logicalset.d.ts +2 -2
- package/esm/maths/algebra/logicalset.js.map +1 -1
- package/esm/maths/algebra/monom.d.ts +3 -2
- package/esm/maths/algebra/monom.js +22 -1
- package/esm/maths/algebra/monom.js.map +1 -1
- package/esm/maths/algebra/polynom.d.ts +6 -6
- package/esm/maths/algebra/polynom.js +3 -3
- package/esm/maths/algebra/polynom.js.map +1 -1
- package/esm/maths/coefficients/fraction.d.ts +2 -2
- package/esm/maths/coefficients/fraction.js +1 -1
- package/esm/maths/coefficients/fraction.js.map +1 -1
- package/esm/maths/coefficients/nthroot.d.ts +1 -1
- package/esm/maths/coefficients/nthroot.js +4 -1
- package/esm/maths/coefficients/nthroot.js.map +1 -1
- package/esm/maths/geometry/circle.d.ts +12 -3
- package/esm/maths/geometry/circle.js +125 -39
- package/esm/maths/geometry/circle.js.map +1 -1
- package/esm/maths/geometry/line.d.ts +4 -4
- package/esm/maths/geometry/line.js +17 -7
- package/esm/maths/geometry/line.js.map +1 -1
- package/esm/maths/geometry/point.d.ts +3 -4
- package/esm/maths/geometry/point.js +18 -15
- package/esm/maths/geometry/point.js.map +1 -1
- package/esm/maths/geometry/triangle.d.ts +0 -1
- package/esm/maths/geometry/triangle.js +3 -4
- package/esm/maths/geometry/triangle.js.map +1 -1
- package/esm/maths/geometry/vector.js +2 -1
- package/esm/maths/geometry/vector.js.map +1 -1
- package/esm/maths/random/index.js +18 -6
- package/esm/maths/random/index.js.map +1 -1
- package/esm/maths/random/rndFraction.js +4 -3
- package/esm/maths/random/rndFraction.js.map +1 -1
- package/esm/maths/random/rndMonom.d.ts +1 -1
- package/esm/maths/random/rndMonom.js +12 -7
- package/esm/maths/random/rndMonom.js.map +1 -1
- package/esm/maths/random/rndPolynom.js +8 -2
- package/esm/maths/random/rndPolynom.js.map +1 -1
- package/esm/maths/random/rndTypes.d.ts +3 -1
- package/package.json +3 -5
- package/src/maths/algebra/equation.ts +183 -73
- package/src/maths/algebra/linearSystem.ts +262 -265
- package/src/maths/algebra/logicalset.ts +1 -1
- package/src/maths/algebra/monom.ts +24 -18
- package/src/maths/algebra/polynom.ts +9 -9
- package/src/maths/coefficients/fraction.ts +11 -7
- package/src/maths/coefficients/nthroot.ts +8 -1
- package/src/maths/geometry/circle.ts +160 -45
- package/src/maths/geometry/line.ts +30 -11
- package/src/maths/geometry/point.ts +25 -18
- package/src/maths/geometry/triangle.ts +3 -5
- package/src/maths/geometry/vector.ts +4 -3
- package/src/maths/random/index.ts +24 -6
- package/src/maths/random/rndFraction.ts +4 -3
- package/src/maths/random/rndMonom.ts +39 -35
- package/src/maths/random/rndPolynom.ts +13 -3
- package/src/maths/random/rndTypes.ts +4 -2
- package/tests/algebra/monom.test.ts +18 -4
- package/tests/algebra/polynom.test.ts +10 -4
- package/tests/geometry/circle.test.ts +28 -0
- package/tsconfig.json +4 -1
- package/typedoc.katex.js +11 -0
- package/docs/classes/algebra.Algebra.Equation.html +0 -26
- package/docs/classes/algebra.Algebra.LinearSystem.html +0 -1
- package/docs/classes/algebra.Algebra.LogicalSet.html +0 -3
- package/docs/classes/algebra.Algebra.Monom.html +0 -111
- package/docs/classes/algebra.Algebra.Polynom.html +0 -36
- package/docs/classes/algebra.Algebra.Rational.html +0 -2
- package/docs/classes/geometry.Geometry.Circle.html +0 -1
- package/docs/classes/geometry.Geometry.Line.html +0 -1
- package/docs/classes/geometry.Geometry.Point.html +0 -1
- package/docs/classes/geometry.Geometry.Triangle.html +0 -9
- package/docs/classes/geometry.Geometry.Vector.html +0 -1
- package/docs/modules/algebra.Algebra.html +0 -1
- package/docs/modules/geometry.Geometry.html +0 -1
- package/src/maths/algebra/monom_bck.backup +0 -746
|
@@ -19,7 +19,7 @@ export class Monom {
|
|
|
19
19
|
* Create the monom object.
|
|
20
20
|
* @param value (optional) string
|
|
21
21
|
*/
|
|
22
|
-
constructor(value?:
|
|
22
|
+
constructor(value?: unknown) {
|
|
23
23
|
this.zero();
|
|
24
24
|
|
|
25
25
|
if (value !== undefined) {
|
|
@@ -279,23 +279,20 @@ export class Monom {
|
|
|
279
279
|
* Parse a string to a monom. The string may include fraction.
|
|
280
280
|
* @param inputStr
|
|
281
281
|
*/
|
|
282
|
-
parse = (inputStr:
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
// // Multiply the current coefficient by the new found value.
|
|
297
|
-
// this._coefficient.multiply(new Fraction(v.trim()));
|
|
298
|
-
// }
|
|
282
|
+
parse = (inputStr: unknown): Monom => {
|
|
283
|
+
|
|
284
|
+
if(typeof inputStr === 'string') {
|
|
285
|
+
this._shutingYardToReducedMonom(inputStr)
|
|
286
|
+
}else if(typeof inputStr ==='number') {
|
|
287
|
+
this._coefficient = new Fraction(inputStr)
|
|
288
|
+
this._literal = {}
|
|
289
|
+
}else if(inputStr instanceof Fraction) {
|
|
290
|
+
this._coefficient = inputStr.clone()
|
|
291
|
+
this._literal = {}
|
|
292
|
+
}else if(inputStr instanceof Monom){
|
|
293
|
+
this._coefficient = inputStr._coefficient.clone()
|
|
294
|
+
this._literal = this.copyLiterals(inputStr.literal)
|
|
295
|
+
}
|
|
299
296
|
|
|
300
297
|
return this;
|
|
301
298
|
};
|
|
@@ -386,6 +383,15 @@ export class Monom {
|
|
|
386
383
|
return F;
|
|
387
384
|
};
|
|
388
385
|
|
|
386
|
+
copyLiterals = (literal: literalType): literalType => {
|
|
387
|
+
let L:literalType = {}
|
|
388
|
+
|
|
389
|
+
for (let k in literal) {
|
|
390
|
+
L[k] = literal[k].clone()
|
|
391
|
+
}
|
|
392
|
+
return L
|
|
393
|
+
}
|
|
394
|
+
|
|
389
395
|
makeSame = (M: Monom):Monom => {
|
|
390
396
|
// Copy the literal parts.
|
|
391
397
|
for (let k in M._literal) {
|
|
@@ -25,7 +25,7 @@ export class Polynom {
|
|
|
25
25
|
* @param {string} polynomString (optional) Default polynom to parse on class creation
|
|
26
26
|
* @param values
|
|
27
27
|
*/
|
|
28
|
-
constructor(polynomString?: string, ...values:
|
|
28
|
+
constructor(polynomString?: string, ...values: unknown[]) {
|
|
29
29
|
this._monoms = [];
|
|
30
30
|
this._factors = [];
|
|
31
31
|
if (polynomString !== undefined) {
|
|
@@ -149,7 +149,7 @@ export class Polynom {
|
|
|
149
149
|
* @param inputStr
|
|
150
150
|
* @param values: as string, numbers or fractions
|
|
151
151
|
*/
|
|
152
|
-
parse = (inputStr: string, ...values:
|
|
152
|
+
parse = (inputStr: string, ...values: unknown[]): Polynom => {
|
|
153
153
|
|
|
154
154
|
if (values === undefined || values.length === 0) {
|
|
155
155
|
inputStr = '' + inputStr;
|
|
@@ -357,7 +357,7 @@ export class Polynom {
|
|
|
357
357
|
return this;
|
|
358
358
|
};
|
|
359
359
|
|
|
360
|
-
add = (...values:
|
|
360
|
+
add = (...values: unknown[]): Polynom => {
|
|
361
361
|
|
|
362
362
|
for (let value of values) {
|
|
363
363
|
if (value instanceof Polynom) {
|
|
@@ -374,7 +374,7 @@ export class Polynom {
|
|
|
374
374
|
return this.reduce();
|
|
375
375
|
};
|
|
376
376
|
|
|
377
|
-
subtract = (...values:
|
|
377
|
+
subtract = (...values: unknown[]): Polynom => {
|
|
378
378
|
|
|
379
379
|
for (let value of values) {
|
|
380
380
|
if (value instanceof Polynom) {
|
|
@@ -391,14 +391,14 @@ export class Polynom {
|
|
|
391
391
|
return this.reduce();
|
|
392
392
|
};
|
|
393
393
|
|
|
394
|
-
multiply = (value:
|
|
394
|
+
multiply = (value: unknown): Polynom => {
|
|
395
395
|
if (value instanceof Polynom) {
|
|
396
396
|
return this.multiplyByPolynom(value);
|
|
397
397
|
} else if (value instanceof Fraction) {
|
|
398
398
|
return this.multiplyByFraction(value);
|
|
399
399
|
} else if (value instanceof Monom) {
|
|
400
400
|
return this.multiplyByMonom(value);
|
|
401
|
-
} else if (Number.isSafeInteger(value)) {
|
|
401
|
+
} else if (Number.isSafeInteger(value) && typeof value==='number') {
|
|
402
402
|
return this.multiplyByInteger(value);
|
|
403
403
|
}
|
|
404
404
|
|
|
@@ -479,10 +479,10 @@ export class Polynom {
|
|
|
479
479
|
return {quotient, reminder};
|
|
480
480
|
};
|
|
481
481
|
|
|
482
|
-
divide = (value:
|
|
483
|
-
if (value
|
|
482
|
+
divide = (value: unknown): Polynom => {
|
|
483
|
+
if (value instanceof Fraction) {
|
|
484
484
|
this.divideByFraction(value);
|
|
485
|
-
} else if (Number.isSafeInteger(value)) {
|
|
485
|
+
} else if (typeof value==='number' && Number.isSafeInteger(value)) {
|
|
486
486
|
return this.divideByInteger(value);
|
|
487
487
|
}
|
|
488
488
|
}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import {Numeric} from "../numeric";
|
|
2
|
-
import {Random} from "../random";
|
|
3
2
|
|
|
3
|
+
/**
|
|
4
|
+
* The fraction class make possible to handle
|
|
5
|
+
* TODO: Write the documentation correctly.
|
|
6
|
+
* \\(\frac{a}{b}\\) or \\[\frac{a}{b}\\] values.
|
|
7
|
+
*/
|
|
4
8
|
export class Fraction {
|
|
5
9
|
private _numerator: number;
|
|
6
10
|
private _denominator: number;
|
|
7
11
|
|
|
8
|
-
constructor(value?:
|
|
12
|
+
constructor(value?: unknown, denominatorOrPeriodic?: number) {
|
|
9
13
|
this._numerator = 1;
|
|
10
14
|
this._denominator = 1;
|
|
11
15
|
|
|
@@ -80,7 +84,7 @@ export class Fraction {
|
|
|
80
84
|
* @param value : number or string to parse to get the fraction
|
|
81
85
|
* @param denominatorOrPeriodic (optional|number) : length of the periodic part: 2.333333 => 1 or denominator value
|
|
82
86
|
*/
|
|
83
|
-
parse = (value:
|
|
87
|
+
parse = (value: unknown, denominatorOrPeriodic?: number): Fraction => {
|
|
84
88
|
let S: string[];
|
|
85
89
|
|
|
86
90
|
// A null value means a zero fraction.
|
|
@@ -146,7 +150,7 @@ export class Fraction {
|
|
|
146
150
|
}
|
|
147
151
|
break;
|
|
148
152
|
case "object":
|
|
149
|
-
if (value
|
|
153
|
+
if (value instanceof Fraction) {
|
|
150
154
|
this._numerator = +value.numerator;
|
|
151
155
|
this._denominator = +value.denominator;
|
|
152
156
|
}
|
|
@@ -201,7 +205,7 @@ export class Fraction {
|
|
|
201
205
|
|
|
202
206
|
this._numerator = N * F.denominator + F.numerator * D;
|
|
203
207
|
this._denominator = D * F.denominator;
|
|
204
|
-
}else{
|
|
208
|
+
} else {
|
|
205
209
|
return this.add(new Fraction(F))
|
|
206
210
|
}
|
|
207
211
|
|
|
@@ -303,7 +307,7 @@ export class Fraction {
|
|
|
303
307
|
};
|
|
304
308
|
|
|
305
309
|
|
|
306
|
-
static max = (...fractions: (Fraction|number)[]): Fraction => {
|
|
310
|
+
static max = (...fractions: (Fraction | number)[]): Fraction => {
|
|
307
311
|
let M = new Fraction(fractions[0])
|
|
308
312
|
|
|
309
313
|
for (let m of fractions) {
|
|
@@ -315,7 +319,7 @@ export class Fraction {
|
|
|
315
319
|
|
|
316
320
|
return M
|
|
317
321
|
}
|
|
318
|
-
static min = (...fractions: (Fraction|number)[]): Fraction => {
|
|
322
|
+
static min = (...fractions: (Fraction | number)[]): Fraction => {
|
|
319
323
|
let M = new Fraction(fractions[0])
|
|
320
324
|
|
|
321
325
|
for (let m of fractions) {
|
|
@@ -1,14 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nthroot is something like "a+b\sqrt{3}
|
|
3
|
+
*/
|
|
1
4
|
export class Nthroot {
|
|
2
5
|
private _radical: number;
|
|
3
6
|
private _nth: number;
|
|
4
7
|
private _coefficient: number;
|
|
5
8
|
private _isValid:boolean;
|
|
6
9
|
|
|
7
|
-
constructor() {
|
|
10
|
+
constructor(...values: number[]) {
|
|
8
11
|
this._radical = 1;
|
|
9
12
|
this._coefficient = 1;
|
|
10
13
|
this._nth = 2;
|
|
11
14
|
this._isValid = true;
|
|
15
|
+
|
|
16
|
+
if(values !== undefined){
|
|
17
|
+
this.parse(values[0], values[1], values[2])
|
|
18
|
+
}
|
|
12
19
|
}
|
|
13
20
|
|
|
14
21
|
// ------------------------------------------
|
|
@@ -3,16 +3,15 @@ import {Fraction} from "../coefficients";
|
|
|
3
3
|
import {Equation, Monom, Polynom} from "../algebra";
|
|
4
4
|
import {Line} from "./line";
|
|
5
5
|
import {Vector} from "./vector";
|
|
6
|
-
|
|
6
|
+
import {Triangle} from "./triangle";
|
|
7
7
|
|
|
8
8
|
export class Circle {
|
|
9
9
|
private _center: Point;
|
|
10
|
-
private _radius: Fraction;
|
|
11
10
|
private _squareRadius: Fraction;
|
|
12
11
|
private _cartesian: Equation;
|
|
13
12
|
private _exists: boolean;
|
|
14
13
|
|
|
15
|
-
constructor(...values:
|
|
14
|
+
constructor(...values: unknown[]) {
|
|
16
15
|
this._exists = false
|
|
17
16
|
|
|
18
17
|
if (values !== undefined) {
|
|
@@ -25,6 +24,15 @@ export class Circle {
|
|
|
25
24
|
return this._center;
|
|
26
25
|
}
|
|
27
26
|
|
|
27
|
+
|
|
28
|
+
get exists(): boolean {
|
|
29
|
+
return this._exists;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get squareRadius(): Fraction {
|
|
33
|
+
return this._squareRadius
|
|
34
|
+
}
|
|
35
|
+
|
|
28
36
|
get radius(): { tex: string, display: string } {
|
|
29
37
|
if (this._squareRadius.isSquare()) {
|
|
30
38
|
return {
|
|
@@ -41,18 +49,23 @@ export class Circle {
|
|
|
41
49
|
}
|
|
42
50
|
|
|
43
51
|
get tex(): string {
|
|
44
|
-
|
|
45
|
-
if (this.
|
|
46
|
-
cx
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
|
|
53
|
+
if (this._exists) {
|
|
54
|
+
let cx, cy
|
|
55
|
+
if (this._center.x.isZero()) {
|
|
56
|
+
cx = 'x^2'
|
|
57
|
+
} else {
|
|
58
|
+
cx = `\\left(x${this._center.x.isNegative() ? '+' : '-'}${this._center.x.clone().abs().tex}\\right)^2`
|
|
59
|
+
}
|
|
60
|
+
if (this._center.y.isZero()) {
|
|
61
|
+
cy = 'y^2'
|
|
62
|
+
} else {
|
|
63
|
+
cy = `\\left(y${this._center.y.isNegative() ? '+' : '-'}${this._center.y.clone().abs().tex}\\right)^2`
|
|
64
|
+
}
|
|
65
|
+
return `${cx}+${cy}=${this._squareRadius.tex}`
|
|
52
66
|
} else {
|
|
53
|
-
|
|
67
|
+
return `\\text{le cercle n'existe pas.}`
|
|
54
68
|
}
|
|
55
|
-
return `${cx}+${cy}=${this._squareRadius.tex}`
|
|
56
69
|
}
|
|
57
70
|
|
|
58
71
|
get developed(): string {
|
|
@@ -69,46 +82,119 @@ export class Circle {
|
|
|
69
82
|
return this._cartesian
|
|
70
83
|
}
|
|
71
84
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
85
|
+
clone(): Circle {
|
|
86
|
+
this._center = this._center.clone()
|
|
87
|
+
this._squareRadius = this._squareRadius.clone()
|
|
88
|
+
this._calculateCartesian()
|
|
89
|
+
return this
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private _reset(): Circle {
|
|
93
|
+
this._center = null
|
|
94
|
+
this._squareRadius = null
|
|
95
|
+
this._cartesian = null
|
|
96
|
+
this._exists = false
|
|
97
|
+
|
|
98
|
+
return this
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private parse(...values: unknown[]): Circle {
|
|
102
|
+
// Data can be given in these formats:
|
|
103
|
+
// one value, a string -> make it an Equation
|
|
104
|
+
// one value, an Equation
|
|
105
|
+
// one value, a circle -> clone it
|
|
106
|
+
// two values: two points (center and pointThrough)
|
|
107
|
+
// two values: point and Fraction (center and radius)
|
|
108
|
+
// three values: Point, Fraction, Boolean (center, square radius, true)
|
|
109
|
+
|
|
110
|
+
this._reset()
|
|
77
111
|
|
|
112
|
+
if (typeof values[0] === 'string') {
|
|
113
|
+
this._parseEquation(new Equation(values[0]))
|
|
114
|
+
} else if (values[0] instanceof Equation) {
|
|
115
|
+
this._parseEquation(values[0])
|
|
116
|
+
} else if (values[0] instanceof Circle) {
|
|
117
|
+
this._parseCopyCircle(values[0])
|
|
118
|
+
} else if (values[0] instanceof Point && values.length > 1) {
|
|
78
119
|
if (values[1] instanceof Point) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
} else {
|
|
82
|
-
if (values[2] === true) {
|
|
83
|
-
this._squareRadius = new Fraction(values[1])
|
|
120
|
+
if (values[2] instanceof Point) {
|
|
121
|
+
this._parseThroughtThreePoints(values[0], values[1], values[2])
|
|
84
122
|
} else {
|
|
85
|
-
this.
|
|
86
|
-
this._squareRadius = this._radius.clone().pow(2)
|
|
123
|
+
this._parseCenterAndPointThrough(values[0], values[1])
|
|
87
124
|
}
|
|
125
|
+
} else if (values[1] instanceof Fraction || typeof values[1] === 'number') {
|
|
126
|
+
this._parseCenterAndRadius(values[0], values[1], (typeof values[2] === "boolean") ? values[2] : false)
|
|
88
127
|
}
|
|
89
|
-
this._cartesian = (new Equation(
|
|
90
|
-
new Polynom(`(x-(${this._center.x.display}))^2+(y-(${this._center.y.display}))^2`),
|
|
91
|
-
new Polynom(`${this._squareRadius.display}`)
|
|
92
|
-
)).moveLeft()
|
|
93
128
|
}
|
|
129
|
+
|
|
130
|
+
// Calculate once the different values.
|
|
131
|
+
if(this._exists) {
|
|
132
|
+
this._calculateCartesian()
|
|
133
|
+
|
|
134
|
+
// If the square radius is zero or positive, the circle exists.
|
|
135
|
+
if (this._squareRadius !== undefined && this._squareRadius.isNegative()) {
|
|
136
|
+
this._exists = false
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return this
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private _calculateCartesian() {
|
|
144
|
+
this._cartesian = (new Equation(
|
|
145
|
+
new Polynom(`(x-(${this._center.x.display}))^2+(y-(${this._center.y.display}))^2`),
|
|
146
|
+
new Polynom(`${this._squareRadius.display}`)
|
|
147
|
+
)).moveLeft()
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private _parseCopyCircle(circle: Circle): Circle {
|
|
151
|
+
this._center = circle.center.clone()
|
|
152
|
+
this._squareRadius = circle.squareRadius.clone()
|
|
153
|
+
this._calculateCartesian()
|
|
154
|
+
this._exists = circle.exists
|
|
155
|
+
return this
|
|
94
156
|
}
|
|
95
157
|
|
|
158
|
+
private _parseCenterAndRadius(center: Point, radius: Fraction | number, square?: boolean): Circle {
|
|
159
|
+
this._center = center.clone()
|
|
160
|
+
|
|
161
|
+
if (square) {
|
|
162
|
+
this._squareRadius = (new Fraction(radius))
|
|
163
|
+
} else {
|
|
164
|
+
this._squareRadius = new Fraction(radius).pow(2)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
this._exists = true
|
|
168
|
+
return this
|
|
169
|
+
}
|
|
96
170
|
|
|
97
|
-
|
|
98
|
-
|
|
171
|
+
private _parseCenterAndPointThrough(center: Point, pointThrough: Point): Circle {
|
|
172
|
+
this._center = center.clone()
|
|
173
|
+
this._squareRadius = new Vector(this._center, pointThrough).normSquare
|
|
174
|
+
this._exists = true
|
|
175
|
+
return this
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
private _parseEquation(equ: Equation): Circle {
|
|
179
|
+
this._exists = false
|
|
180
|
+
|
|
181
|
+
// Move everything to the left.
|
|
182
|
+
equ.moveLeft()
|
|
183
|
+
|
|
184
|
+
if (equ.degree('x').value === 2 && equ.degree('y').value === 2) {
|
|
99
185
|
// Both must be of degree 2.
|
|
100
|
-
let x2 =
|
|
101
|
-
y2 =
|
|
186
|
+
let x2 = equ.left.monomByDegree(2, 'x'),
|
|
187
|
+
y2 = equ.left.monomByDegree(2, 'y'),
|
|
102
188
|
x1: Monom, y1: Monom, c: Monom
|
|
103
189
|
|
|
104
190
|
// Both square monoms must have the same coefficient.
|
|
105
191
|
if (x2.coefficient.isEqual(y2.coefficient)) {
|
|
106
|
-
|
|
192
|
+
equ.divide(x2.coefficient)
|
|
107
193
|
|
|
108
|
-
x1 =
|
|
109
|
-
y1 =
|
|
194
|
+
x1 = equ.left.monomByDegree(1, 'x')
|
|
195
|
+
y1 = equ.left.monomByDegree(1, 'y')
|
|
110
196
|
|
|
111
|
-
c =
|
|
197
|
+
c = equ.left.monomByDegree(0)
|
|
112
198
|
|
|
113
199
|
this._center = new Point(
|
|
114
200
|
x1.coefficient.clone().divide(2).opposed(),
|
|
@@ -119,10 +205,25 @@ export class Circle {
|
|
|
119
205
|
.add(this._center.x.clone().pow(2))
|
|
120
206
|
.add(this._center.y.clone().pow(2))
|
|
121
207
|
|
|
208
|
+
this._calculateCartesian()
|
|
209
|
+
this._exists = true
|
|
210
|
+
}else{
|
|
211
|
+
// The circle is not a valid circle
|
|
212
|
+
this._center = null
|
|
213
|
+
this._squareRadius = null
|
|
214
|
+
this._exists = false
|
|
122
215
|
}
|
|
123
216
|
}
|
|
217
|
+
return this
|
|
218
|
+
}
|
|
124
219
|
|
|
125
|
-
|
|
220
|
+
private _parseThroughtThreePoints(A: Point, B: Point, C: Point): Circle {
|
|
221
|
+
let T = new Triangle(A, B, C),
|
|
222
|
+
mAB = T.remarquables.mediators.AB.clone(),
|
|
223
|
+
mAC = T.remarquables.mediators.AC.clone()
|
|
224
|
+
this.parse(mAB.intersection(mAC).point, A)
|
|
225
|
+
|
|
226
|
+
return this
|
|
126
227
|
}
|
|
127
228
|
|
|
128
229
|
/**
|
|
@@ -144,16 +245,30 @@ export class Circle {
|
|
|
144
245
|
}
|
|
145
246
|
|
|
146
247
|
lineIntersection = (L: Line): Point[] => {
|
|
147
|
-
let
|
|
248
|
+
let intersectionPoints: Point[] = [], solX: Fraction
|
|
249
|
+
|
|
250
|
+
if(this._cartesian===null){return []}
|
|
251
|
+
const equX = this._cartesian.clone(),
|
|
252
|
+
lineX = L.equation.clone().isolate('x'),
|
|
253
|
+
lineY = L.equation.clone().isolate('y')
|
|
254
|
+
|
|
255
|
+
if (lineX instanceof Equation && lineY instanceof Equation) {
|
|
256
|
+
equX.replaceBy('y', lineY.right).simplify()
|
|
257
|
+
equX.solve()
|
|
148
258
|
|
|
149
|
-
|
|
150
|
-
|
|
259
|
+
for(let x of equX.solutions){
|
|
260
|
+
if(x.exact===false && isNaN(x.value)){continue}
|
|
151
261
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
262
|
+
solX = new Fraction(x.exact===false?x.value:x.exact)
|
|
263
|
+
intersectionPoints.push(
|
|
264
|
+
new Point(
|
|
265
|
+
solX.clone(),
|
|
266
|
+
lineY.right.evaluate(solX)
|
|
267
|
+
)
|
|
268
|
+
)
|
|
269
|
+
}
|
|
155
270
|
}
|
|
156
271
|
|
|
157
|
-
return
|
|
272
|
+
return intersectionPoints
|
|
158
273
|
}
|
|
159
274
|
}
|
|
@@ -31,7 +31,7 @@ export class Line {
|
|
|
31
31
|
static PERPENDICULAR = LinePropriety.Perpendicular
|
|
32
32
|
static PARALLEL = LinePropriety.Parallel
|
|
33
33
|
|
|
34
|
-
constructor(...values:
|
|
34
|
+
constructor(...values: unknown[]) {
|
|
35
35
|
|
|
36
36
|
this._exists = false;
|
|
37
37
|
|
|
@@ -42,10 +42,6 @@ export class Line {
|
|
|
42
42
|
return this;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
get isLine(): boolean {
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
45
|
get exists(): boolean {
|
|
50
46
|
return this._exists;
|
|
51
47
|
}
|
|
@@ -189,6 +185,14 @@ export class Line {
|
|
|
189
185
|
(values[2] instanceof Fraction || typeof values[2] === 'number')
|
|
190
186
|
) {
|
|
191
187
|
return this.parseByCoefficient(values[0], values[1], values[2]);
|
|
188
|
+
}else if (
|
|
189
|
+
values[0] instanceof Point && values[1] instanceof Vector
|
|
190
|
+
){
|
|
191
|
+
if(values[2] === LinePropriety.Perpendicular){
|
|
192
|
+
return this.parseByPointAndNormal(values[0], values[1])
|
|
193
|
+
}else if (values[2] === LinePropriety.Parallel){
|
|
194
|
+
return this.parseByPointAndVector(values[0], values[1])
|
|
195
|
+
}
|
|
192
196
|
}
|
|
193
197
|
}
|
|
194
198
|
|
|
@@ -308,6 +312,19 @@ export class Line {
|
|
|
308
312
|
isSameAs = (line: Line): Boolean => {
|
|
309
313
|
return this.slope.isEqual(line.slope) && this.height.isEqual(line.height);
|
|
310
314
|
}
|
|
315
|
+
simplify = (): Line => {
|
|
316
|
+
let lcm = Numeric.lcm(this._a.denominator, this._b.denominator, this._c.denominator),
|
|
317
|
+
gcd = Numeric.gcd(this._a.numerator, this._b.numerator, this._c.numerator);
|
|
318
|
+
|
|
319
|
+
this.parseByCoefficient(
|
|
320
|
+
this._a.clone().multiply(lcm).divide(gcd),
|
|
321
|
+
this._b.clone().multiply(lcm).divide(gcd),
|
|
322
|
+
this._c.clone().multiply(lcm).divide(gcd),
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
return this
|
|
326
|
+
}
|
|
327
|
+
|
|
311
328
|
simplifyDirection = (): Line => {
|
|
312
329
|
let lcm = Numeric.lcm(this._d.x.denominator, this._d.y.denominator),
|
|
313
330
|
gcd = Numeric.gcd(this._d.x.numerator, this._d.y.numerator);
|
|
@@ -411,19 +428,21 @@ export class Line {
|
|
|
411
428
|
return false;
|
|
412
429
|
}
|
|
413
430
|
|
|
414
|
-
getValueAtX = (value: Fraction): Fraction => {
|
|
415
|
-
const equ = this.equation.clone().isolate('y')
|
|
431
|
+
getValueAtX = (value: Fraction|number): Fraction => {
|
|
432
|
+
const equ = this.equation.clone().isolate('y'),
|
|
433
|
+
F = new Fraction(value)
|
|
416
434
|
|
|
417
435
|
if(equ instanceof Equation){
|
|
418
|
-
return equ.right.evaluate({x:
|
|
436
|
+
return equ.right.evaluate({x: F})
|
|
419
437
|
}
|
|
420
438
|
return
|
|
421
439
|
}
|
|
422
|
-
getValueAtY = (value: Fraction): Fraction => {
|
|
423
|
-
const equ = this.equation.clone().isolate('x')
|
|
440
|
+
getValueAtY = (value: Fraction|number): Fraction => {
|
|
441
|
+
const equ = this.equation.clone().isolate('x'),
|
|
442
|
+
F = new Fraction(value)
|
|
424
443
|
|
|
425
444
|
if(equ instanceof Equation){
|
|
426
|
-
return equ.right.evaluate({y:
|
|
445
|
+
return equ.right.evaluate({y: F})
|
|
427
446
|
}
|
|
428
447
|
return
|
|
429
448
|
}
|
|
@@ -2,15 +2,22 @@
|
|
|
2
2
|
* Vector module contains everything necessary to handle 2d or 3d vectors.
|
|
3
3
|
* @module Vector
|
|
4
4
|
*/
|
|
5
|
-
import {Fraction} from "../coefficients
|
|
5
|
+
import {Fraction} from "../coefficients"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Helper class - a way to identify an object {x: number, y: number}
|
|
9
|
+
*/
|
|
10
|
+
class PointXY {
|
|
11
|
+
public x: number
|
|
12
|
+
public y: number
|
|
13
|
+
}
|
|
6
14
|
|
|
7
|
-
//TODO: Ajouter une vérification si la droite existe.
|
|
8
15
|
export class Point {
|
|
9
16
|
private _x: Fraction; // 1st component
|
|
10
17
|
private _y: Fraction; // 2nd component
|
|
11
18
|
private _exist: Boolean;
|
|
12
19
|
|
|
13
|
-
constructor(...values:
|
|
20
|
+
constructor(...values: unknown[]) {
|
|
14
21
|
this._x = new Fraction().zero();
|
|
15
22
|
this._y = new Fraction().zero();
|
|
16
23
|
|
|
@@ -21,10 +28,6 @@ export class Point {
|
|
|
21
28
|
return this
|
|
22
29
|
};
|
|
23
30
|
|
|
24
|
-
get isPoint() {
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
31
|
// ------------------------------------------
|
|
29
32
|
// Getter and setter
|
|
30
33
|
// ------------------------------------------
|
|
@@ -66,7 +69,8 @@ export class Point {
|
|
|
66
69
|
// Creation / parsing functions
|
|
67
70
|
// ------------------------------------------
|
|
68
71
|
|
|
69
|
-
|
|
72
|
+
|
|
73
|
+
parse = (...values: unknown[]): Point => {
|
|
70
74
|
// Initialize the value.
|
|
71
75
|
this.zero();
|
|
72
76
|
|
|
@@ -81,30 +85,33 @@ export class Point {
|
|
|
81
85
|
if (values[0] instanceof Point) {
|
|
82
86
|
this._x = values[0].x.clone()
|
|
83
87
|
this._y = values[0].y.clone()
|
|
84
|
-
return this
|
|
88
|
+
return this
|
|
85
89
|
}
|
|
86
90
|
|
|
87
91
|
// Value is given as string, comma separated.
|
|
88
|
-
if(typeof values[0] === 'string'){
|
|
92
|
+
if (typeof values[0] === 'string') {
|
|
89
93
|
let xy = values[0].split(',')
|
|
90
|
-
if(xy.length===2){
|
|
94
|
+
if (xy.length === 2) {
|
|
91
95
|
this._x = new Fraction(xy[0]).reduce()
|
|
92
96
|
this._y = new Fraction(xy[1]).reduce()
|
|
93
|
-
return this
|
|
97
|
+
return this
|
|
94
98
|
}
|
|
95
99
|
}
|
|
96
100
|
|
|
97
101
|
// Value given as an object with {x: value, y: value}
|
|
98
|
-
if
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
if(values[0] instanceof PointXY){
|
|
103
|
+
this._x = new Fraction(values[0].x).reduce()
|
|
104
|
+
this._y = new Fraction(values[0].y).reduce()
|
|
105
|
+
return this
|
|
101
106
|
} else {
|
|
102
|
-
return this.zero()
|
|
107
|
+
return this.zero()
|
|
103
108
|
}
|
|
104
109
|
}
|
|
110
|
+
|
|
105
111
|
if (values.length === 2) {
|
|
106
112
|
this._x = new Fraction(values[0]).reduce()
|
|
107
113
|
this._y = new Fraction(values[1]).reduce()
|
|
114
|
+
return this
|
|
108
115
|
}
|
|
109
116
|
|
|
110
117
|
return this;
|
|
@@ -140,8 +147,8 @@ export class Point {
|
|
|
140
147
|
texValues = (numberOfDigits: number): string => {
|
|
141
148
|
let pts = [];
|
|
142
149
|
|
|
143
|
-
pts.push(this._x.value.toFixed(numberOfDigits===undefined?2:numberOfDigits));
|
|
144
|
-
pts.push(this._y.value.toFixed(numberOfDigits===undefined?2:numberOfDigits));
|
|
150
|
+
pts.push(this._x.value.toFixed(numberOfDigits === undefined ? 2 : numberOfDigits));
|
|
151
|
+
pts.push(this._y.value.toFixed(numberOfDigits === undefined ? 2 : numberOfDigits));
|
|
145
152
|
|
|
146
153
|
return `\\left(${pts.join(';')}\\right)`
|
|
147
154
|
}
|