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.
Files changed (44) hide show
  1. package/dev/index.html +46 -9
  2. package/dev/pi.js +890 -806
  3. package/dev/pi.js.map +1 -1
  4. package/dist/pi.js +1 -1
  5. package/dist/pi.js.map +1 -1
  6. package/esm/maths/algebra/equation.d.ts +1 -0
  7. package/esm/maths/algebra/equation.js +5 -2
  8. package/esm/maths/algebra/equation.js.map +1 -1
  9. package/esm/maths/algebra/monom.d.ts +1 -1
  10. package/esm/maths/algebra/monom.js +27 -18
  11. package/esm/maths/algebra/monom.js.map +1 -1
  12. package/esm/maths/algebra/polynom.d.ts +0 -1
  13. package/esm/maths/algebra/polynom.js +7 -11
  14. package/esm/maths/algebra/polynom.js.map +1 -1
  15. package/esm/maths/geometry/circle.d.ts +16 -1
  16. package/esm/maths/geometry/circle.js +89 -12
  17. package/esm/maths/geometry/circle.js.map +1 -1
  18. package/esm/maths/geometry/line.d.ts +20 -4
  19. package/esm/maths/geometry/line.js +109 -39
  20. package/esm/maths/geometry/line.js.map +1 -1
  21. package/esm/maths/geometry/point.d.ts +1 -0
  22. package/esm/maths/geometry/point.js +6 -0
  23. package/esm/maths/geometry/point.js.map +1 -1
  24. package/esm/maths/geometry/vector.d.ts +0 -1
  25. package/esm/maths/geometry/vector.js +1 -4
  26. package/esm/maths/geometry/vector.js.map +1 -1
  27. package/esm/maths/random/rndFraction.js +8 -2
  28. package/esm/maths/random/rndFraction.js.map +1 -1
  29. package/esm/maths/random/rndMonom.js +2 -1
  30. package/esm/maths/random/rndMonom.js.map +1 -1
  31. package/esm/maths/random/rndTypes.d.ts +1 -0
  32. package/package.json +1 -1
  33. package/src/maths/algebra/equation.ts +7 -2
  34. package/src/maths/algebra/monom.ts +40 -25
  35. package/src/maths/algebra/polynom.ts +9 -13
  36. package/src/maths/geometry/circle.ts +133 -21
  37. package/src/maths/geometry/line.ts +161 -57
  38. package/src/maths/geometry/point.ts +9 -0
  39. package/src/maths/geometry/vector.ts +1 -5
  40. package/src/maths/random/rndFraction.ts +7 -2
  41. package/src/maths/random/rndMonom.ts +2 -1
  42. package/src/maths/random/rndTypes.ts +2 -1
  43. package/tests/algebra/monom.test.ts +25 -7
  44. 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/fraction";
5
+ import {Fraction} from "../coefficients";
6
6
  import {Vector} from "./vector";
7
7
  import {Point} from "./point";
8
- import {Polynom} from "../algebra/polynom";
8
+ import {Equation, Polynom} from "../algebra";
9
9
  import {Numeric} from "../numeric";
10
- import {Equation} from "../algebra/equation";
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 !== undefined) {
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 {return true;}
35
- get exists(): boolean {return this._exists; }
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
- parse = (...values: any): Line => {
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
- if (values.length === 3) {
124
- return this.parseByCoefficient(values[0], values[1], values[2]);
125
- } else if (values.length === 2) {
126
- if (values[0].isPoint && values[1].isVector) {
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].isPoint && values[1].isPoint) {
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
- } else if (values.length === 1){
132
- // It's a already a line - clone it !
133
- if(values[0].isLine){
134
- return values[0].clone();
135
- }
181
+ }
136
182
 
137
- // Maybe it's a string or an equation
138
- let equ = new Equation(values[0]);
139
- if(equ.isEquation){
140
- // Check if it's a valid equation.
141
- equ.reorder(true)
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
- // It must contain either x, y or both.
144
- let letters = new Set(equ.letters());
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
- // No 'x', no 'y' in the equations
147
- if(!(letters.has('x') || letters.has('y'))){return;}
200
+ parseEquation = (equ: Equation): Line => {
201
+ // Reorder the eequation
202
+ equ.reorder(true)
148
203
 
149
- // Another letter in the equation.
150
- for(let elem of ['x', 'y']){
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
- if(letters.size>0){
156
- console.log('Extra variable in the equation.')
157
- return this;
158
- }
207
+ // No 'x', no 'y' in the equations
208
+ if (!(letters.has('x') || letters.has('y'))) {
209
+ return this
210
+ }
159
211
 
160
- // Everything should be ok now...
161
- return this.parseByCoefficient(equ.left.monomByLetter('x').coefficient, equ.left.monomByLetter('y').coefficient, equ.left.monomByDegree(0).coefficient)
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
- parseByCoefficient = (a: Fraction, b: Fraction, c: Fraction): Line => {
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()){canonical+='+'}
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()){canonical+='+'}
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].isVector) {
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
- Q.denominator = Random.number(1, 10)
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
  }
@@ -30,7 +30,8 @@ import {Monom} from "../algebra/monom";
30
30
  // Generate the coefficient
31
31
  M.coefficient = Random.fraction({
32
32
  zero: this._config.zero,
33
- reduced: true
33
+ reduced: true,
34
+ natural: !this._config.fraction
34
35
  })
35
36
 
36
37
  // Calculate the degree of the monom
@@ -1,7 +1,8 @@
1
1
  export type randomCoefficientConfig = {
2
2
  negative?: boolean,
3
3
  reduced?: boolean,
4
- zero?:boolean
4
+ zero?:boolean,
5
+ natural?:boolean
5
6
  }
6
7
 
7
8
  export type randomMonomConfig = {
@@ -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
 
package/tsconfig.json CHANGED
@@ -16,7 +16,7 @@
16
16
  "module": "commonjs",
17
17
  "target": "esnext",
18
18
  "allowJs": true,
19
- "jsx": "react",
19
+ // "jsx": "react",
20
20
  "sourceMap": true,
21
21
  "moduleResolution": "node",
22
22
  "declaration": true,