pimath 0.0.17 → 0.0.21
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/index.html +46 -9
- package/dev/pi.js +890 -806
- package/dev/pi.js.map +1 -1
- package/dist/pi.js +1 -1
- package/dist/pi.js.map +1 -1
- package/esm/maths/algebra/equation.d.ts +1 -0
- package/esm/maths/algebra/equation.js +5 -2
- package/esm/maths/algebra/equation.js.map +1 -1
- package/esm/maths/algebra/monom.d.ts +1 -1
- package/esm/maths/algebra/monom.js +27 -18
- package/esm/maths/algebra/monom.js.map +1 -1
- package/esm/maths/algebra/polynom.d.ts +0 -1
- package/esm/maths/algebra/polynom.js +7 -11
- package/esm/maths/algebra/polynom.js.map +1 -1
- package/esm/maths/geometry/circle.d.ts +16 -1
- package/esm/maths/geometry/circle.js +89 -12
- package/esm/maths/geometry/circle.js.map +1 -1
- package/esm/maths/geometry/line.d.ts +20 -4
- package/esm/maths/geometry/line.js +109 -39
- package/esm/maths/geometry/line.js.map +1 -1
- package/esm/maths/geometry/point.d.ts +1 -0
- package/esm/maths/geometry/point.js +6 -0
- package/esm/maths/geometry/point.js.map +1 -1
- package/esm/maths/geometry/vector.d.ts +0 -1
- package/esm/maths/geometry/vector.js +1 -4
- package/esm/maths/geometry/vector.js.map +1 -1
- package/esm/maths/random/rndFraction.js +8 -2
- package/esm/maths/random/rndFraction.js.map +1 -1
- package/esm/maths/random/rndMonom.js +2 -1
- package/esm/maths/random/rndMonom.js.map +1 -1
- package/esm/maths/random/rndTypes.d.ts +1 -0
- package/package.json +1 -1
- package/src/maths/algebra/equation.ts +7 -2
- package/src/maths/algebra/monom.ts +40 -25
- package/src/maths/algebra/polynom.ts +9 -13
- package/src/maths/geometry/circle.ts +133 -21
- package/src/maths/geometry/line.ts +161 -57
- package/src/maths/geometry/point.ts +9 -0
- package/src/maths/geometry/vector.ts +1 -5
- package/src/maths/random/rndFraction.ts +7 -2
- package/src/maths/random/rndMonom.ts +2 -1
- package/src/maths/random/rndTypes.ts +2 -1
- package/tests/algebra/monom.test.ts +25 -7
- package/tsconfig.json +1 -1
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
* This class works for 2d line in a plane.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {Fraction} from "../coefficients
|
|
5
|
+
import {Fraction} from "../coefficients";
|
|
6
6
|
import {Vector} from "./vector";
|
|
7
7
|
import {Point} from "./point";
|
|
8
|
-
import {Polynom} from "../algebra
|
|
8
|
+
import {Equation, Polynom} from "../algebra";
|
|
9
9
|
import {Numeric} from "../numeric";
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
enum LinePropriety {
|
|
12
|
+
None,
|
|
13
|
+
Parallel,
|
|
14
|
+
Perpendicular
|
|
15
|
+
}
|
|
11
16
|
|
|
12
17
|
export class Line {
|
|
13
18
|
// A line is defined as the canonical form
|
|
@@ -20,19 +25,30 @@ export class Line {
|
|
|
20
25
|
private _n: Vector;
|
|
21
26
|
private _exists: boolean
|
|
22
27
|
|
|
28
|
+
private _referencePropriety: LinePropriety
|
|
29
|
+
private _referenceLine: Line
|
|
30
|
+
|
|
31
|
+
static PERPENDICULAR = LinePropriety.Perpendicular
|
|
32
|
+
static PARALLEL = LinePropriety.Parallel
|
|
33
|
+
|
|
23
34
|
constructor(...values: any) {
|
|
24
35
|
|
|
25
36
|
this._exists = false;
|
|
26
37
|
|
|
27
|
-
if (values
|
|
38
|
+
if (values.length > 0) {
|
|
28
39
|
this.parse(...values);
|
|
29
40
|
}
|
|
30
41
|
|
|
31
42
|
return this;
|
|
32
43
|
}
|
|
33
44
|
|
|
34
|
-
get isLine():boolean {
|
|
35
|
-
|
|
45
|
+
get isLine(): boolean {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get exists(): boolean {
|
|
50
|
+
return this._exists;
|
|
51
|
+
}
|
|
36
52
|
|
|
37
53
|
// ------------------------------------------
|
|
38
54
|
// Getter and setter
|
|
@@ -40,6 +56,7 @@ export class Line {
|
|
|
40
56
|
get equation(): Equation {
|
|
41
57
|
return new Equation(new Polynom().parse('xy', this._a, this._b, this._c), new Polynom('0')).simplify();
|
|
42
58
|
}
|
|
59
|
+
|
|
43
60
|
get tex(): { canonical: string, mxh: string, parametric: string } {
|
|
44
61
|
// canonical => ax + by + c = 0
|
|
45
62
|
// mxh => y = -a/b x - c/b
|
|
@@ -47,7 +64,7 @@ export class Line {
|
|
|
47
64
|
|
|
48
65
|
let canonical = this.equation;
|
|
49
66
|
// Make sur the first item is positive.
|
|
50
|
-
if(this._a.isNegative()){
|
|
67
|
+
if (this._a.isNegative()) {
|
|
51
68
|
canonical.multiply(-1);
|
|
52
69
|
}
|
|
53
70
|
|
|
@@ -102,6 +119,10 @@ export class Line {
|
|
|
102
119
|
return new Vector(this._a, this._b);
|
|
103
120
|
}
|
|
104
121
|
|
|
122
|
+
get director(): Vector {
|
|
123
|
+
return this._d.clone()
|
|
124
|
+
}
|
|
125
|
+
|
|
105
126
|
set d(value: Vector) {
|
|
106
127
|
this._d = value;
|
|
107
128
|
}
|
|
@@ -117,61 +138,96 @@ export class Line {
|
|
|
117
138
|
// ------------------------------------------
|
|
118
139
|
// Creation / parsing functions
|
|
119
140
|
// ------------------------------------------
|
|
120
|
-
|
|
141
|
+
/**
|
|
142
|
+
* Parse data to a line
|
|
143
|
+
* @param {any} values
|
|
144
|
+
* @returns {Line}
|
|
145
|
+
*/
|
|
146
|
+
parse = (...values: unknown[]): Line => {
|
|
121
147
|
this._exists = false;
|
|
122
148
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
149
|
+
// Nothing is given...
|
|
150
|
+
if (values.length === 0) {
|
|
151
|
+
return this
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// One value only: already a line (clone it), an Equation, a string (as Equation)
|
|
155
|
+
if (values.length === 1) {
|
|
156
|
+
if (values[0] instanceof Line) {
|
|
157
|
+
// Already a Line
|
|
158
|
+
return values[0].clone()
|
|
159
|
+
} else if (values[0] instanceof Equation) {
|
|
160
|
+
// It's an Equation
|
|
161
|
+
return this.parseEquation(values[0])
|
|
162
|
+
} else if (typeof values[0] === "string") {
|
|
163
|
+
// It's a string - create an Equation from it.
|
|
164
|
+
try {
|
|
165
|
+
let E = new Equation(values[0])
|
|
166
|
+
return this.parse(E)
|
|
167
|
+
} catch (e) {
|
|
168
|
+
return this
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (values.length === 2) {
|
|
174
|
+
if (values[0] instanceof Point && values[1] instanceof Vector) {
|
|
127
175
|
return this.parseByPointAndVector(values[0], values[1]);
|
|
128
|
-
} else if (values[0]
|
|
176
|
+
} else if (values[0] instanceof Point && values[1] instanceof Point) {
|
|
129
177
|
return this.parseByPointAndVector(values[0], new Vector(values[0], values[1]));
|
|
178
|
+
} else if (values[0] instanceof Vector && values[1] instanceof Point) {
|
|
179
|
+
return this.parseByPointAndNormal(values[1], values[0])
|
|
130
180
|
}
|
|
131
|
-
}
|
|
132
|
-
// It's a already a line - clone it !
|
|
133
|
-
if(values[0].isLine){
|
|
134
|
-
return values[0].clone();
|
|
135
|
-
}
|
|
181
|
+
}
|
|
136
182
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
183
|
+
if (values.length === 3) {
|
|
184
|
+
if (
|
|
185
|
+
(values[0] instanceof Fraction || typeof values[0] === 'number')
|
|
186
|
+
&&
|
|
187
|
+
(values[1] instanceof Fraction || typeof values[1] === 'number')
|
|
188
|
+
&&
|
|
189
|
+
(values[2] instanceof Fraction || typeof values[2] === 'number')
|
|
190
|
+
) {
|
|
191
|
+
return this.parseByCoefficient(values[0], values[1], values[2]);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
142
194
|
|
|
143
|
-
|
|
144
|
-
|
|
195
|
+
// TODO: Add the ability to create line from a normal vector
|
|
196
|
+
console.log('Someting wrong happend while creating the line')
|
|
197
|
+
return this;
|
|
198
|
+
}
|
|
145
199
|
|
|
146
|
-
|
|
147
|
-
|
|
200
|
+
parseEquation = (equ: Equation): Line => {
|
|
201
|
+
// Reorder the eequation
|
|
202
|
+
equ.reorder(true)
|
|
148
203
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if(letters.has(elem)){
|
|
152
|
-
letters.delete(elem)}
|
|
153
|
-
}
|
|
204
|
+
// It must contain either x, y or both.
|
|
205
|
+
let letters = new Set(equ.letters());
|
|
154
206
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
207
|
+
// No 'x', no 'y' in the equations
|
|
208
|
+
if (!(letters.has('x') || letters.has('y'))) {
|
|
209
|
+
return this
|
|
210
|
+
}
|
|
159
211
|
|
|
160
|
-
|
|
161
|
-
|
|
212
|
+
// Another letter in the equation ?
|
|
213
|
+
for (let elem of ['x', 'y']) {
|
|
214
|
+
if (letters.has(elem)) {
|
|
215
|
+
letters.delete(elem)
|
|
162
216
|
}
|
|
163
217
|
}
|
|
164
|
-
// TODO: Add the ability to create line from a normal vector
|
|
165
|
-
console.log('Someting wrong happend while creating the line')
|
|
166
|
-
return this;
|
|
167
|
-
}
|
|
168
218
|
|
|
169
|
-
|
|
219
|
+
if (letters.size > 0) {
|
|
220
|
+
return this
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Everything should be ok now...
|
|
224
|
+
return this.parseByCoefficient(equ.left.monomByLetter('x').coefficient, equ.left.monomByLetter('y').coefficient, equ.left.monomByDegree(0).coefficient)
|
|
225
|
+
}
|
|
226
|
+
parseByCoefficient = (a: Fraction | number, b: Fraction | number, c: Fraction | number): Line => {
|
|
170
227
|
this._a = new Fraction(a);
|
|
171
228
|
this._b = new Fraction(b);
|
|
172
229
|
this._c = new Fraction(c);
|
|
173
230
|
|
|
174
|
-
// TODO: initialize direction and reference point
|
|
175
231
|
this._d = new Vector(this._b.clone(), this._a.clone().opposed());
|
|
176
232
|
this._OA = new Point(new Fraction().zero(), this._c.clone());
|
|
177
233
|
this._n = this._d.clone().normal();
|
|
@@ -205,6 +261,31 @@ export class Line {
|
|
|
205
261
|
return this;
|
|
206
262
|
}
|
|
207
263
|
|
|
264
|
+
parseByPointAndNormal = (P: Point, n: Vector): Line => {
|
|
265
|
+
return this.parseByCoefficient(
|
|
266
|
+
n.x,
|
|
267
|
+
n.y,
|
|
268
|
+
P.x.clone().multiply(n.x)
|
|
269
|
+
.add(P.y.clone().multiply(n.y)).opposed()
|
|
270
|
+
)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
parseByPointAndLine = (P: Point, L: Line, orientation?: LinePropriety): Line => {
|
|
274
|
+
|
|
275
|
+
if (orientation === undefined) {
|
|
276
|
+
orientation = LinePropriety.Parallel
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (orientation === LinePropriety.Parallel) {
|
|
280
|
+
return this.parseByPointAndNormal(P, L.normal)
|
|
281
|
+
} else if (orientation === LinePropriety.Perpendicular) {
|
|
282
|
+
return this.parseByPointAndNormal(P, L.director)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
this._exists = false
|
|
286
|
+
return this
|
|
287
|
+
}
|
|
288
|
+
|
|
208
289
|
clone = (): Line => {
|
|
209
290
|
this._a = this._a.clone();
|
|
210
291
|
this._b = this._b.clone();
|
|
@@ -214,6 +295,7 @@ export class Line {
|
|
|
214
295
|
this._OA = this._OA.clone();
|
|
215
296
|
this._n = this._n.clone();
|
|
216
297
|
|
|
298
|
+
this._exists = this.exists
|
|
217
299
|
return this;
|
|
218
300
|
}
|
|
219
301
|
// ------------------------------------------
|
|
@@ -320,7 +402,7 @@ export class Line {
|
|
|
320
402
|
)
|
|
321
403
|
|
|
322
404
|
// There is an intersection point
|
|
323
|
-
if(iPt.hasIntersection) {
|
|
405
|
+
if (iPt.hasIntersection) {
|
|
324
406
|
return iPt.point.x.value >= Math.min(A.x.value, B.x.value)
|
|
325
407
|
&& iPt.point.x.value <= Math.max(A.x.value, B.x.value)
|
|
326
408
|
&& iPt.point.y.value >= Math.min(A.y.value, B.y.value)
|
|
@@ -328,36 +410,58 @@ export class Line {
|
|
|
328
410
|
}
|
|
329
411
|
return false;
|
|
330
412
|
}
|
|
413
|
+
|
|
414
|
+
getValueAtX = (value: Fraction): Fraction => {
|
|
415
|
+
const equ = this.equation.clone().isolate('y')
|
|
416
|
+
|
|
417
|
+
if(equ instanceof Equation){
|
|
418
|
+
return equ.right.evaluate({x: value})
|
|
419
|
+
}
|
|
420
|
+
return
|
|
421
|
+
}
|
|
422
|
+
getValueAtY = (value: Fraction): Fraction => {
|
|
423
|
+
const equ = this.equation.clone().isolate('x')
|
|
424
|
+
|
|
425
|
+
if(equ instanceof Equation){
|
|
426
|
+
return equ.right.evaluate({y: value})
|
|
427
|
+
}
|
|
428
|
+
return
|
|
429
|
+
}
|
|
430
|
+
|
|
331
431
|
// ------------------------------------------
|
|
332
432
|
// Special functions
|
|
333
433
|
// ------------------------------------------
|
|
334
|
-
canonicalAsFloatCoefficient(decimals: number): string{
|
|
335
|
-
if(decimals===undefined){
|
|
434
|
+
canonicalAsFloatCoefficient(decimals: number): string {
|
|
435
|
+
if (decimals === undefined) {
|
|
336
436
|
decimals = 2;
|
|
337
437
|
}
|
|
338
438
|
|
|
339
439
|
let ca = this._a.value,
|
|
340
440
|
cb = this._b.value,
|
|
341
|
-
cc= this._c.value,
|
|
441
|
+
cc = this._c.value,
|
|
342
442
|
canonical = '';
|
|
343
443
|
|
|
344
|
-
if(!this._a.isZero()){
|
|
345
|
-
if(this._a.isOne()){
|
|
444
|
+
if (!this._a.isZero()) {
|
|
445
|
+
if (this._a.isOne()) {
|
|
346
446
|
canonical = 'x'
|
|
347
|
-
}else if(this._a.clone().opposed().isOne()){
|
|
447
|
+
} else if (this._a.clone().opposed().isOne()) {
|
|
348
448
|
canonical = '-x'
|
|
349
|
-
}else{
|
|
350
|
-
canonical = this._a.value.toFixed(decimals)+'x'
|
|
449
|
+
} else {
|
|
450
|
+
canonical = this._a.value.toFixed(decimals) + 'x'
|
|
351
451
|
}
|
|
352
452
|
}
|
|
353
453
|
|
|
354
|
-
if(!this._b.isZero()){
|
|
355
|
-
if(this._b.isPositive()){
|
|
454
|
+
if (!this._b.isZero()) {
|
|
455
|
+
if (this._b.isPositive()) {
|
|
456
|
+
canonical += '+'
|
|
457
|
+
}
|
|
356
458
|
canonical += this._b.value.toFixed(decimals) + 'y'
|
|
357
459
|
}
|
|
358
460
|
|
|
359
|
-
if(!this._c.isZero()){
|
|
360
|
-
if(this._c.isPositive()){
|
|
461
|
+
if (!this._c.isZero()) {
|
|
462
|
+
if (this._c.isPositive()) {
|
|
463
|
+
canonical += '+'
|
|
464
|
+
}
|
|
361
465
|
canonical += this._c.value.toFixed(decimals)
|
|
362
466
|
}
|
|
363
467
|
|
|
@@ -53,6 +53,15 @@ export class Point {
|
|
|
53
53
|
return `\\left(${pts.join(';')}\\right)`
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
get display(): string {
|
|
57
|
+
let pts = [];
|
|
58
|
+
|
|
59
|
+
pts.push(this._x.tex);
|
|
60
|
+
pts.push(this._y.tex);
|
|
61
|
+
|
|
62
|
+
return `(${pts.join(';')})`
|
|
63
|
+
}
|
|
64
|
+
|
|
56
65
|
// ------------------------------------------
|
|
57
66
|
// Creation / parsing functions
|
|
58
67
|
// ------------------------------------------
|
|
@@ -18,10 +18,6 @@ export class Vector {
|
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
get isVector() {
|
|
22
|
-
return true;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
21
|
// ------------------------------------------
|
|
26
22
|
// Getter and setter
|
|
27
23
|
// ------------------------------------------
|
|
@@ -68,7 +64,7 @@ export class Vector {
|
|
|
68
64
|
}
|
|
69
65
|
|
|
70
66
|
if (values.length === 1) {
|
|
71
|
-
if (values[0]
|
|
67
|
+
if (values[0] instanceof Vector) {
|
|
72
68
|
return values[0].clone()
|
|
73
69
|
} else {
|
|
74
70
|
return this._parseString(values[0])
|
|
@@ -16,7 +16,8 @@ export class rndFraction extends randomCore {
|
|
|
16
16
|
this._defaultConfig = {
|
|
17
17
|
negative: true,
|
|
18
18
|
reduced: true,
|
|
19
|
-
zero: true
|
|
19
|
+
zero: true,
|
|
20
|
+
natural: false
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
this._config = this.mergeConfig(userConfig, this._defaultConfig)
|
|
@@ -30,7 +31,11 @@ export class rndFraction extends randomCore {
|
|
|
30
31
|
}else {
|
|
31
32
|
Q.numerator = Random.number(this._config.zero ? 0 : 1, 10)
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
+
if(this._config.natural){
|
|
35
|
+
Q.denominator = 1
|
|
36
|
+
}else {
|
|
37
|
+
Q.denominator = Random.number(1, 10)
|
|
38
|
+
}
|
|
34
39
|
|
|
35
40
|
return this._config.reduced?Q.reduce():Q
|
|
36
41
|
}
|
|
@@ -6,22 +6,40 @@ import exp = require("constants");
|
|
|
6
6
|
describe('Monom tests', ()=> {
|
|
7
7
|
it('parsing', ()=>{
|
|
8
8
|
const M0a = new Monom('3');
|
|
9
|
-
const M0b = new Monom('x');
|
|
10
|
-
const M1 = new Monom('3x^5');
|
|
11
|
-
const M2 = new Monom('2/3x^2yz^3y^4')
|
|
12
|
-
const M3 = new Monom('-3x^(-2)')
|
|
13
|
-
const M4 = new Monom('3x^(2/3)')
|
|
14
|
-
const M5 = new Monom('-3x^(-2/3)y^(-5)8x^3')
|
|
15
|
-
|
|
16
9
|
expect(M0a.tex).to.be.equal('3')
|
|
10
|
+
|
|
11
|
+
const M0b = new Monom('x');
|
|
17
12
|
expect(M0b.tex).to.be.equal('x')
|
|
13
|
+
|
|
14
|
+
const M0c = new Monom('3x');
|
|
15
|
+
expect(M0c.tex).to.be.equal('3x')
|
|
16
|
+
|
|
17
|
+
const M1 = new Monom('3x^5');
|
|
18
18
|
expect(M1.tex).to.be.equal('3x^{5}')
|
|
19
|
+
|
|
20
|
+
const M2 = new Monom('2/3x^2yz^3y^4')
|
|
19
21
|
expect(M2.display).to.be.equal('2/3x^2y^5z^3')
|
|
22
|
+
|
|
23
|
+
const M3 = new Monom('-3x^(-2)')
|
|
20
24
|
expect(M3.tex).to.be.equal('-3x^{-2}')
|
|
25
|
+
|
|
26
|
+
const M4 = new Monom('3x^(2/3)')
|
|
21
27
|
expect(M4.tex).to.be.equal('3x^{2/3}')
|
|
28
|
+
|
|
29
|
+
const M5 = new Monom('-3x^(-2/3)y^(-5)8x^3')
|
|
22
30
|
expect(M5.tex).to.be.equal('-24x^{7/3}y^{-5}')
|
|
23
31
|
})
|
|
24
32
|
|
|
33
|
+
it('basic operations', ()=>{
|
|
34
|
+
const M1 = new Monom('3x'),
|
|
35
|
+
M2 = new Monom('2x')
|
|
36
|
+
|
|
37
|
+
expect(M1.clone().add(M2).isEqual(new Monom('5x'))).to.be.true
|
|
38
|
+
expect(M1.clone().subtract(M2).isEqual(new Monom('x'))).to.be.true
|
|
39
|
+
expect(M1.clone().multiply(M2).isEqual(new Monom('6x^2'))).to.be.true
|
|
40
|
+
expect(M1.clone().divide(M2).isEqual(new Monom('3/2'))).to.be.true
|
|
41
|
+
})
|
|
42
|
+
|
|
25
43
|
it('derivative', () => { // the single test
|
|
26
44
|
const options = new Monom('7x^3'); // this will be your class
|
|
27
45
|
|