pimath 0.0.119 → 0.0.121

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 (173) hide show
  1. package/.eslintrc.js +23 -23
  2. package/.idea/PI.iml +7 -1
  3. package/dev/pimath.js +7929 -0
  4. package/dev/pimath.js.map +1 -0
  5. package/dist/{pi.js → pimath.js} +7612 -7829
  6. package/dist/pimath.js.map +1 -0
  7. package/dist/pimath.min.js +2 -0
  8. package/dist/pimath.min.js.map +1 -0
  9. package/docs/assets/main.js +3 -3
  10. package/docs/assets/search.js +1 -1
  11. package/docs/assets/style.css +450 -363
  12. package/docs/classes/Logicalset.Logicalset.html +119 -110
  13. package/docs/classes/Polynom.Rational.html +230 -227
  14. package/docs/classes/Vector-1.Vector.html +319 -273
  15. package/docs/classes/Vector.Point.html +189 -190
  16. package/docs/classes/algebra_equation.Equation.html +489 -446
  17. package/docs/classes/algebra_linearSystem.LinearSystem.html +228 -217
  18. package/docs/classes/algebra_monom.Monom.html +564 -507
  19. package/docs/classes/algebra_polynom.Polynom.html +774 -753
  20. package/docs/classes/coefficients_fraction.Fraction.html +573 -565
  21. package/docs/classes/geometry_circle.Circle.html +299 -299
  22. package/docs/classes/geometry_line.Line.html +511 -451
  23. package/docs/classes/geometry_triangle.Triangle.html +273 -264
  24. package/docs/classes/numeric.Numeric.html +138 -132
  25. package/docs/classes/shutingyard.Shutingyard.html +144 -133
  26. package/docs/enums/algebra_equation.PARTICULAR_SOLUTION.html +47 -46
  27. package/docs/enums/geometry_line.LinePropriety.html +58 -58
  28. package/docs/enums/shutingyard.ShutingyardMode.html +62 -58
  29. package/docs/enums/shutingyard.ShutingyardType.html +74 -70
  30. package/docs/index.html +31 -33
  31. package/docs/interfaces/algebra_equation.ISolution.html +61 -59
  32. package/docs/interfaces/algebra_polynom.IEuclidian.html +47 -46
  33. package/docs/interfaces/geometry_triangle.remarquableLines.html +74 -74
  34. package/docs/modules/Logicalset.html +33 -38
  35. package/docs/modules/Polynom.html +33 -38
  36. package/docs/modules/Vector-1.html +33 -38
  37. package/docs/modules/Vector.html +33 -38
  38. package/docs/modules/algebra_equation.html +35 -41
  39. package/docs/modules/algebra_linearSystem.html +31 -37
  40. package/docs/modules/algebra_monom.html +33 -39
  41. package/docs/modules/algebra_polynom.html +35 -41
  42. package/docs/modules/coefficients_fraction.html +33 -39
  43. package/docs/modules/geometry_circle.html +31 -37
  44. package/docs/modules/geometry_line.html +33 -39
  45. package/docs/modules/geometry_triangle.html +33 -39
  46. package/docs/modules/numeric.html +31 -37
  47. package/docs/modules/shutingyard.html +41 -47
  48. package/docs/types/algebra_monom.literalType.html +33 -37
  49. package/docs/types/algebra_polynom.PolynomParsingType.html +33 -37
  50. package/docs/types/coefficients_fraction.FractionParsingType.html +32 -36
  51. package/docs/types/shutingyard.Token.html +38 -42
  52. package/docs/types/shutingyard.tokenType.html +40 -44
  53. package/docs/variables/shutingyard.tokenConstant.html +37 -41
  54. package/esm/index.d.ts +38 -41
  55. package/esm/index.js +43 -46
  56. package/esm/index.js.map +1 -1
  57. package/esm/maths/algebra/equation.d.ts +119 -117
  58. package/esm/maths/algebra/equation.js +796 -785
  59. package/esm/maths/algebra/equation.js.map +1 -1
  60. package/esm/maths/algebra/linearSystem.d.ts +39 -38
  61. package/esm/maths/algebra/linearSystem.js +278 -262
  62. package/esm/maths/algebra/linearSystem.js.map +1 -1
  63. package/esm/maths/algebra/logicalset.d.ts +28 -28
  64. package/esm/maths/algebra/logicalset.js +157 -157
  65. package/esm/maths/algebra/monom.d.ts +206 -206
  66. package/esm/maths/algebra/monom.js +908 -908
  67. package/esm/maths/algebra/monom.js.map +1 -1
  68. package/esm/maths/algebra/polynom.d.ts +157 -157
  69. package/esm/maths/algebra/polynom.js +1277 -1277
  70. package/esm/maths/algebra/rational.d.ts +45 -45
  71. package/esm/maths/algebra/rational.js +183 -183
  72. package/esm/maths/algebra/study/rationalStudy.d.ts +28 -28
  73. package/esm/maths/algebra/study/rationalStudy.js +243 -243
  74. package/esm/maths/algebra/study.d.ts +142 -142
  75. package/esm/maths/algebra/study.js +377 -377
  76. package/esm/maths/algebra/study.js.map +1 -1
  77. package/esm/maths/coefficients/fraction.d.ts +90 -90
  78. package/esm/maths/coefficients/fraction.js +516 -516
  79. package/esm/maths/coefficients/fraction.js.map +1 -1
  80. package/esm/maths/coefficients/nthRoot.d.ts +23 -23
  81. package/esm/maths/coefficients/nthRoot.js +136 -136
  82. package/esm/maths/geometry/circle.d.ts +45 -45
  83. package/esm/maths/geometry/circle.js +323 -323
  84. package/esm/maths/geometry/line.d.ts +99 -99
  85. package/esm/maths/geometry/line.js +481 -481
  86. package/esm/maths/geometry/line.js.map +1 -1
  87. package/esm/maths/geometry/point.d.ts +34 -34
  88. package/esm/maths/geometry/point.js +166 -166
  89. package/esm/maths/geometry/point.js.map +1 -1
  90. package/esm/maths/geometry/triangle.d.ts +85 -85
  91. package/esm/maths/geometry/triangle.js +268 -268
  92. package/esm/maths/geometry/vector.d.ts +41 -41
  93. package/esm/maths/geometry/vector.js +197 -197
  94. package/esm/maths/geometry/vector.js.map +1 -1
  95. package/esm/maths/numeric.d.ts +28 -28
  96. package/esm/maths/numeric.js +180 -169
  97. package/esm/maths/numeric.js.map +1 -1
  98. package/esm/maths/numexp.d.ts +19 -0
  99. package/esm/maths/numexp.js +186 -0
  100. package/esm/maths/numexp.js.map +1 -0
  101. package/esm/maths/randomization/random.d.ts +23 -23
  102. package/esm/maths/randomization/random.js +78 -78
  103. package/esm/maths/randomization/random.js.map +1 -1
  104. package/esm/maths/randomization/randomCore.d.ts +7 -7
  105. package/esm/maths/randomization/randomCore.js +21 -21
  106. package/esm/maths/randomization/rndFraction.d.ts +12 -12
  107. package/esm/maths/randomization/rndFraction.js +43 -43
  108. package/esm/maths/randomization/rndGeometryLine.d.ts +12 -12
  109. package/esm/maths/randomization/rndGeometryLine.js +45 -45
  110. package/esm/maths/randomization/rndGeometryPoint.d.ts +12 -12
  111. package/esm/maths/randomization/rndGeometryPoint.js +60 -60
  112. package/esm/maths/randomization/rndHelpers.d.ts +23 -23
  113. package/esm/maths/randomization/rndHelpers.js +76 -76
  114. package/esm/maths/randomization/rndMonom.d.ts +12 -12
  115. package/esm/maths/randomization/rndMonom.js +52 -52
  116. package/esm/maths/randomization/rndPolynom.d.ts +13 -13
  117. package/esm/maths/randomization/rndPolynom.js +74 -74
  118. package/esm/maths/randomization/rndTypes.d.ts +34 -34
  119. package/esm/maths/randomization/rndTypes.js +2 -2
  120. package/esm/maths/shutingyard.d.ts +59 -59
  121. package/esm/maths/shutingyard.js +442 -442
  122. package/esm/maths/shutingyard.js.map +1 -1
  123. package/package.json +11 -11
  124. package/public/index.html +50 -81
  125. package/public/playground.html +7 -8
  126. package/src/index.ts +2 -5
  127. package/src/maths/algebra/equation.ts +16 -0
  128. package/src/maths/algebra/linearSystem.ts +20 -0
  129. package/src/maths/algebra/study.ts +1 -1
  130. package/src/maths/numeric.ts +49 -48
  131. package/src/maths/{expressions/numexp.ts → numexp.ts} +2 -2
  132. package/tests/algebra/equation.test.ts +19 -5
  133. package/tests/algebra/linear.test.ts +3 -11
  134. package/tests/algebra/polynom.test.ts +7 -8
  135. package/tests/algebra/rationnal.test.ts +1 -1
  136. package/tests/algebra/study.test.ts +2 -9
  137. package/tests/coefficients/fraction.test.ts +8 -8
  138. package/tests/custom.test.ts +33 -37
  139. package/tests/numeric.test.ts +1 -2
  140. package/tests/numexp.test.ts +1 -5
  141. package/tests/shutingyard.test.ts +3 -3
  142. package/webpack-production-min.config.js +1 -1
  143. package/webpack-production.config.js +1 -1
  144. package/webpack.config.js +1 -1
  145. package/dist/pi.js.map +0 -1
  146. package/dist/pi.min.js +0 -2
  147. package/dist/pi.min.js.map +0 -1
  148. package/docs/classes/expressions_numexp.NumExp.html +0 -236
  149. package/docs/classes/expressions_polynomexp.PolynomExpFactor.html +0 -317
  150. package/docs/classes/expressions_polynomexp.PolynomExpProduct.html +0 -285
  151. package/docs/modules/expressions_numexp.html +0 -71
  152. package/docs/modules/expressions_polynomexp.html +0 -73
  153. package/docs/modules.html +0 -76
  154. package/graph.svg +0 -1033
  155. package/src/maths/expressions/ExpressionTree.ts +0 -172
  156. package/src/maths/expressions/expression.ts +0 -286
  157. package/src/maths/expressions/expressionFactor.ts +0 -190
  158. package/src/maths/expressions/expressionMember.ts +0 -233
  159. package/src/maths/expressions/expressionOperators.ts +0 -49
  160. package/src/maths/expressions/expressionParser.ts +0 -295
  161. package/src/maths/expressions/factors/ExpFactor.ts +0 -39
  162. package/src/maths/expressions/factors/ExpFactorConstant.ts +0 -60
  163. package/src/maths/expressions/factors/ExpFactorExponential.ts +0 -26
  164. package/src/maths/expressions/factors/ExpFactorNumber.ts +0 -72
  165. package/src/maths/expressions/factors/ExpFactorPower.ts +0 -42
  166. package/src/maths/expressions/factors/ExpFactorTrigo.ts +0 -53
  167. package/src/maths/expressions/factors/ExpFactorVariable.ts +0 -45
  168. package/src/maths/expressions/internals.ts +0 -14
  169. package/src/maths/expressions/polynomexp.bkp.ts +0 -221
  170. package/src/maths/expressions/polynomexp.ts +0 -310
  171. package/tests/expressions/expressions.test.ts +0 -145
  172. package/tests/expressions/expressiontree.test.ts +0 -11
  173. package/tests/polynomexp.test.ts +0 -12
@@ -1,324 +1,324 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Circle = void 0;
4
- const point_1 = require("./point");
5
- const line_1 = require("./line");
6
- const vector_1 = require("./vector");
7
- const triangle_1 = require("./triangle");
8
- const numeric_1 = require("../numeric");
9
- const fraction_1 = require("../coefficients/fraction");
10
- const equation_1 = require("../algebra/equation");
11
- const polynom_1 = require("../algebra/polynom");
12
- class Circle {
13
- constructor(...values) {
14
- /**
15
- * Get the relative position between circle and line. It corresponds to the number of intersection.
16
- * @param {Line} L
17
- * @returns {number}
18
- */
19
- this.relativePosition = (L) => {
20
- let distance = L.distanceTo(this.center), radius = Math.sqrt(this._squareRadius.value);
21
- if (distance.value - radius > 0.0000000001) {
22
- return 0; // external
23
- }
24
- else if (Math.abs(distance.value - radius) < 0.0000000001) {
25
- return 1; // tangent
26
- }
27
- else {
28
- return 2; // external
29
- }
30
- };
31
- this.lineIntersection = (L) => {
32
- let intersectionPoints = [], solX;
33
- if (this._cartesian === null) {
34
- return [];
35
- }
36
- const equX = this._cartesian.clone(), lineX = L.equation.clone().isolate('x'), lineY = L.equation.clone().isolate('y');
37
- if (lineX instanceof equation_1.Equation && lineY instanceof equation_1.Equation) {
38
- equX.replaceBy('y', lineY.right).simplify();
39
- equX.solve();
40
- for (let x of equX.solutions) {
41
- if (x.exact === false && isNaN(x.value)) {
42
- continue;
43
- }
44
- solX = new fraction_1.Fraction(x.exact === false ? x.value : x.exact);
45
- intersectionPoints.push(new point_1.Point(solX.clone(), lineY.right.evaluate(solX)));
46
- }
47
- }
48
- return intersectionPoints;
49
- };
50
- this.tangents = (P) => {
51
- if (P instanceof fraction_1.Fraction) {
52
- return this._tangentsWithSlope(P);
53
- }
54
- else if (this.isPointOnCircle(P)) {
55
- return this._tangentsThroughOnePointOnTheCircle(P);
56
- }
57
- else if (this.center.distanceTo(P).value > this.radius.value) {
58
- //TODO: Must check it's outside the circle
59
- return this._tangentsThroughOnePointOutsideTheCircle(P);
60
- }
61
- else {
62
- console.log('No tangents as the point is inside !');
63
- }
64
- return [];
65
- };
66
- this.isPointOnCircle = (P) => {
67
- return this._cartesian.test({ x: P.x, y: P.y });
68
- };
69
- this.getPointsOnCircle = (numberIsInteger) => {
70
- if (numberIsInteger === undefined) {
71
- numberIsInteger = false;
72
- }
73
- // It means searching for pythagorician triples that make a perfect square.
74
- // (x-4)^2 + (y+3)^2 = 15
75
- let triplets = numeric_1.Numeric.pythagoricianTripletsWithTarget(this._squareRadius.value, true);
76
- let points = [], pt;
77
- triplets.forEach(triplet => {
78
- // Allow positive / negative values
79
- // x-a = t => x = a + t
80
- // x-a = -t => x = a - t
81
- for (let k of [[1, 1], [-1, 1], [-1, -1], [1, -1]]) {
82
- pt = new point_1.Point(this.center.x.clone().add(k[0] * triplet[0]), this.center.y.clone().add(k[1] * triplet[1]));
83
- // Check if the point is not already in points.
84
- if (!pt.isInListOfPoints(points)) {
85
- points.push(pt);
86
- }
87
- }
88
- });
89
- return points;
90
- };
91
- this._tangentsThroughOnePointOnTheCircle = (P) => {
92
- let CT = new vector_1.Vector(this._center, P);
93
- return [new line_1.Line(P, CT, line_1.LinePropriety.Perpendicular)];
94
- };
95
- this._tangentsThroughOnePointOutsideTheCircle = (P) => {
96
- // y = mx + h
97
- // px, py => h = -m px + py => mx - y -m.px + py = 0 =>
98
- // Centre: cx, cy, radius: r
99
- // (m.cx - cy -m.px + py)^2 = r^2 * (m^2 + 1)
100
- // (m(cx-py) - (cy - py))^2 = r^2 * (m^2 + 1)
101
- let cx_px = this.center.x.clone().subtract(P.x), cy_py = this.center.y.clone().subtract(P.y), polyLeft = new polynom_1.Polynom('x'), polyRight = new polynom_1.Polynom('x^2+1');
102
- polyLeft.multiply(cx_px).subtract(cy_py).pow(2);
103
- polyRight.multiply(this.squareRadius);
104
- let equ = new equation_1.Equation(polyLeft, polyRight);
105
- equ.moveLeft().simplify().solve();
106
- return equ.solutions.map(sol => {
107
- // h = -m px + py
108
- let h, equ = new equation_1.Equation('y', 'x');
109
- if (sol.exact instanceof fraction_1.Fraction) {
110
- h = P.x.clone().opposed().multiply(sol.exact).add(P.y);
111
- equ.right.multiply(sol.exact).add(h);
112
- }
113
- else {
114
- h = P.x.clone().opposed().multiply(sol.value).add(P.y);
115
- equ.right.multiply(sol.value).add(h);
116
- }
117
- return new line_1.Line(equ);
118
- });
119
- };
120
- this._tangentsWithSlope = (slope) => {
121
- // d(C;t)=r => ac1+bc2 + x = +- sqrt(a^2 + b^2)*r
122
- // x = -ac1-bc2 +- sqrt(a^2 + b^2)*r
123
- // y = a/bx + h => ax-by + H = 0
124
- const a = slope.numerator, b = -slope.denominator, c1 = this._center.x.clone(), c2 = this._center.y.clone(), r = this._squareRadius;
125
- let sq = this._squareRadius.clone().multiply(slope.numerator ** 2 + slope.denominator ** 2), x1 = c1.clone().multiply(a).opposed().subtract(c2.clone().multiply(b)).add(sq.clone().sqrt()), x2 = c1.clone().multiply(a).opposed().subtract(c2.clone().multiply(b)).subtract(sq.clone().sqrt());
126
- return [new line_1.Line(a, b, x1), new line_1.Line(a, b, x2)];
127
- };
128
- this._exists = false;
129
- if (values !== undefined) {
130
- this.parse(...values);
131
- }
132
- }
133
- get center() {
134
- return this._center;
135
- }
136
- get squareRadius() {
137
- return this._squareRadius;
138
- }
139
- get cartesian() {
140
- return this._cartesian;
141
- }
142
- get exists() {
143
- return this._exists;
144
- }
145
- get radius() {
146
- if (this._squareRadius.isSquare()) {
147
- return {
148
- tex: this._squareRadius.clone().sqrt().tex,
149
- display: this._squareRadius.clone().sqrt().display,
150
- value: this._squareRadius.clone().sqrt().value
151
- };
152
- }
153
- else {
154
- return {
155
- tex: `\\sqrt{${this._squareRadius.tex}}`,
156
- display: `sqrt(${this._squareRadius.display})`,
157
- value: this._squareRadius.clone().sqrt().value
158
- };
159
- }
160
- return this._squareRadius;
161
- }
162
- get tex() {
163
- if (this._exists) {
164
- let cx, cy;
165
- if (this._center.x.isZero()) {
166
- cx = 'x^2';
167
- }
168
- else {
169
- cx = `\\left(x${this._center.x.isNegative() ? '+' : '-'}${this._center.x.clone().abs().tex}\\right)^2`;
170
- }
171
- if (this._center.y.isZero()) {
172
- cy = 'y^2';
173
- }
174
- else {
175
- cy = `\\left(y${this._center.y.isNegative() ? '+' : '-'}${this._center.y.clone().abs().tex}\\right)^2`;
176
- }
177
- return `${cx}+${cy}=${this._squareRadius.tex}`;
178
- }
179
- else {
180
- return `\\text{le cercle n'existe pas.}`;
181
- }
182
- }
183
- get developed() {
184
- return this._cartesian.tex;
185
- }
186
- get display() {
187
- if (this._exists) {
188
- let cx, cy;
189
- if (this._center.x.isZero()) {
190
- cx = 'x^2';
191
- }
192
- else {
193
- cx = `(x${this._center.x.isNegative() ? '+' : '-'}${this._center.x.clone().abs().tex})^2`;
194
- }
195
- if (this._center.y.isZero()) {
196
- cy = 'y^2';
197
- }
198
- else {
199
- cy = `(y${this._center.y.isNegative() ? '+' : '-'}${this._center.y.clone().abs().tex})^2`;
200
- }
201
- return `${cx}+${cy}=${this._squareRadius.display}`;
202
- }
203
- else {
204
- return `\\text{le cercle n'existe pas.}`;
205
- }
206
- }
207
- clone() {
208
- this._center = this._center.clone();
209
- this._squareRadius = this._squareRadius.clone();
210
- this._calculateCartesian();
211
- return this;
212
- }
213
- _reset() {
214
- this._center = null;
215
- this._squareRadius = null;
216
- this._cartesian = null;
217
- this._exists = false;
218
- return this;
219
- }
220
- parse(...values) {
221
- // Data can be given in these formats:
222
- // one value, a string -> make it an Equation
223
- // one value, an Equation
224
- // one value, a circle -> clone it
225
- // two values: two points (center and pointThrough)
226
- // two values: point and Fraction (center and radius)
227
- // three values: Point, Fraction, Boolean (center, square radius, true)
228
- this._reset();
229
- if (typeof values[0] === 'string') {
230
- this._parseEquation(new equation_1.Equation(values[0]));
231
- }
232
- else if (values[0] instanceof equation_1.Equation) {
233
- this._parseEquation(values[0]);
234
- }
235
- else if (values[0] instanceof Circle) {
236
- this._parseCopyCircle(values[0]);
237
- }
238
- else if (values[0] instanceof point_1.Point && values.length > 1) {
239
- if (values[1] instanceof point_1.Point) {
240
- if (values[2] instanceof point_1.Point) {
241
- this._parseThroughtThreePoints(values[0], values[1], values[2]);
242
- }
243
- else {
244
- this._parseCenterAndPointThrough(values[0], values[1]);
245
- }
246
- }
247
- else if (values[1] instanceof fraction_1.Fraction || typeof values[1] === 'number') {
248
- this._parseCenterAndRadius(values[0], values[1], (typeof values[2] === "boolean") ? values[2] : false);
249
- }
250
- }
251
- // Calculate once the different values.
252
- if (this._exists) {
253
- this._calculateCartesian();
254
- // If the square radius is zero or positive, the circle exists.
255
- if (this._squareRadius !== undefined && this._squareRadius.isNegative()) {
256
- this._exists = false;
257
- }
258
- }
259
- return this;
260
- }
261
- _calculateCartesian() {
262
- this._cartesian = (new equation_1.Equation(new polynom_1.Polynom(`(x-(${this._center.x.display}))^2+(y-(${this._center.y.display}))^2`), new polynom_1.Polynom(`${this._squareRadius.display}`))).moveLeft();
263
- }
264
- _parseCopyCircle(circle) {
265
- this._center = circle.center.clone();
266
- this._squareRadius = circle.squareRadius.clone();
267
- this._calculateCartesian();
268
- this._exists = circle.exists;
269
- return this;
270
- }
271
- _parseCenterAndRadius(center, radius, square) {
272
- this._center = center.clone();
273
- if (square) {
274
- this._squareRadius = (new fraction_1.Fraction(radius));
275
- }
276
- else {
277
- this._squareRadius = new fraction_1.Fraction(radius).pow(2);
278
- }
279
- this._exists = true;
280
- return this;
281
- }
282
- _parseCenterAndPointThrough(center, pointThrough) {
283
- this._center = center.clone();
284
- this._squareRadius = new vector_1.Vector(this._center, pointThrough).normSquare;
285
- this._exists = true;
286
- return this;
287
- }
288
- _parseEquation(equ) {
289
- this._exists = false;
290
- // Move everything to the left.
291
- equ.moveLeft();
292
- if (equ.degree('x').value === 2 && equ.degree('y').value === 2) {
293
- // Both must be of degree 2.
294
- let x2 = equ.left.monomByDegree(2, 'x'), y2 = equ.left.monomByDegree(2, 'y'), x1, y1, c;
295
- // Both square monoms must have the same coefficient.
296
- if (x2.coefficient.isEqual(y2.coefficient)) {
297
- equ.divide(x2.coefficient);
298
- x1 = equ.left.monomByDegree(1, 'x');
299
- y1 = equ.left.monomByDegree(1, 'y');
300
- c = equ.left.monomByDegree(0);
301
- this._center = new point_1.Point(x1.coefficient.clone().divide(2).opposed(), y1.coefficient.clone().divide(2).opposed());
302
- this._squareRadius = c.coefficient.clone().opposed()
303
- .add(this._center.x.clone().pow(2))
304
- .add(this._center.y.clone().pow(2));
305
- this._calculateCartesian();
306
- this._exists = true;
307
- }
308
- else {
309
- // The circle is not a valid circle
310
- this._center = null;
311
- this._squareRadius = null;
312
- this._exists = false;
313
- }
314
- }
315
- return this;
316
- }
317
- _parseThroughtThreePoints(A, B, C) {
318
- let T = new triangle_1.Triangle(A, B, C), mAB = T.remarquables.mediators.AB.clone(), mAC = T.remarquables.mediators.AC.clone();
319
- this.parse(mAB.intersection(mAC).point, A);
320
- return this;
321
- }
322
- }
323
- exports.Circle = Circle;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Circle = void 0;
4
+ const point_1 = require("./point");
5
+ const line_1 = require("./line");
6
+ const vector_1 = require("./vector");
7
+ const triangle_1 = require("./triangle");
8
+ const numeric_1 = require("../numeric");
9
+ const fraction_1 = require("../coefficients/fraction");
10
+ const equation_1 = require("../algebra/equation");
11
+ const polynom_1 = require("../algebra/polynom");
12
+ class Circle {
13
+ constructor(...values) {
14
+ /**
15
+ * Get the relative position between circle and line. It corresponds to the number of intersection.
16
+ * @param {Line} L
17
+ * @returns {number}
18
+ */
19
+ this.relativePosition = (L) => {
20
+ let distance = L.distanceTo(this.center), radius = Math.sqrt(this._squareRadius.value);
21
+ if (distance.value - radius > 0.0000000001) {
22
+ return 0; // external
23
+ }
24
+ else if (Math.abs(distance.value - radius) < 0.0000000001) {
25
+ return 1; // tangent
26
+ }
27
+ else {
28
+ return 2; // external
29
+ }
30
+ };
31
+ this.lineIntersection = (L) => {
32
+ let intersectionPoints = [], solX;
33
+ if (this._cartesian === null) {
34
+ return [];
35
+ }
36
+ const equX = this._cartesian.clone(), lineX = L.equation.clone().isolate('x'), lineY = L.equation.clone().isolate('y');
37
+ if (lineX instanceof equation_1.Equation && lineY instanceof equation_1.Equation) {
38
+ equX.replaceBy('y', lineY.right).simplify();
39
+ equX.solve();
40
+ for (let x of equX.solutions) {
41
+ if (x.exact === false && isNaN(x.value)) {
42
+ continue;
43
+ }
44
+ solX = new fraction_1.Fraction(x.exact === false ? x.value : x.exact);
45
+ intersectionPoints.push(new point_1.Point(solX.clone(), lineY.right.evaluate(solX)));
46
+ }
47
+ }
48
+ return intersectionPoints;
49
+ };
50
+ this.tangents = (P) => {
51
+ if (P instanceof fraction_1.Fraction) {
52
+ return this._tangentsWithSlope(P);
53
+ }
54
+ else if (this.isPointOnCircle(P)) {
55
+ return this._tangentsThroughOnePointOnTheCircle(P);
56
+ }
57
+ else if (this.center.distanceTo(P).value > this.radius.value) {
58
+ //TODO: Must check it's outside the circle
59
+ return this._tangentsThroughOnePointOutsideTheCircle(P);
60
+ }
61
+ else {
62
+ console.log('No tangents as the point is inside !');
63
+ }
64
+ return [];
65
+ };
66
+ this.isPointOnCircle = (P) => {
67
+ return this._cartesian.test({ x: P.x, y: P.y });
68
+ };
69
+ this.getPointsOnCircle = (numberIsInteger) => {
70
+ if (numberIsInteger === undefined) {
71
+ numberIsInteger = false;
72
+ }
73
+ // It means searching for pythagorician triples that make a perfect square.
74
+ // (x-4)^2 + (y+3)^2 = 15
75
+ let triplets = numeric_1.Numeric.pythagoricianTripletsWithTarget(this._squareRadius.value, true);
76
+ let points = [], pt;
77
+ triplets.forEach(triplet => {
78
+ // Allow positive / negative values
79
+ // x-a = t => x = a + t
80
+ // x-a = -t => x = a - t
81
+ for (let k of [[1, 1], [-1, 1], [-1, -1], [1, -1]]) {
82
+ pt = new point_1.Point(this.center.x.clone().add(k[0] * triplet[0]), this.center.y.clone().add(k[1] * triplet[1]));
83
+ // Check if the point is not already in points.
84
+ if (!pt.isInListOfPoints(points)) {
85
+ points.push(pt);
86
+ }
87
+ }
88
+ });
89
+ return points;
90
+ };
91
+ this._tangentsThroughOnePointOnTheCircle = (P) => {
92
+ let CT = new vector_1.Vector(this._center, P);
93
+ return [new line_1.Line(P, CT, line_1.LinePropriety.Perpendicular)];
94
+ };
95
+ this._tangentsThroughOnePointOutsideTheCircle = (P) => {
96
+ // y = mx + h
97
+ // px, py => h = -m px + py => mx - y -m.px + py = 0 =>
98
+ // Centre: cx, cy, radius: r
99
+ // (m.cx - cy -m.px + py)^2 = r^2 * (m^2 + 1)
100
+ // (m(cx-py) - (cy - py))^2 = r^2 * (m^2 + 1)
101
+ let cx_px = this.center.x.clone().subtract(P.x), cy_py = this.center.y.clone().subtract(P.y), polyLeft = new polynom_1.Polynom('x'), polyRight = new polynom_1.Polynom('x^2+1');
102
+ polyLeft.multiply(cx_px).subtract(cy_py).pow(2);
103
+ polyRight.multiply(this.squareRadius);
104
+ let equ = new equation_1.Equation(polyLeft, polyRight);
105
+ equ.moveLeft().simplify().solve();
106
+ return equ.solutions.map(sol => {
107
+ // h = -m px + py
108
+ let h, equ = new equation_1.Equation('y', 'x');
109
+ if (sol.exact instanceof fraction_1.Fraction) {
110
+ h = P.x.clone().opposed().multiply(sol.exact).add(P.y);
111
+ equ.right.multiply(sol.exact).add(h);
112
+ }
113
+ else {
114
+ h = P.x.clone().opposed().multiply(sol.value).add(P.y);
115
+ equ.right.multiply(sol.value).add(h);
116
+ }
117
+ return new line_1.Line(equ);
118
+ });
119
+ };
120
+ this._tangentsWithSlope = (slope) => {
121
+ // d(C;t)=r => ac1+bc2 + x = +- sqrt(a^2 + b^2)*r
122
+ // x = -ac1-bc2 +- sqrt(a^2 + b^2)*r
123
+ // y = a/bx + h => ax-by + H = 0
124
+ const a = slope.numerator, b = -slope.denominator, c1 = this._center.x.clone(), c2 = this._center.y.clone(), r = this._squareRadius;
125
+ let sq = this._squareRadius.clone().multiply(slope.numerator ** 2 + slope.denominator ** 2), x1 = c1.clone().multiply(a).opposed().subtract(c2.clone().multiply(b)).add(sq.clone().sqrt()), x2 = c1.clone().multiply(a).opposed().subtract(c2.clone().multiply(b)).subtract(sq.clone().sqrt());
126
+ return [new line_1.Line(a, b, x1), new line_1.Line(a, b, x2)];
127
+ };
128
+ this._exists = false;
129
+ if (values !== undefined) {
130
+ this.parse(...values);
131
+ }
132
+ }
133
+ get center() {
134
+ return this._center;
135
+ }
136
+ get squareRadius() {
137
+ return this._squareRadius;
138
+ }
139
+ get cartesian() {
140
+ return this._cartesian;
141
+ }
142
+ get exists() {
143
+ return this._exists;
144
+ }
145
+ get radius() {
146
+ if (this._squareRadius.isSquare()) {
147
+ return {
148
+ tex: this._squareRadius.clone().sqrt().tex,
149
+ display: this._squareRadius.clone().sqrt().display,
150
+ value: this._squareRadius.clone().sqrt().value
151
+ };
152
+ }
153
+ else {
154
+ return {
155
+ tex: `\\sqrt{${this._squareRadius.tex}}`,
156
+ display: `sqrt(${this._squareRadius.display})`,
157
+ value: this._squareRadius.clone().sqrt().value
158
+ };
159
+ }
160
+ return this._squareRadius;
161
+ }
162
+ get tex() {
163
+ if (this._exists) {
164
+ let cx, cy;
165
+ if (this._center.x.isZero()) {
166
+ cx = 'x^2';
167
+ }
168
+ else {
169
+ cx = `\\left(x${this._center.x.isNegative() ? '+' : '-'}${this._center.x.clone().abs().tex}\\right)^2`;
170
+ }
171
+ if (this._center.y.isZero()) {
172
+ cy = 'y^2';
173
+ }
174
+ else {
175
+ cy = `\\left(y${this._center.y.isNegative() ? '+' : '-'}${this._center.y.clone().abs().tex}\\right)^2`;
176
+ }
177
+ return `${cx}+${cy}=${this._squareRadius.tex}`;
178
+ }
179
+ else {
180
+ return `\\text{le cercle n'existe pas.}`;
181
+ }
182
+ }
183
+ get developed() {
184
+ return this._cartesian.tex;
185
+ }
186
+ get display() {
187
+ if (this._exists) {
188
+ let cx, cy;
189
+ if (this._center.x.isZero()) {
190
+ cx = 'x^2';
191
+ }
192
+ else {
193
+ cx = `(x${this._center.x.isNegative() ? '+' : '-'}${this._center.x.clone().abs().tex})^2`;
194
+ }
195
+ if (this._center.y.isZero()) {
196
+ cy = 'y^2';
197
+ }
198
+ else {
199
+ cy = `(y${this._center.y.isNegative() ? '+' : '-'}${this._center.y.clone().abs().tex})^2`;
200
+ }
201
+ return `${cx}+${cy}=${this._squareRadius.display}`;
202
+ }
203
+ else {
204
+ return `\\text{le cercle n'existe pas.}`;
205
+ }
206
+ }
207
+ clone() {
208
+ this._center = this._center.clone();
209
+ this._squareRadius = this._squareRadius.clone();
210
+ this._calculateCartesian();
211
+ return this;
212
+ }
213
+ _reset() {
214
+ this._center = null;
215
+ this._squareRadius = null;
216
+ this._cartesian = null;
217
+ this._exists = false;
218
+ return this;
219
+ }
220
+ parse(...values) {
221
+ // Data can be given in these formats:
222
+ // one value, a string -> make it an Equation
223
+ // one value, an Equation
224
+ // one value, a circle -> clone it
225
+ // two values: two points (center and pointThrough)
226
+ // two values: point and Fraction (center and radius)
227
+ // three values: Point, Fraction, Boolean (center, square radius, true)
228
+ this._reset();
229
+ if (typeof values[0] === 'string') {
230
+ this._parseEquation(new equation_1.Equation(values[0]));
231
+ }
232
+ else if (values[0] instanceof equation_1.Equation) {
233
+ this._parseEquation(values[0]);
234
+ }
235
+ else if (values[0] instanceof Circle) {
236
+ this._parseCopyCircle(values[0]);
237
+ }
238
+ else if (values[0] instanceof point_1.Point && values.length > 1) {
239
+ if (values[1] instanceof point_1.Point) {
240
+ if (values[2] instanceof point_1.Point) {
241
+ this._parseThroughtThreePoints(values[0], values[1], values[2]);
242
+ }
243
+ else {
244
+ this._parseCenterAndPointThrough(values[0], values[1]);
245
+ }
246
+ }
247
+ else if (values[1] instanceof fraction_1.Fraction || typeof values[1] === 'number') {
248
+ this._parseCenterAndRadius(values[0], values[1], (typeof values[2] === "boolean") ? values[2] : false);
249
+ }
250
+ }
251
+ // Calculate once the different values.
252
+ if (this._exists) {
253
+ this._calculateCartesian();
254
+ // If the square radius is zero or positive, the circle exists.
255
+ if (this._squareRadius !== undefined && this._squareRadius.isNegative()) {
256
+ this._exists = false;
257
+ }
258
+ }
259
+ return this;
260
+ }
261
+ _calculateCartesian() {
262
+ this._cartesian = (new equation_1.Equation(new polynom_1.Polynom(`(x-(${this._center.x.display}))^2+(y-(${this._center.y.display}))^2`), new polynom_1.Polynom(`${this._squareRadius.display}`))).moveLeft();
263
+ }
264
+ _parseCopyCircle(circle) {
265
+ this._center = circle.center.clone();
266
+ this._squareRadius = circle.squareRadius.clone();
267
+ this._calculateCartesian();
268
+ this._exists = circle.exists;
269
+ return this;
270
+ }
271
+ _parseCenterAndRadius(center, radius, square) {
272
+ this._center = center.clone();
273
+ if (square) {
274
+ this._squareRadius = (new fraction_1.Fraction(radius));
275
+ }
276
+ else {
277
+ this._squareRadius = new fraction_1.Fraction(radius).pow(2);
278
+ }
279
+ this._exists = true;
280
+ return this;
281
+ }
282
+ _parseCenterAndPointThrough(center, pointThrough) {
283
+ this._center = center.clone();
284
+ this._squareRadius = new vector_1.Vector(this._center, pointThrough).normSquare;
285
+ this._exists = true;
286
+ return this;
287
+ }
288
+ _parseEquation(equ) {
289
+ this._exists = false;
290
+ // Move everything to the left.
291
+ equ.moveLeft();
292
+ if (equ.degree('x').value === 2 && equ.degree('y').value === 2) {
293
+ // Both must be of degree 2.
294
+ let x2 = equ.left.monomByDegree(2, 'x'), y2 = equ.left.monomByDegree(2, 'y'), x1, y1, c;
295
+ // Both square monoms must have the same coefficient.
296
+ if (x2.coefficient.isEqual(y2.coefficient)) {
297
+ equ.divide(x2.coefficient);
298
+ x1 = equ.left.monomByDegree(1, 'x');
299
+ y1 = equ.left.monomByDegree(1, 'y');
300
+ c = equ.left.monomByDegree(0);
301
+ this._center = new point_1.Point(x1.coefficient.clone().divide(2).opposed(), y1.coefficient.clone().divide(2).opposed());
302
+ this._squareRadius = c.coefficient.clone().opposed()
303
+ .add(this._center.x.clone().pow(2))
304
+ .add(this._center.y.clone().pow(2));
305
+ this._calculateCartesian();
306
+ this._exists = true;
307
+ }
308
+ else {
309
+ // The circle is not a valid circle
310
+ this._center = null;
311
+ this._squareRadius = null;
312
+ this._exists = false;
313
+ }
314
+ }
315
+ return this;
316
+ }
317
+ _parseThroughtThreePoints(A, B, C) {
318
+ let T = new triangle_1.Triangle(A, B, C), mAB = T.remarquables.mediators.AB.clone(), mAC = T.remarquables.mediators.AC.clone();
319
+ this.parse(mAB.intersection(mAC).point, A);
320
+ return this;
321
+ }
322
+ }
323
+ exports.Circle = Circle;
324
324
  //# sourceMappingURL=circle.js.map