geometric-library 1.3.1 → 1.4.0

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 (143) hide show
  1. package/README.md +39 -430
  2. package/dist/cjs/abstracts/{Angle.js → angle/Angle.js} +11 -11
  3. package/dist/cjs/abstracts/angle/Angle.types.js +2 -0
  4. package/dist/cjs/abstracts/angle/index.js +18 -0
  5. package/dist/cjs/abstracts/{Figure.js → figure/Figure.js} +45 -30
  6. package/dist/cjs/abstracts/figure/Figure.types.js +2 -0
  7. package/dist/cjs/abstracts/figure/index.js +18 -0
  8. package/dist/cjs/abstracts/{Flag.js → flag/Flag.js} +1 -0
  9. package/dist/cjs/abstracts/flag/Flag.types.js +2 -0
  10. package/dist/cjs/abstracts/flag/index.js +18 -0
  11. package/dist/cjs/abstracts/index.js +22 -0
  12. package/dist/cjs/abstracts/{Magnitude.js → magnitude/Magnitude.js} +3 -2
  13. package/dist/cjs/abstracts/magnitude/Magnitude.types.js +2 -0
  14. package/dist/cjs/abstracts/magnitude/index.js +18 -0
  15. package/dist/cjs/abstracts/{Point.js → point/Point.js} +8 -7
  16. package/dist/cjs/abstracts/point/Point.types.js +2 -0
  17. package/dist/cjs/abstracts/point/index.js +18 -0
  18. package/dist/cjs/abstracts/{Vector.js → vector/Vector.js} +16 -15
  19. package/dist/cjs/abstracts/vector/Vector.types.js +2 -0
  20. package/dist/cjs/abstracts/vector/index.js +18 -0
  21. package/dist/cjs/figures/arc-curve/ArcCurve.js +174 -0
  22. package/dist/cjs/figures/arc-curve/ArcCurve.types.js +2 -0
  23. package/dist/cjs/figures/arc-curve/index.js +18 -0
  24. package/dist/cjs/figures/{Circle.js → circle/Circle.js} +8 -9
  25. package/dist/cjs/figures/circle/Circle.types.js +2 -0
  26. package/dist/cjs/figures/circle/index.js +18 -0
  27. package/dist/cjs/figures/{CubicBezierCurve.js → cubic-bezier-curve/CubicBezierCurve.js} +22 -17
  28. package/dist/cjs/figures/cubic-bezier-curve/CubicBezierCurve.types.js +2 -0
  29. package/dist/cjs/figures/cubic-bezier-curve/index.js +18 -0
  30. package/dist/cjs/figures/ellipse/Ellipse.js +129 -0
  31. package/dist/cjs/figures/ellipse/Ellipse.types.js +2 -0
  32. package/dist/cjs/figures/ellipse/index.js +18 -0
  33. package/dist/cjs/figures/index.js +23 -0
  34. package/dist/cjs/figures/{Line.js → line/Line.js} +78 -59
  35. package/dist/cjs/figures/line/Line.types.js +2 -0
  36. package/dist/cjs/figures/line/index.js +18 -0
  37. package/dist/cjs/figures/polygon/Polygon.js +51 -0
  38. package/dist/cjs/figures/polygon/Polygon.types.js +2 -0
  39. package/dist/cjs/figures/polygon/index.js +18 -0
  40. package/dist/cjs/figures/{QuadraticBezierCurve.js → quadratic-bezier-curve/QuadraticBezierCurve.js} +12 -8
  41. package/dist/cjs/figures/quadratic-bezier-curve/QuadraticBezierCurve.types.js +2 -0
  42. package/dist/cjs/figures/quadratic-bezier-curve/index.js +18 -0
  43. package/dist/cjs/index.js +2 -29
  44. package/dist/cjs/utilities/{Calculator.js → calculator/Calculator.js} +9 -1
  45. package/dist/cjs/utilities/calculator/index.js +17 -0
  46. package/dist/cjs/utilities/index.js +20 -8
  47. package/dist/esm/abstracts/{Angle.js → angle/Angle.js} +4 -4
  48. package/dist/esm/abstracts/angle/Angle.types.js +1 -0
  49. package/dist/esm/abstracts/angle/index.js +2 -0
  50. package/dist/esm/abstracts/{Figure.js → figure/Figure.js} +37 -22
  51. package/dist/esm/abstracts/figure/Figure.types.js +1 -0
  52. package/dist/esm/abstracts/figure/index.js +2 -0
  53. package/dist/esm/abstracts/{Flag.js → flag/Flag.js} +1 -0
  54. package/dist/esm/abstracts/flag/Flag.types.js +1 -0
  55. package/dist/esm/abstracts/flag/index.js +2 -0
  56. package/dist/esm/abstracts/index.js +6 -0
  57. package/dist/esm/abstracts/{Magnitude.js → magnitude/Magnitude.js} +2 -1
  58. package/dist/esm/abstracts/magnitude/Magnitude.types.js +1 -0
  59. package/dist/esm/abstracts/magnitude/index.js +2 -0
  60. package/dist/esm/abstracts/{Point.js → point/Point.js} +2 -1
  61. package/dist/esm/abstracts/point/Point.types.js +1 -0
  62. package/dist/esm/abstracts/point/index.js +2 -0
  63. package/dist/esm/abstracts/{Vector.js → vector/Vector.js} +3 -2
  64. package/dist/esm/abstracts/vector/Vector.types.js +1 -0
  65. package/dist/esm/abstracts/vector/index.js +2 -0
  66. package/dist/esm/figures/{ArcCurve.js → arc-curve/ArcCurve.js} +50 -8
  67. package/dist/esm/figures/arc-curve/ArcCurve.types.js +1 -0
  68. package/dist/esm/figures/arc-curve/index.js +2 -0
  69. package/dist/esm/figures/{Circle.js → circle/Circle.js} +3 -4
  70. package/dist/esm/figures/circle/Circle.types.js +1 -0
  71. package/dist/esm/figures/circle/index.js +2 -0
  72. package/dist/esm/figures/{CubicBezierCurve.js → cubic-bezier-curve/CubicBezierCurve.js} +11 -6
  73. package/dist/esm/figures/cubic-bezier-curve/CubicBezierCurve.types.js +1 -0
  74. package/dist/esm/figures/cubic-bezier-curve/index.js +2 -0
  75. package/dist/esm/figures/{Ellipse.js → ellipse/Ellipse.js} +24 -6
  76. package/dist/esm/figures/ellipse/Ellipse.types.js +1 -0
  77. package/dist/esm/figures/ellipse/index.js +2 -0
  78. package/dist/esm/figures/index.js +7 -0
  79. package/dist/esm/figures/{Line.js → line/Line.js} +57 -38
  80. package/dist/esm/figures/line/Line.types.js +1 -0
  81. package/dist/esm/figures/line/index.js +2 -0
  82. package/dist/esm/figures/polygon/Polygon.js +47 -0
  83. package/dist/esm/figures/polygon/Polygon.types.js +1 -0
  84. package/dist/esm/figures/polygon/index.js +2 -0
  85. package/dist/esm/figures/{QuadraticBezierCurve.js → quadratic-bezier-curve/QuadraticBezierCurve.js} +7 -3
  86. package/dist/esm/figures/quadratic-bezier-curve/QuadraticBezierCurve.types.js +1 -0
  87. package/dist/esm/figures/quadratic-bezier-curve/index.js +2 -0
  88. package/dist/esm/index.js +2 -14
  89. package/dist/esm/utilities/{Calculator.js → calculator/Calculator.js} +9 -1
  90. package/dist/esm/utilities/calculator/index.js +1 -0
  91. package/dist/esm/utilities/index.js +4 -6
  92. package/dist/types/abstracts/{Angle.d.ts → angle/Angle.d.ts} +2 -1
  93. package/dist/types/abstracts/angle/Angle.types.d.ts +16 -0
  94. package/dist/types/abstracts/angle/index.d.ts +2 -0
  95. package/dist/types/abstracts/{Figure.d.ts → figure/Figure.d.ts} +4 -4
  96. package/dist/types/abstracts/figure/Figure.types.d.ts +14 -0
  97. package/dist/types/abstracts/figure/index.d.ts +2 -0
  98. package/dist/types/abstracts/{Flag.d.ts → flag/Flag.d.ts} +2 -1
  99. package/dist/types/abstracts/flag/Flag.types.d.ts +8 -0
  100. package/dist/types/abstracts/flag/index.d.ts +2 -0
  101. package/dist/types/abstracts/index.d.ts +6 -0
  102. package/dist/types/abstracts/{Magnitude.d.ts → magnitude/Magnitude.d.ts} +2 -1
  103. package/dist/types/abstracts/magnitude/Magnitude.types.d.ts +8 -0
  104. package/dist/types/abstracts/magnitude/index.d.ts +2 -0
  105. package/dist/types/abstracts/{Point.d.ts → point/Point.d.ts} +2 -1
  106. package/dist/types/abstracts/point/Point.types.d.ts +13 -0
  107. package/dist/types/abstracts/point/index.d.ts +2 -0
  108. package/dist/types/abstracts/{Vector.d.ts → vector/Vector.d.ts} +3 -1
  109. package/dist/types/abstracts/vector/Vector.types.d.ts +19 -0
  110. package/dist/types/abstracts/vector/index.d.ts +2 -0
  111. package/dist/types/figures/{ArcCurve.d.ts → arc-curve/ArcCurve.d.ts} +7 -2
  112. package/dist/types/figures/arc-curve/ArcCurve.types.d.ts +11 -0
  113. package/dist/types/figures/arc-curve/index.d.ts +2 -0
  114. package/dist/types/figures/{Circle.d.ts → circle/Circle.d.ts} +3 -2
  115. package/dist/types/figures/circle/Circle.types.d.ts +9 -0
  116. package/dist/types/figures/circle/index.d.ts +2 -0
  117. package/dist/types/figures/{CubicBezierCurve.d.ts → cubic-bezier-curve/CubicBezierCurve.d.ts} +4 -2
  118. package/dist/types/figures/cubic-bezier-curve/CubicBezierCurve.types.d.ts +8 -0
  119. package/dist/types/figures/cubic-bezier-curve/index.d.ts +2 -0
  120. package/dist/types/figures/{Ellipse.d.ts → ellipse/Ellipse.d.ts} +5 -2
  121. package/dist/types/figures/ellipse/Ellipse.types.d.ts +16 -0
  122. package/dist/types/figures/ellipse/index.d.ts +2 -0
  123. package/dist/types/figures/index.d.ts +7 -0
  124. package/dist/types/figures/{Line.d.ts → line/Line.d.ts} +6 -4
  125. package/dist/types/figures/line/Line.types.d.ts +30 -0
  126. package/dist/types/figures/line/index.d.ts +2 -0
  127. package/dist/types/figures/polygon/Polygon.d.ts +17 -0
  128. package/dist/types/figures/polygon/Polygon.types.d.ts +8 -0
  129. package/dist/types/figures/polygon/index.d.ts +2 -0
  130. package/dist/types/figures/{QuadraticBezierCurve.d.ts → quadratic-bezier-curve/QuadraticBezierCurve.d.ts} +4 -2
  131. package/dist/types/figures/quadratic-bezier-curve/QuadraticBezierCurve.types.d.ts +8 -0
  132. package/dist/types/figures/quadratic-bezier-curve/index.d.ts +2 -0
  133. package/dist/types/index.d.ts +2 -14
  134. package/dist/types/types/index.d.ts +0 -129
  135. package/dist/types/utilities/{Calculator.d.ts → calculator/Calculator.d.ts} +4 -0
  136. package/dist/types/utilities/calculator/index.d.ts +1 -0
  137. package/dist/types/utilities/index.d.ts +2 -4
  138. package/package.json +24 -18
  139. package/dist/cjs/figures/ArcCurve.js +0 -132
  140. package/dist/cjs/figures/Ellipse.js +0 -111
  141. package/dist/cjs/figures/Polygon.js +0 -17
  142. package/dist/esm/figures/Polygon.js +0 -13
  143. package/dist/types/figures/Polygon.d.ts +0 -7
@@ -1,6 +1,5 @@
1
- import { Calculator } from '../utilities/Calculator';
2
- import { Point } from '../abstracts/Point';
3
- import { Figure } from '../abstracts/Figure';
1
+ import { Figure, Point } from '../../abstracts';
2
+ import { Calculator } from '../../utilities/calculator';
4
3
  export class CubicBezierCurve extends Figure {
5
4
  _criticalPoints;
6
5
  constructor(values) {
@@ -58,6 +57,11 @@ export class CubicBezierCurve extends Figure {
58
57
  this.recompute();
59
58
  return this;
60
59
  }
60
+ scaleXY(factorX, factorY, about) {
61
+ super.scaleXY(factorX, factorY, about);
62
+ this.recompute();
63
+ return this;
64
+ }
61
65
  translate(vector) {
62
66
  super.translate(vector);
63
67
  this.recompute();
@@ -70,7 +74,8 @@ export class CubicBezierCurve extends Figure {
70
74
  }
71
75
  const criticalPoints = tValues.reduce((criticalPoints, t) => {
72
76
  const criticalPoint = this.getPointAtParameter(t);
73
- criticalPoint && criticalPoints.push(criticalPoint);
77
+ if (criticalPoint)
78
+ criticalPoints.push(criticalPoint);
74
79
  return criticalPoints;
75
80
  }, []);
76
81
  return criticalPoints;
@@ -92,7 +97,7 @@ export class CubicBezierCurve extends Figure {
92
97
  for (let n = 0; n < signs.length; n++) {
93
98
  const sign = signs[n];
94
99
  let tValue;
95
- if (+a === 0) {
100
+ if (Calculator.isNearZero(+a)) {
96
101
  // 1st degree equation to avoid n/0
97
102
  tValue = c.neg().div(b);
98
103
  }
@@ -111,7 +116,7 @@ export class CubicBezierCurve extends Figure {
111
116
  if (!tValues.length) {
112
117
  return;
113
118
  }
114
- return tValues.filter((value, index, array) => index === array.findIndex((v) => +value === +v));
119
+ return tValues.filter((value, index, array) => index === array.findIndex((v) => Calculator.isEqual(+value, +v)));
115
120
  }
116
121
  getCoordinateAtParameter(t, axis) {
117
122
  const { P0, P1, P2, P3 } = this;
@@ -0,0 +1,2 @@
1
+ export * from './CubicBezierCurve';
2
+ export * from './CubicBezierCurve.types';
@@ -1,8 +1,15 @@
1
- import { Calculator } from '../utilities/Calculator';
2
- import { Angle } from '../abstracts/Angle';
3
- import { Point } from '../abstracts/Point';
4
- import { Figure } from '../abstracts/Figure';
5
- import { xAxis } from '../utilities';
1
+ import { Angle, Figure, Point, Vector } from '../../abstracts';
2
+ import { CubicBezierCurve } from '../cubic-bezier-curve/CubicBezierCurve';
3
+ import { Calculator } from '../../utilities/calculator';
4
+ import { Line } from '../line/Line';
5
+ const KAPPA = 0.5522847498307936;
6
+ const xAxis = new Line([new Point([0, 0]), new Point([1, 0])]);
7
+ const unitCircleCubicBezierCurves = [
8
+ new CubicBezierCurve([new Point([1, 0]), new Point([1, KAPPA]), new Point([KAPPA, 1]), new Point([0, 1])]),
9
+ new CubicBezierCurve([new Point([0, 1]), new Point([-KAPPA, 1]), new Point([-1, KAPPA]), new Point([-1, 0])]),
10
+ new CubicBezierCurve([new Point([-1, 0]), new Point([-1, -KAPPA]), new Point([-KAPPA, -1]), new Point([0, -1])]),
11
+ new CubicBezierCurve([new Point([0, -1]), new Point([KAPPA, -1]), new Point([1, -KAPPA]), new Point([1, 0])])
12
+ ];
6
13
  export class Ellipse extends Figure {
7
14
  _center;
8
15
  _criticalPoints;
@@ -28,7 +35,7 @@ export class Ellipse extends Figure {
28
35
  return this._criticalPoints;
29
36
  }
30
37
  get isCircle() {
31
- return +this.rx === +this.ry;
38
+ return Calculator.isEqual(+this.rx, +this.ry);
32
39
  }
33
40
  get phi() {
34
41
  return this._phi;
@@ -83,6 +90,17 @@ export class Ellipse extends Figure {
83
90
  this.recompute();
84
91
  return this;
85
92
  }
93
+ toCubicBezierCurves() {
94
+ const { rx, ry, phi, center } = this;
95
+ const curves = unitCircleCubicBezierCurves.map((curve) => {
96
+ return curve
97
+ .clone()
98
+ .scaleXY(+rx, +ry)
99
+ .rotate(phi)
100
+ .translate(new Vector([center.x, center.y]));
101
+ });
102
+ return curves;
103
+ }
86
104
  translate(vector) {
87
105
  this._center.translate(vector);
88
106
  this.recompute();
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from './Ellipse';
2
+ export * from './Ellipse.types';
@@ -0,0 +1,7 @@
1
+ export * from './arc-curve';
2
+ export * from './circle';
3
+ export * from './cubic-bezier-curve';
4
+ export * from './ellipse';
5
+ export * from './line';
6
+ export * from './polygon';
7
+ export * from './quadratic-bezier-curve';
@@ -1,12 +1,10 @@
1
- import { Calculator } from '../utilities/Calculator';
2
- import { Angle } from '../abstracts/Angle';
3
- import { Point } from '../abstracts/Point';
4
- import { Vector } from '../abstracts/Vector';
5
- import { Figure } from '../abstracts/Figure';
1
+ import { Angle, Figure, Point, Vector } from '../../abstracts';
2
+ import { Calculator } from '../../utilities/calculator';
6
3
  export class Line extends Figure {
7
4
  _P0;
8
5
  _P1;
9
6
  _V;
7
+ _dirty = true;
10
8
  _reciprocal;
11
9
  _slope;
12
10
  _xIntercept;
@@ -24,10 +22,6 @@ export class Line extends Figure {
24
22
  this._P1 = anchor;
25
23
  }
26
24
  this._P0 = P0;
27
- this._slope = this.computeSlope();
28
- this._yIntercept = this.computeYIntercept();
29
- this._reciprocal = this.computeReciprocal();
30
- this._xIntercept = this.computeXIntercept();
31
25
  this.points = [this.P0, this.P1];
32
26
  this.vectors = [this.V];
33
27
  }
@@ -80,33 +74,41 @@ export class Line extends Figure {
80
74
  return typeof slope === 'undefined';
81
75
  }
82
76
  get reciprocal() {
77
+ this.ensureComputed();
83
78
  return this._reciprocal;
84
79
  }
85
80
  get slope() {
81
+ this.ensureComputed();
86
82
  return this._slope;
87
83
  }
88
84
  get xIntercept() {
85
+ this.ensureComputed();
89
86
  return this._xIntercept;
90
87
  }
91
88
  get yIntercept() {
89
+ this.ensureComputed();
92
90
  return this._yIntercept;
93
91
  }
94
- angleTo(line) {
95
- if (this.isParallelTo(line)) {
96
- return new Angle(0, 'radians');
97
- }
98
- if (this.isPerpendicularTo(line)) {
99
- return new Angle(+Calculator.div(Math.PI, 2), 'radians');
100
- }
101
- if (typeof this.slope === 'undefined') {
102
- return new Angle(+Calculator.atan(line.slope), 'radians');
103
- }
104
- if (typeof line.slope === 'undefined') {
105
- return new Angle(+Calculator.atan(this.slope), 'radians');
106
- }
107
- const thisSlope = new Calculator(this.slope);
108
- const lineSlope = new Calculator(line.slope);
109
- return new Angle(+lineSlope.sub(thisSlope).div(thisSlope.mul(lineSlope).add(1)).abs().atan(), 'radians');
92
+ angleTo(reference) {
93
+ if ('slope' in reference) {
94
+ const line = reference;
95
+ if (this.isParallelTo(line)) {
96
+ return new Angle(0, 'radians');
97
+ }
98
+ if (this.isPerpendicularTo(line)) {
99
+ return new Angle(+Calculator.div(Math.PI, 2), 'radians');
100
+ }
101
+ if (typeof this.slope === 'undefined') {
102
+ return new Angle(+Calculator.atan(line.slope), 'radians');
103
+ }
104
+ if (typeof line.slope === 'undefined') {
105
+ return new Angle(+Calculator.atan(this.slope), 'radians');
106
+ }
107
+ const thisSlope = new Calculator(this.slope);
108
+ const lineSlope = new Calculator(line.slope);
109
+ return new Angle(+lineSlope.sub(thisSlope).div(thisSlope.mul(lineSlope).add(1)).abs().atan(), 'radians');
110
+ }
111
+ return this.V.angleTo(reference);
110
112
  }
111
113
  clone() {
112
114
  const values = this.values.map((value) => value.clone());
@@ -134,9 +136,11 @@ export class Line extends Figure {
134
136
  perpendicularProjection = new Point([point.x, P0.y]);
135
137
  }
136
138
  else {
137
- const x = new Calculator(1);
138
- const y = x.mul(1).div(slope).neg().add(Calculator.div(point.x, slope)).add(point.y);
139
- perpendicularProjection = new Point([+x, +y]);
139
+ const perpendicularSlope = +Calculator.div(-1, slope);
140
+ const perpendicularYIntercept = +Calculator.sub(point.y, Calculator.mul(perpendicularSlope, point.x));
141
+ const x = +Calculator.sub(perpendicularYIntercept, this.yIntercept).div(Calculator.sub(slope, perpendicularSlope));
142
+ const y = +Calculator.mul(slope, x).add(this.yIntercept);
143
+ perpendicularProjection = new Point([x, y]);
140
144
  }
141
145
  return perpendicularProjection;
142
146
  }
@@ -174,11 +178,17 @@ export class Line extends Figure {
174
178
  return +Calculator.mul(slope, x).add(yIntercept);
175
179
  }
176
180
  hasPoint(P) {
181
+ if (this.isVertical) {
182
+ return Calculator.isEqual(P.x, this.P0.x);
183
+ }
177
184
  const potentialY = this.getYValueAtX(P.x);
178
- return typeof potentialY === 'number' && potentialY === P.y;
185
+ return typeof potentialY === 'number' && Calculator.isEqual(potentialY, P.y);
179
186
  }
180
187
  isParallelTo(line) {
181
- return this.slope == line.slope;
188
+ if (typeof this.slope === 'undefined' || typeof line.slope === 'undefined') {
189
+ return typeof this.slope === typeof line.slope;
190
+ }
191
+ return Calculator.isEqual(this.slope, line.slope);
182
192
  }
183
193
  isPerpendicularTo(line) {
184
194
  if (this.isVertical) {
@@ -187,34 +197,39 @@ export class Line extends Figure {
187
197
  if (this.isHorizontal) {
188
198
  return line.isVertical;
189
199
  }
200
+ /* v8 ignore next 3 */
190
201
  if (line.isVertical) {
191
202
  return this.isHorizontal;
192
203
  }
204
+ /* v8 ignore next 3 */
193
205
  if (line.isHorizontal) {
194
206
  return this.isVertical;
195
207
  }
196
- const thisSlope = new Calculator(this.slope);
197
- const lineSlope = new Calculator(line.slope);
198
- return +thisSlope === +Calculator.div(-1, lineSlope);
208
+ return Calculator.isEqual(this.slope, +Calculator.div(-1, line.slope));
199
209
  }
200
210
  reflect(about) {
201
211
  super.reflect(about);
202
- this.recompute();
212
+ this._dirty = true;
203
213
  return this;
204
214
  }
205
215
  rotate(phi, about) {
206
216
  super.rotate(phi, about);
207
- this.recompute();
217
+ this._dirty = true;
208
218
  return this;
209
219
  }
210
220
  scale(factor, about) {
211
221
  super.scale(factor, about);
212
- this.recompute();
222
+ this._dirty = true;
223
+ return this;
224
+ }
225
+ scaleXY(factorX, factorY, about) {
226
+ super.scaleXY(factorX, factorY, about);
227
+ this._dirty = true;
213
228
  return this;
214
229
  }
215
230
  translate(vector) {
216
231
  super.translate(vector);
217
- this.recompute();
232
+ this._dirty = true;
218
233
  return this;
219
234
  }
220
235
  computeReciprocal() {
@@ -251,7 +266,11 @@ export class Line extends Figure {
251
266
  }
252
267
  return +Calculator.sub(P0.y, Calculator.mul(slope, P0.x));
253
268
  }
254
- recompute() {
269
+ ensureComputed() {
270
+ if (!this._dirty) {
271
+ return;
272
+ }
273
+ this._dirty = false;
255
274
  this._slope = this.computeSlope();
256
275
  this._yIntercept = this.computeYIntercept();
257
276
  this._reciprocal = this.computeReciprocal();
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from './Line';
2
+ export * from './Line.types';
@@ -0,0 +1,47 @@
1
+ import { Figure } from '../../abstracts';
2
+ import { Line } from '../line/Line';
3
+ export class Polygon extends Figure {
4
+ _lines;
5
+ constructor(values) {
6
+ super(values);
7
+ this._lines = this.computeLines();
8
+ }
9
+ get lines() {
10
+ return this._lines;
11
+ }
12
+ get sides() {
13
+ return this.points.length;
14
+ }
15
+ clone() {
16
+ const values = this.values.map((value) => value.clone());
17
+ return new Polygon(values);
18
+ }
19
+ reflect(about) {
20
+ super.reflect(about);
21
+ this._lines = this.computeLines();
22
+ return this;
23
+ }
24
+ rotate(phi, about) {
25
+ super.rotate(phi, about);
26
+ this._lines = this.computeLines();
27
+ return this;
28
+ }
29
+ scale(factor, about) {
30
+ super.scale(factor, about);
31
+ this._lines = this.computeLines();
32
+ return this;
33
+ }
34
+ scaleXY(factorX, factorY, about) {
35
+ super.scaleXY(factorX, factorY, about);
36
+ this._lines = this.computeLines();
37
+ return this;
38
+ }
39
+ translate(vector) {
40
+ super.translate(vector);
41
+ this._lines = this.computeLines();
42
+ return this;
43
+ }
44
+ computeLines() {
45
+ return this.points.map((point, i) => new Line([point, this.points[(i + 1) % this.points.length]]));
46
+ }
47
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from './Polygon';
2
+ export * from './Polygon.types';
@@ -1,6 +1,5 @@
1
- import { Calculator } from '../utilities/Calculator';
2
- import { Point } from '../abstracts/Point';
3
- import { Figure } from '../abstracts/Figure';
1
+ import { Figure, Point } from '../../abstracts';
2
+ import { Calculator } from '../../utilities/calculator';
4
3
  export class QuadraticBezierCurve extends Figure {
5
4
  _criticalPoints;
6
5
  constructor(values) {
@@ -52,6 +51,11 @@ export class QuadraticBezierCurve extends Figure {
52
51
  this.recompute();
53
52
  return this;
54
53
  }
54
+ scaleXY(factorX, factorY, about) {
55
+ super.scaleXY(factorX, factorY, about);
56
+ this.recompute();
57
+ return this;
58
+ }
55
59
  translate(vector) {
56
60
  super.translate(vector);
57
61
  this.recompute();
@@ -0,0 +1,2 @@
1
+ export * from './QuadraticBezierCurve';
2
+ export * from './QuadraticBezierCurve.types';
package/dist/esm/index.js CHANGED
@@ -1,17 +1,5 @@
1
1
  /* v8 ignore */
2
- export { Angle } from './abstracts/Angle';
3
- export { Figure } from './abstracts/Figure';
4
- export { Flag } from './abstracts/Flag';
5
- export { Magnitude } from './abstracts/Magnitude';
6
- export { Point } from './abstracts/Point';
7
- export { Vector } from './abstracts/Vector.js';
8
- export { ArcCurve } from './figures/ArcCurve';
9
- export { Circle } from './figures/Circle';
10
- export { CubicBezierCurve } from './figures/CubicBezierCurve';
11
- export { Ellipse } from './figures/Ellipse';
12
- export { Line } from './figures/Line';
13
- export { Polygon } from './figures/Polygon';
14
- export { QuadraticBezierCurve } from './figures/QuadraticBezierCurve';
15
- export { Calculator } from './utilities/Calculator';
2
+ export * from './abstracts';
3
+ export * from './figures';
16
4
  export * from './utilities';
17
5
  export * from './types';
@@ -1,5 +1,7 @@
1
1
  import { Decimal } from 'decimal.js';
2
2
  export class Calculator {
3
+ static EPSILON = 1e-8;
4
+ static PI2 = +Calculator.mul(Math.PI, 2);
3
5
  _instance;
4
6
  constructor(arg) {
5
7
  this._instance = new Decimal(arg);
@@ -26,6 +28,12 @@ export class Calculator {
26
28
  static div(first, second) {
27
29
  return Calculator.computeBinaryOperation('div', [first, second]);
28
30
  }
31
+ static isEqual(a, b) {
32
+ return Math.abs(a - b) <= Calculator.EPSILON;
33
+ }
34
+ static isNearZero(a) {
35
+ return Math.abs(a) <= Calculator.EPSILON;
36
+ }
29
37
  static max(args) {
30
38
  return Calculator.computeIndefiniteOperation('max', args);
31
39
  }
@@ -80,7 +88,7 @@ export class Calculator {
80
88
  * than epsilon, and then to round up to that point instead of choosing an arbitrary precision.
81
89
  */
82
90
  static roundDecimalWithPrecision(value) {
83
- const epsilon = new Decimal('1e-8');
91
+ const epsilon = new Decimal(Calculator.EPSILON);
84
92
  const distanceToLowerInt = value.sub(value.floor());
85
93
  const distanceToUpperInt = value.ceil().sub(value);
86
94
  if (distanceToLowerInt.lte(epsilon)) {
@@ -0,0 +1 @@
1
+ export * from './Calculator';
@@ -1,7 +1,5 @@
1
- import { Calculator } from './Calculator';
2
- import { Point } from '../abstracts/Point';
3
- import { Line } from '../figures/Line';
1
+ import { Calculator } from './calculator';
2
+ import { Point } from '../abstracts';
3
+ export * from './calculator';
4
4
  export const coordinateOrigin = new Point([0, 0]);
5
- export const xAxis = new Line([coordinateOrigin, new Point([1, 0])]);
6
- export const yAxis = new Line([coordinateOrigin, new Point([0, 1])]);
7
- export const PI2 = +Calculator.mul(Math.PI, 2); // 360 degrees
5
+ export const PI2 = Calculator.PI2;
@@ -1,5 +1,6 @@
1
- import { IAngle, TAngleUnit } from '../types';
1
+ import { IAngle, TAngleUnit } from './Angle.types';
2
2
  export declare class Angle implements IAngle {
3
+ readonly kind: "angle";
3
4
  private _radians;
4
5
  constructor(value: number, unit: TAngleUnit);
5
6
  get cos(): number;
@@ -0,0 +1,16 @@
1
+ import { IClonable } from '../../types';
2
+ export type TAngleUnit = 'radians' | 'degrees';
3
+ export interface IAngle extends IClonable<IAngle> {
4
+ readonly cos: number;
5
+ readonly cot: number;
6
+ readonly degrees: number;
7
+ readonly kind: 'angle';
8
+ readonly radians: number;
9
+ readonly sin: number;
10
+ readonly tan: number;
11
+ normalize(): this;
12
+ replace(value: number, unit: TAngleUnit): this;
13
+ scale(factor: number): this;
14
+ valueOf(): number;
15
+ }
16
+ export type TAngleRange = [IAngle, IAngle];
@@ -0,0 +1,2 @@
1
+ export * from './Angle';
2
+ export * from './Angle.types';
@@ -1,4 +1,6 @@
1
- import { IAngle, IBoundingBox, IFigure, ILine, IMagnitude, IPoint, IVector, TFigureValues } from '../types';
1
+ import { IAngle, IFigure, IMagnitude, IPoint, IVector, TFigureValues } from '..';
2
+ import type { ILine } from '../../figures';
3
+ import { IBoundingBox } from '../../types';
2
4
  export declare abstract class Figure implements IFigure {
3
5
  protected angles: IAngle[];
4
6
  protected isRelative: boolean;
@@ -9,14 +11,12 @@ export declare abstract class Figure implements IFigure {
9
11
  constructor(values: TFigureValues);
10
12
  get boundingBox(): IBoundingBox;
11
13
  get values(): TFigureValues;
12
- /**
13
- * @todo Figure out a better way to type narrow than iterating again.
14
- */
15
14
  protected set values(values: TFigureValues);
16
15
  protected static computeBoundingBox(points: IPoint[]): IBoundingBox;
17
16
  private static getNoPointsErrorMessage;
18
17
  reflect(about: IPoint | ILine): this;
19
18
  rotate(phi: IAngle, about?: IPoint): this;
20
19
  scale(factor: number, about?: IPoint): this;
20
+ scaleXY(factorX: number, factorY: number, about?: IPoint): this;
21
21
  translate(vector: IVector): this;
22
22
  }
@@ -0,0 +1,14 @@
1
+ import { IAngle, IFlag, IMagnitude, IPoint, IVector } from '..';
2
+ import { ILine } from '../../figures';
3
+ import { IBoundingBox } from '../../types';
4
+ export type TFigureValue = IFlag | IMagnitude | IAngle | IPoint | IVector;
5
+ export type TFigureValues = [IPoint, ...TFigureValue[]];
6
+ export interface IFigure {
7
+ readonly boundingBox: IBoundingBox;
8
+ readonly values: TFigureValues;
9
+ reflect(about: IPoint | ILine): this;
10
+ rotate(phi: IAngle, about?: IPoint): this;
11
+ scale(factor: number, about?: IPoint): this;
12
+ scaleXY(factorX: number, factorY: number, about?: IPoint): this;
13
+ translate(vector: IVector): this;
14
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Figure';
2
+ export * from './Figure.types';
@@ -1,5 +1,6 @@
1
- import { IFlag } from '../types';
1
+ import { IFlag } from './Flag.types';
2
2
  export declare class Flag implements IFlag {
3
+ readonly kind: "flag";
3
4
  private _value;
4
5
  constructor(value: boolean);
5
6
  get value(): boolean;
@@ -0,0 +1,8 @@
1
+ import { IClonable } from '../../types';
2
+ export interface IFlag extends IClonable<IFlag> {
3
+ readonly kind: 'flag';
4
+ readonly value: boolean;
5
+ invert(): this;
6
+ replace(value: boolean): this;
7
+ valueOf(): number;
8
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Flag';
2
+ export * from './Flag.types';
@@ -0,0 +1,6 @@
1
+ export * from './angle';
2
+ export * from './figure';
3
+ export * from './flag';
4
+ export * from './magnitude';
5
+ export * from './point';
6
+ export * from './vector';
@@ -1,5 +1,6 @@
1
- import { IMagnitude } from '../types';
1
+ import { IMagnitude } from './Magnitude.types';
2
2
  export declare class Magnitude implements IMagnitude {
3
+ readonly kind: "magnitude";
3
4
  private _value;
4
5
  constructor(value: number);
5
6
  get value(): number;
@@ -0,0 +1,8 @@
1
+ import { IClonable } from '../../types';
2
+ export interface IMagnitude extends IClonable<IMagnitude> {
3
+ readonly kind: 'magnitude';
4
+ readonly value: number;
5
+ replace(value: number): this;
6
+ scale(factor: number): this;
7
+ valueOf(): number;
8
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Magnitude';
2
+ export * from './Magnitude.types';
@@ -1,5 +1,6 @@
1
- import { IAngle, IPoint, IVector, TPointValues } from '../types';
1
+ import { IAngle, IPoint, IVector, TPointValues } from '..';
2
2
  export declare class Point implements IPoint {
3
+ readonly kind: "point";
3
4
  private _x;
4
5
  private _y;
5
6
  constructor([x, y]: TPointValues);
@@ -0,0 +1,13 @@
1
+ import { IAngle, IVector } from '..';
2
+ import { IClonable } from '../../types';
3
+ export type TPointValues = [number, number];
4
+ export interface IPoint extends IClonable<IPoint> {
5
+ readonly kind: 'point';
6
+ readonly values: TPointValues;
7
+ readonly x: number;
8
+ readonly y: number;
9
+ reflect(about: IPoint): this;
10
+ replace(point: IPoint): this;
11
+ rotate(phi: IAngle, about?: IPoint): this;
12
+ translate(vector: IVector): this;
13
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Point';
2
+ export * from './Point.types';
@@ -1,5 +1,7 @@
1
- import { IVector, TVectorValues, TSegment, IAngle } from '../types';
1
+ import { IVector, TVectorValues, IAngle } from '..';
2
+ import type { TSegment } from '../../figures';
2
3
  export declare class Vector implements IVector {
4
+ readonly kind: "vector";
3
5
  private _dx;
4
6
  private _dy;
5
7
  constructor(values: TVectorValues | TSegment);
@@ -0,0 +1,19 @@
1
+ import { IAngle } from '..';
2
+ import { IClonable } from '../../types';
3
+ export type TVectorValues = [number, number];
4
+ export interface IVector extends IClonable<IVector> {
5
+ readonly dx: number;
6
+ readonly dy: number;
7
+ readonly kind: 'vector';
8
+ readonly magnitude: number;
9
+ readonly values: TVectorValues;
10
+ angleTo(vector: IVector): IAngle;
11
+ dotProduct(vector: IVector): number;
12
+ reflect(about: {
13
+ x: boolean;
14
+ y: boolean;
15
+ }): this;
16
+ replace(vector: IVector): this;
17
+ rotate(phi: IAngle): this;
18
+ scale(factor: number): this;
19
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Vector';
2
+ export * from './Vector.types';