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.
- package/README.md +39 -430
- package/dist/cjs/abstracts/{Angle.js → angle/Angle.js} +11 -11
- package/dist/cjs/abstracts/angle/Angle.types.js +2 -0
- package/dist/cjs/abstracts/angle/index.js +18 -0
- package/dist/cjs/abstracts/{Figure.js → figure/Figure.js} +45 -30
- package/dist/cjs/abstracts/figure/Figure.types.js +2 -0
- package/dist/cjs/abstracts/figure/index.js +18 -0
- package/dist/cjs/abstracts/{Flag.js → flag/Flag.js} +1 -0
- package/dist/cjs/abstracts/flag/Flag.types.js +2 -0
- package/dist/cjs/abstracts/flag/index.js +18 -0
- package/dist/cjs/abstracts/index.js +22 -0
- package/dist/cjs/abstracts/{Magnitude.js → magnitude/Magnitude.js} +3 -2
- package/dist/cjs/abstracts/magnitude/Magnitude.types.js +2 -0
- package/dist/cjs/abstracts/magnitude/index.js +18 -0
- package/dist/cjs/abstracts/{Point.js → point/Point.js} +8 -7
- package/dist/cjs/abstracts/point/Point.types.js +2 -0
- package/dist/cjs/abstracts/point/index.js +18 -0
- package/dist/cjs/abstracts/{Vector.js → vector/Vector.js} +16 -15
- package/dist/cjs/abstracts/vector/Vector.types.js +2 -0
- package/dist/cjs/abstracts/vector/index.js +18 -0
- package/dist/cjs/figures/arc-curve/ArcCurve.js +174 -0
- package/dist/cjs/figures/arc-curve/ArcCurve.types.js +2 -0
- package/dist/cjs/figures/arc-curve/index.js +18 -0
- package/dist/cjs/figures/{Circle.js → circle/Circle.js} +8 -9
- package/dist/cjs/figures/circle/Circle.types.js +2 -0
- package/dist/cjs/figures/circle/index.js +18 -0
- package/dist/cjs/figures/{CubicBezierCurve.js → cubic-bezier-curve/CubicBezierCurve.js} +22 -17
- package/dist/cjs/figures/cubic-bezier-curve/CubicBezierCurve.types.js +2 -0
- package/dist/cjs/figures/cubic-bezier-curve/index.js +18 -0
- package/dist/cjs/figures/ellipse/Ellipse.js +129 -0
- package/dist/cjs/figures/ellipse/Ellipse.types.js +2 -0
- package/dist/cjs/figures/ellipse/index.js +18 -0
- package/dist/cjs/figures/index.js +23 -0
- package/dist/cjs/figures/{Line.js → line/Line.js} +78 -59
- package/dist/cjs/figures/line/Line.types.js +2 -0
- package/dist/cjs/figures/line/index.js +18 -0
- package/dist/cjs/figures/polygon/Polygon.js +51 -0
- package/dist/cjs/figures/polygon/Polygon.types.js +2 -0
- package/dist/cjs/figures/polygon/index.js +18 -0
- package/dist/cjs/figures/{QuadraticBezierCurve.js → quadratic-bezier-curve/QuadraticBezierCurve.js} +12 -8
- package/dist/cjs/figures/quadratic-bezier-curve/QuadraticBezierCurve.types.js +2 -0
- package/dist/cjs/figures/quadratic-bezier-curve/index.js +18 -0
- package/dist/cjs/index.js +2 -29
- package/dist/cjs/utilities/{Calculator.js → calculator/Calculator.js} +9 -1
- package/dist/cjs/utilities/calculator/index.js +17 -0
- package/dist/cjs/utilities/index.js +20 -8
- package/dist/esm/abstracts/{Angle.js → angle/Angle.js} +4 -4
- package/dist/esm/abstracts/angle/Angle.types.js +1 -0
- package/dist/esm/abstracts/angle/index.js +2 -0
- package/dist/esm/abstracts/{Figure.js → figure/Figure.js} +37 -22
- package/dist/esm/abstracts/figure/Figure.types.js +1 -0
- package/dist/esm/abstracts/figure/index.js +2 -0
- package/dist/esm/abstracts/{Flag.js → flag/Flag.js} +1 -0
- package/dist/esm/abstracts/flag/Flag.types.js +1 -0
- package/dist/esm/abstracts/flag/index.js +2 -0
- package/dist/esm/abstracts/index.js +6 -0
- package/dist/esm/abstracts/{Magnitude.js → magnitude/Magnitude.js} +2 -1
- package/dist/esm/abstracts/magnitude/Magnitude.types.js +1 -0
- package/dist/esm/abstracts/magnitude/index.js +2 -0
- package/dist/esm/abstracts/{Point.js → point/Point.js} +2 -1
- package/dist/esm/abstracts/point/Point.types.js +1 -0
- package/dist/esm/abstracts/point/index.js +2 -0
- package/dist/esm/abstracts/{Vector.js → vector/Vector.js} +3 -2
- package/dist/esm/abstracts/vector/Vector.types.js +1 -0
- package/dist/esm/abstracts/vector/index.js +2 -0
- package/dist/esm/figures/{ArcCurve.js → arc-curve/ArcCurve.js} +50 -8
- package/dist/esm/figures/arc-curve/ArcCurve.types.js +1 -0
- package/dist/esm/figures/arc-curve/index.js +2 -0
- package/dist/esm/figures/{Circle.js → circle/Circle.js} +3 -4
- package/dist/esm/figures/circle/Circle.types.js +1 -0
- package/dist/esm/figures/circle/index.js +2 -0
- package/dist/esm/figures/{CubicBezierCurve.js → cubic-bezier-curve/CubicBezierCurve.js} +11 -6
- package/dist/esm/figures/cubic-bezier-curve/CubicBezierCurve.types.js +1 -0
- package/dist/esm/figures/cubic-bezier-curve/index.js +2 -0
- package/dist/esm/figures/{Ellipse.js → ellipse/Ellipse.js} +24 -6
- package/dist/esm/figures/ellipse/Ellipse.types.js +1 -0
- package/dist/esm/figures/ellipse/index.js +2 -0
- package/dist/esm/figures/index.js +7 -0
- package/dist/esm/figures/{Line.js → line/Line.js} +57 -38
- package/dist/esm/figures/line/Line.types.js +1 -0
- package/dist/esm/figures/line/index.js +2 -0
- package/dist/esm/figures/polygon/Polygon.js +47 -0
- package/dist/esm/figures/polygon/Polygon.types.js +1 -0
- package/dist/esm/figures/polygon/index.js +2 -0
- package/dist/esm/figures/{QuadraticBezierCurve.js → quadratic-bezier-curve/QuadraticBezierCurve.js} +7 -3
- package/dist/esm/figures/quadratic-bezier-curve/QuadraticBezierCurve.types.js +1 -0
- package/dist/esm/figures/quadratic-bezier-curve/index.js +2 -0
- package/dist/esm/index.js +2 -14
- package/dist/esm/utilities/{Calculator.js → calculator/Calculator.js} +9 -1
- package/dist/esm/utilities/calculator/index.js +1 -0
- package/dist/esm/utilities/index.js +4 -6
- package/dist/types/abstracts/{Angle.d.ts → angle/Angle.d.ts} +2 -1
- package/dist/types/abstracts/angle/Angle.types.d.ts +16 -0
- package/dist/types/abstracts/angle/index.d.ts +2 -0
- package/dist/types/abstracts/{Figure.d.ts → figure/Figure.d.ts} +4 -4
- package/dist/types/abstracts/figure/Figure.types.d.ts +14 -0
- package/dist/types/abstracts/figure/index.d.ts +2 -0
- package/dist/types/abstracts/{Flag.d.ts → flag/Flag.d.ts} +2 -1
- package/dist/types/abstracts/flag/Flag.types.d.ts +8 -0
- package/dist/types/abstracts/flag/index.d.ts +2 -0
- package/dist/types/abstracts/index.d.ts +6 -0
- package/dist/types/abstracts/{Magnitude.d.ts → magnitude/Magnitude.d.ts} +2 -1
- package/dist/types/abstracts/magnitude/Magnitude.types.d.ts +8 -0
- package/dist/types/abstracts/magnitude/index.d.ts +2 -0
- package/dist/types/abstracts/{Point.d.ts → point/Point.d.ts} +2 -1
- package/dist/types/abstracts/point/Point.types.d.ts +13 -0
- package/dist/types/abstracts/point/index.d.ts +2 -0
- package/dist/types/abstracts/{Vector.d.ts → vector/Vector.d.ts} +3 -1
- package/dist/types/abstracts/vector/Vector.types.d.ts +19 -0
- package/dist/types/abstracts/vector/index.d.ts +2 -0
- package/dist/types/figures/{ArcCurve.d.ts → arc-curve/ArcCurve.d.ts} +7 -2
- package/dist/types/figures/arc-curve/ArcCurve.types.d.ts +11 -0
- package/dist/types/figures/arc-curve/index.d.ts +2 -0
- package/dist/types/figures/{Circle.d.ts → circle/Circle.d.ts} +3 -2
- package/dist/types/figures/circle/Circle.types.d.ts +9 -0
- package/dist/types/figures/circle/index.d.ts +2 -0
- package/dist/types/figures/{CubicBezierCurve.d.ts → cubic-bezier-curve/CubicBezierCurve.d.ts} +4 -2
- package/dist/types/figures/cubic-bezier-curve/CubicBezierCurve.types.d.ts +8 -0
- package/dist/types/figures/cubic-bezier-curve/index.d.ts +2 -0
- package/dist/types/figures/{Ellipse.d.ts → ellipse/Ellipse.d.ts} +5 -2
- package/dist/types/figures/ellipse/Ellipse.types.d.ts +16 -0
- package/dist/types/figures/ellipse/index.d.ts +2 -0
- package/dist/types/figures/index.d.ts +7 -0
- package/dist/types/figures/{Line.d.ts → line/Line.d.ts} +6 -4
- package/dist/types/figures/line/Line.types.d.ts +30 -0
- package/dist/types/figures/line/index.d.ts +2 -0
- package/dist/types/figures/polygon/Polygon.d.ts +17 -0
- package/dist/types/figures/polygon/Polygon.types.d.ts +8 -0
- package/dist/types/figures/polygon/index.d.ts +2 -0
- package/dist/types/figures/{QuadraticBezierCurve.d.ts → quadratic-bezier-curve/QuadraticBezierCurve.d.ts} +4 -2
- package/dist/types/figures/quadratic-bezier-curve/QuadraticBezierCurve.types.d.ts +8 -0
- package/dist/types/figures/quadratic-bezier-curve/index.d.ts +2 -0
- package/dist/types/index.d.ts +2 -14
- package/dist/types/types/index.d.ts +0 -129
- package/dist/types/utilities/{Calculator.d.ts → calculator/Calculator.d.ts} +4 -0
- package/dist/types/utilities/calculator/index.d.ts +1 -0
- package/dist/types/utilities/index.d.ts +2 -4
- package/package.json +24 -18
- package/dist/cjs/figures/ArcCurve.js +0 -132
- package/dist/cjs/figures/Ellipse.js +0 -111
- package/dist/cjs/figures/Polygon.js +0 -17
- package/dist/esm/figures/Polygon.js +0 -13
- package/dist/types/figures/Polygon.d.ts +0 -7
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
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
|
-
|
|
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
|
|
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
|
|
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 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
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
|
|
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 {};
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
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(
|
|
95
|
-
if (
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
|
138
|
-
const
|
|
139
|
-
|
|
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
|
|
185
|
+
return typeof potentialY === 'number' && Calculator.isEqual(potentialY, P.y);
|
|
179
186
|
}
|
|
180
187
|
isParallelTo(line) {
|
|
181
|
-
|
|
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
|
-
|
|
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.
|
|
212
|
+
this._dirty = true;
|
|
203
213
|
return this;
|
|
204
214
|
}
|
|
205
215
|
rotate(phi, about) {
|
|
206
216
|
super.rotate(phi, about);
|
|
207
|
-
this.
|
|
217
|
+
this._dirty = true;
|
|
208
218
|
return this;
|
|
209
219
|
}
|
|
210
220
|
scale(factor, about) {
|
|
211
221
|
super.scale(factor, about);
|
|
212
|
-
this.
|
|
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.
|
|
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
|
-
|
|
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,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 {};
|
package/dist/esm/figures/{QuadraticBezierCurve.js → quadratic-bezier-curve/QuadraticBezierCurve.js}
RENAMED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
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 @@
|
|
|
1
|
+
export {};
|
package/dist/esm/index.js
CHANGED
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
/* v8 ignore */
|
|
2
|
-
export
|
|
3
|
-
export
|
|
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(
|
|
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 './
|
|
2
|
-
import { Point } from '../abstracts
|
|
3
|
-
|
|
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
|
|
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;
|
|
@@ -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];
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { IAngle,
|
|
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,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
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { IVector, TVectorValues,
|
|
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
|
+
}
|