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
package/README.md
CHANGED
|
@@ -11,468 +11,77 @@ This library assumes you already have basic knowledge of geometric concepts, inc
|
|
|
11
11
|
- **Transformations**: rotation, translation, reflection, scaling
|
|
12
12
|
- **Units**: radian, degree
|
|
13
13
|
|
|
14
|
-
##
|
|
15
|
-
|
|
16
|
-
You may install this library into your JavaScript or TypeScript project using the following command:
|
|
14
|
+
## Installation
|
|
17
15
|
|
|
18
16
|
```sh
|
|
19
17
|
npm install geometric-library
|
|
20
18
|
```
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
```javascript
|
|
25
|
-
import { Point } from 'geometric-library';
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Alternatively if you're using CommonJS in your project instead of ESM, you may `require` the modules:
|
|
20
|
+
## Importing (ESM)
|
|
29
21
|
|
|
30
22
|
```javascript
|
|
31
|
-
|
|
23
|
+
import { Point, Line, Vector, Angle } from 'geometric-library';
|
|
32
24
|
```
|
|
33
25
|
|
|
34
|
-
|
|
26
|
+
## Importing (CommonJS)
|
|
35
27
|
|
|
36
28
|
```javascript
|
|
37
|
-
|
|
29
|
+
const { Point, Line, Vector, Angle } = require('geometric-library');
|
|
38
30
|
```
|
|
39
31
|
|
|
40
|
-
##
|
|
41
|
-
|
|
42
|
-
#### Decimal.js
|
|
43
|
-
|
|
44
|
-
JavaScript is bad at math. Don't hate me for saying it, it's actually a pretty well known fact that JavaScript just struggles with even simple calculations and especially when they involve floating point numbers. Here's one of the many articles about it if you want to learn more: [Why JavaScript is Bad At Math](https://javascript.plainenglish.io/why-javascript-is-bad-at-math-9b8247640caa), by Alexandra Langton.
|
|
45
|
-
|
|
46
|
-
Though there are ways to more or less combat these issues natively, for the purposes of this library I chose to use an abstraction of [Decimal.js](https://mikemcl.github.io/decimal.js/), which does just that pretty efficiently.
|
|
47
|
-
|
|
48
|
-
Note: You do NOT have to install Decimal.js, as it's included with this library.
|
|
49
|
-
|
|
50
|
-
## Contributing
|
|
32
|
+
## TypeScript Types
|
|
51
33
|
|
|
52
|
-
|
|
34
|
+
If you're using TypeScript, you can import types and interfaces for all exported functionalities:
|
|
53
35
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
If you believe there's a missing feature feel free to open an issue as well detailing the feature request and its value to the users of this library.
|
|
57
|
-
|
|
58
|
-
If you want to directly contribute to the library, feel free to do so by opening a pull request with your changes, as long as there's a related issue tracking the bug/feature request.
|
|
59
|
-
|
|
60
|
-
On the note of directly contributing, though the project includes some automated scripts for linting, cleaning, building, testing and deploying the code, please do try to adhere to the existing standards in terms of naming, directory structure and principles (solid, kiss, single source of truth, etc).
|
|
61
|
-
|
|
62
|
-
## References
|
|
63
|
-
|
|
64
|
-
- [Intro to Bezier curves](https://iquilezles.org/articles/bezierbbox) by [Inigo Quilez](https://iquilezles.org/).
|
|
65
|
-
- [Arc Implementation Notes](https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes) from the [SVG 2 Specification](https://www.w3.org/TR/SVG).
|
|
66
|
-
|
|
67
|
-
## License
|
|
68
|
-
|
|
69
|
-
This project is published and distributed under the [MIT License](./LICENSE).
|
|
70
|
-
|
|
71
|
-
## API
|
|
72
|
-
|
|
73
|
-
The types and interfaces exported from [./src/types/index.ts](./src/types/index.ts) should give you a pretty good idea of how to use any of the functionalities included in this library.
|
|
74
|
-
|
|
75
|
-
The following classes are available:
|
|
76
|
-
|
|
77
|
-
### Abstracts
|
|
78
|
-
|
|
79
|
-
#### Flag
|
|
80
|
-
|
|
81
|
-
`Flag` is just an abstraction of the `boolean` primitive in object form so that its value may be passed by reference. It can be used to determine if a line intersects another, if a point belongs to a line, the side of an ellipse arc, etc.
|
|
82
|
-
|
|
83
|
-
```javascript
|
|
84
|
-
// constructor
|
|
85
|
-
new Flag(value: boolean)
|
|
86
|
-
|
|
87
|
-
// example
|
|
88
|
-
const flag = new Flag(false);
|
|
36
|
+
```typescript
|
|
37
|
+
import { IPoint, TPointValues, ILine, TLineValues } from 'geometric-library';
|
|
89
38
|
```
|
|
90
39
|
|
|
91
|
-
|
|
92
|
-
// api
|
|
93
|
-
{
|
|
94
|
-
value: boolean; // Returns the value of the flag.
|
|
95
|
-
clone(): this; // Clones the Flag object.
|
|
96
|
-
invert(): this; // Inverts (negates) the value of the flag.
|
|
97
|
-
replace(value: boolean): this; // Replaces the value of the flag.
|
|
98
|
-
valueOf(): number; // Returns 1 for true and 0 for false when the Flag object is used arithmetically.
|
|
99
|
-
}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
#### Angle
|
|
103
|
-
|
|
104
|
-
`Angle` implements the geometric concept of angle along with multiple trigonometric operations and pertinent transformations. It can be initialized with a value in either `degrees` or `radians` without presenting any differences, as it keeps a single internal source of truth.
|
|
40
|
+
This is recommended as it will help you understand how everything works and provides full type safety.
|
|
105
41
|
|
|
106
|
-
|
|
107
|
-
// constructor
|
|
108
|
-
new Angle(value: number, unit: 'radians' | 'degrees')
|
|
109
|
-
|
|
110
|
-
// example
|
|
111
|
-
const angleDeg = new Angle(180, 'degrees');
|
|
112
|
-
const angleRad = new Angle(Math.PI, 'radians'); // also 180 degrees
|
|
113
|
-
```
|
|
42
|
+
## Quick Example
|
|
114
43
|
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
{
|
|
118
|
-
cos: number; // Returns the cosine value of the angle.
|
|
119
|
-
cot: number; // Returns the cotangent value of the angle.
|
|
120
|
-
degrees: number; // Returns the angle value in degrees.
|
|
121
|
-
radians: number; // Returns the angle value in radians.
|
|
122
|
-
sin: number; // Returns the sine value of the angle.
|
|
123
|
-
tan: number; // Returns the tangent value of the angle.
|
|
124
|
-
clone(): this; // Clones the Angle object.
|
|
125
|
-
normalize(): this; // Normalizes the value of the angle within the range [0, 360] degrees. Any angle outside the range is replaced with the equivalent angle within the range.
|
|
126
|
-
replace(value: number, unit: 'radians' | 'degrees'): this; // Replaces the value of the angle in the given unit.
|
|
127
|
-
scale(factor: number): this; // Scales the angle by multiplying it by the given factor.
|
|
128
|
-
valueOf(): number; // Returns the value of the Angle in radians when the Angle object is used arithmetically.
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
#### Magnitude
|
|
133
|
-
|
|
134
|
-
`Magnitude` implements the geometric concept of magnitude, which is esentially a value of dimension or size. In its implementation it is esentially an abstraction of the `number` primitive in object form so that its value may be passed by reference.
|
|
135
|
-
|
|
136
|
-
```javascript
|
|
137
|
-
// constructor
|
|
138
|
-
new Magnitude(value: number)
|
|
139
|
-
|
|
140
|
-
// example
|
|
141
|
-
const magnitude = new Magnitude(2);
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
```javascript
|
|
145
|
-
// api
|
|
146
|
-
{
|
|
147
|
-
value: number; // Returns the value of the magnitude.
|
|
148
|
-
clone(): this; // Clones the Magnitude object.
|
|
149
|
-
replace(value: boolean): this; // Replaces the value of the flag.
|
|
150
|
-
scale(factor: number): this; // Scales the magnitude by multiplying it by the given factor.
|
|
151
|
-
valueOf(): number; // Returns the value of the magnitude when the Magnitude object is used arithmetically.
|
|
152
|
-
}
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
#### Vector
|
|
156
|
-
|
|
157
|
-
`Vector` implements the geometric concept of vector, which is esentially a combination of magnitude and direction (ie. 2 units this way) and is generally useful in combination with a positional (a point or a figure) in order to perform different transformations. It is determined by two values corresponding to the x and y axii.
|
|
158
|
-
|
|
159
|
-
```javascript
|
|
160
|
-
// constructor
|
|
161
|
-
new Vector([ dx: number, dy: number ])
|
|
162
|
-
|
|
163
|
-
// example
|
|
164
|
-
const vector = new Vector([1, 2]);
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
```javascript
|
|
168
|
-
// api
|
|
169
|
-
{
|
|
170
|
-
dx: number; // Returns the value of its x dimension.
|
|
171
|
-
dy: number; // Returns the value of its y dimension.
|
|
172
|
-
values: [dx: number, dy: number]; // Returns its dimensional values.
|
|
173
|
-
angleTo(vector: Vector): Angle; // Returns the angle between itself and a given vector.
|
|
174
|
-
clone(): this; // Clones the Vector object.
|
|
175
|
-
dotProduct(vector: Vector): number; // Returns the dot product between itself and a given vector.
|
|
176
|
-
reflect(about: Point): this; // Reflects the vector about a given point.
|
|
177
|
-
replace(vector: Vector): this; // Replaces the vector's values with a given vector's values, while keeping its reference.
|
|
178
|
-
rotate(angle: Angle): this; // Rotates the vector a given angle.
|
|
179
|
-
scale(factor: number): this; // Scales the vector by multiplying its dimensions by a given factor.
|
|
180
|
-
}
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
#### Point
|
|
184
|
-
|
|
185
|
-
`Point` implements the geometric concept of point, which is esentially a given position within space (as determined by a 2..n dimensions coordinate system). This library is currently limited to 2 dimensions and therefore a point is determined by an `x` value and a `y` value. A point it is the most essential part of geometric representation. A point does not have a dimension, however concepts determined by two or more points can have 2..n dimensions (ie. line: 1D, square: 2D, cube: 3D, etc.).
|
|
186
|
-
|
|
187
|
-
```javascript
|
|
188
|
-
// constructor
|
|
189
|
-
new Point([ x: number, y: number ])
|
|
190
|
-
|
|
191
|
-
// example
|
|
192
|
-
const vector = new Point([1, 2]);
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
```javascript
|
|
196
|
-
// api
|
|
197
|
-
{
|
|
198
|
-
values: [ x: number, y: number ]; // Returns the coordinate positional values of the point.
|
|
199
|
-
x: number; // Returns the x coordinate value of the point.
|
|
200
|
-
y: number; // Returns the y coordinate value of the point
|
|
201
|
-
clone(): this; // Clones the Point object.
|
|
202
|
-
reflect(about: Point): this; // Reflects the point about a given point.
|
|
203
|
-
replace(point: Point): this; // Replaces the point's values with a given point's values, while keeping its reference.
|
|
204
|
-
rotate(angle: Angle, about?: Point): this; // Rotates the point a given angle about a given point. If no point is provided about which to rotate, the coordinate origin point [0, 0] is used instead.
|
|
205
|
-
translate(vector: Vector): this; // Translates the point following a given vector.
|
|
206
|
-
}
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
#### Figure
|
|
210
|
-
|
|
211
|
-
`Figure` implements the geometric concept of figure, which is defined as a combination of points, lines or planes. It is the basis for lines, curves, ellipses and polygons. As such, it is an abstract class meant for extension by more concrete figures.
|
|
212
|
-
|
|
213
|
-
```javascript
|
|
214
|
-
type TFigureValues = [Point, ...(Angle | Flag | Magnitude | Point | Vector)[]];
|
|
215
|
-
interface IBoundingBox { xMin: number, xMax: number, yMin: number, yMax: number }
|
|
216
|
-
|
|
217
|
-
// constructor
|
|
218
|
-
constructor (values: TFigureValues) {...}
|
|
219
|
-
|
|
220
|
-
// example
|
|
221
|
-
class Line extends Figure {
|
|
222
|
-
constructor(values: [Point, Point]) {
|
|
223
|
-
super(values);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
...
|
|
228
|
-
|
|
229
|
-
const pointA = new Point([1, 1]);
|
|
230
|
-
const pointB = new Point([2, 2]);
|
|
231
|
-
const line = new Line([pointA, pointB]);
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
```javascript
|
|
235
|
-
// api
|
|
236
|
-
{
|
|
237
|
-
values: TFigureValues; // Returns the values that define the figure.
|
|
238
|
-
boundingBox: IBoundingBox; // Returns the bounding box of the figure.
|
|
239
|
-
reflect(about: Point | Line): this; // Reflects the figure about either a given point or a given line (perpendicularly).
|
|
240
|
-
rotate(angle: Angle, about?: Point): this; // Rotates the figure a given angle about a given point. If no point is provided about which to rotate, the coordinate origin point [0, 0] is used instead.
|
|
241
|
-
scale(factor: number, about?: IPoint): this; // Scales the figure by multiplying its dimensions by a given factor.
|
|
242
|
-
translate(vector: IVector): this; // Translates the figure following a given vector.
|
|
243
|
-
}
|
|
244
|
-
```
|
|
44
|
+
```typescript
|
|
45
|
+
import { Point, Vector, Line, Angle } from 'geometric-library';
|
|
245
46
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
#### Line
|
|
249
|
-
|
|
250
|
-
`Line` implements the geometric concept of line, which is defined as an infinite one dimensional figure. Mathematically it's defined by a point for its position and a vector for its direction. In its implementation it's defined by two points (segment) or a point and a vector.
|
|
251
|
-
|
|
252
|
-
```javascript
|
|
253
|
-
type TLineValues = [Point, Point] | [Point, Vector];
|
|
254
|
-
|
|
255
|
-
// constructor
|
|
256
|
-
new Line(values: TLineValues)
|
|
257
|
-
|
|
258
|
-
// example
|
|
259
|
-
const pointA = new Point([1, 1]);
|
|
260
|
-
const pointB = new Point([2, 2]);
|
|
261
|
-
const line = new Line([pointA, pointB]);
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
```javascript
|
|
265
|
-
// api
|
|
266
|
-
{
|
|
267
|
-
...Figure // All the Figure properties and methods.
|
|
268
|
-
|
|
269
|
-
P0: Point; // Returns the defining point of the line.
|
|
270
|
-
isHorizontal: boolean; // Returns true if the line is horizontal, otherwise false.
|
|
271
|
-
isVertical: boolean; // Returns true if the line is vertical, otherwise false.
|
|
272
|
-
reciprocal: number | undefined; // Returns the line's reciprocal value or undefined if the line is horizontal.
|
|
273
|
-
slope: number | undefined; // Returns the line's slope value or undefined if the line is vertical.
|
|
274
|
-
xIntercept: number | undefined; // Returns the x coordinate value of the point where the line intercepts the x axis, undefined if the line is horizontal or coincides with the x acis.
|
|
275
|
-
yIntercept: number | undefined; // Returns the y coordinate value of the point where the line intercepts the y axis, undefined if the line is vertical or coincides with the y axis.
|
|
276
|
-
angleTo(reference: Line | Vector): Angle; // Returns the angle betweem itself and a given line or vector.
|
|
277
|
-
getIntersectionPoint(line: Line): Point | undefined; // Returns the point of intersection between itself and a given line, undefined if the lines are parallel or coincide.
|
|
278
|
-
getPerpendicularProjection(point: Point): Point; // Returns the perpendicular projection point within the line of a given point.
|
|
279
|
-
getPerpendicularThrough(point: Point): Line; // Returns a line passing through a given point that is perpendicular to the current line.
|
|
280
|
-
getPointAtParameter(t: number): Point | undefined; // Returns a point that belongs to the line corresponding to a given value of t (where t is a Real number).
|
|
281
|
-
getXValueAtY(y: number): number | undefined; // Returns the x value of a point that belongs to the line given a value of y, undefined if the line is horizontal.
|
|
282
|
-
getYValueAtX(x: number): number | undefined; // Returns the y value of a point that belongs to the line given a value of x, undefined if the line is vertical.
|
|
283
|
-
hasPoint(point: Point): boolean; // Returns true if a given point belongs to the line, false otherwise.
|
|
284
|
-
isParallelTo(line: Line): boolean; // Returns true if the line is parallel to a given line, false otherwise.
|
|
285
|
-
isPerpendicularTo(line: Line): boolean; // Returns true if the line is perpendicular to a given line, false otherwise.
|
|
286
|
-
}
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
#### Polygon
|
|
290
|
-
|
|
291
|
-
`Polygon` implements the geometric concept of polygon, which is defined as two dimensional figure with straight sides (lines). In its implementation it's defined by three or more points.
|
|
292
|
-
|
|
293
|
-
```javascript
|
|
294
|
-
type TPolygonValues = [Point, Point, Point, ...Point[]];
|
|
295
|
-
|
|
296
|
-
// constructor
|
|
297
|
-
new Polygon(values: TPolygonValues)
|
|
298
|
-
|
|
299
|
-
// example
|
|
300
|
-
const pointA = new Point([0, 0]);
|
|
301
|
-
const pointB = new Point([0, 5]);
|
|
302
|
-
const pointC = new Point([5, 5]);
|
|
303
|
-
const polygon = new Polygon([pointA, pointB, pointC]);
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
```javascript
|
|
307
|
-
// api
|
|
308
|
-
{
|
|
309
|
-
...Figure // All the Figure properties and methods.
|
|
310
|
-
|
|
311
|
-
sides: number; // Returns the number of sides of the polygon.
|
|
312
|
-
}
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
#### QuadraticBezierCurve
|
|
316
|
-
|
|
317
|
-
`QuadraticBezierCurve` implements the geometric concept of a quadratic Bezier curve, which is defined by three points: two endpoints and a control point (or anchor point) that determines the shape of the curve. In its implementation it may also be defined relatively by one base point and two vectors used to calculate the other endpoint and the control point.
|
|
318
|
-
|
|
319
|
-
```javascript
|
|
320
|
-
type TQuadraticBezierValues = [Point, Point, Point] | [Point, Vector, Vector];
|
|
321
|
-
|
|
322
|
-
// constructor
|
|
323
|
-
new QuadraticBezierCurve(values: TQuadraticBezierValues)
|
|
324
|
-
|
|
325
|
-
// example
|
|
326
|
-
const pointA = new Point([0, 0]);
|
|
327
|
-
const pointB = new Point([5, 5]);
|
|
328
|
-
const pointC = new Point([0, 10]);
|
|
329
|
-
const quadraticBezierCurve = new QuadraticBezierCurve([pointA, pointB, pointC]);
|
|
330
|
-
|
|
331
|
-
// example (relative)
|
|
332
|
-
const pointA = new Point([0, 0]);
|
|
333
|
-
const vectorB = new Vector([5, 5]);
|
|
334
|
-
const vectorC = new Vector([0, 5]);
|
|
335
|
-
const quadraticBezierCurve = new QuadraticBezierCurve([pointA, vectorB, vectorC]);
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
```javascript
|
|
339
|
-
// api
|
|
340
|
-
{
|
|
341
|
-
...Figure // All the Figure properties and methods.
|
|
342
|
-
|
|
343
|
-
criticalPoints: Point[]; // Returns the points (if any) where the derivative of the curve is zero, meaning points where the rate of change for x or y is zero. This is useful for finding peeks and valleys of the curve in the direction of either axis. This is essential, for example, for correctly calculating the bounding box of the curve.
|
|
344
|
-
}
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
#### CubicBezierCurve
|
|
348
|
-
|
|
349
|
-
`CubicBezierCurve` implements the geometric concept of a cubic Bezier curve, which is defined by four points: two endpoints and a two control points (or anchor points) that determine the shape of the curve. In its implementation it may also be defined relatively by one base point and three vectors used to calculate the other endpoint and the two control points.
|
|
350
|
-
|
|
351
|
-
```javascript
|
|
352
|
-
type TCubicBezierValues = [Point, Point, Point, Point] | [Point, Vector, Vector, Vector];
|
|
353
|
-
|
|
354
|
-
// constructor
|
|
355
|
-
new CubicBezierCurve(values: TCubicBezierValues)
|
|
356
|
-
|
|
357
|
-
// example
|
|
47
|
+
// Create two points and a line between them
|
|
358
48
|
const pointA = new Point([0, 0]);
|
|
359
49
|
const pointB = new Point([5, 5]);
|
|
360
|
-
const
|
|
361
|
-
const pointD = new Point([15, 0]);
|
|
362
|
-
const cubicBezierCurve = new CubicBezierCurve([pointA, pointB, pointC, pointD]);
|
|
363
|
-
|
|
364
|
-
// example (relative)
|
|
365
|
-
const pointA = new Point([0, 0]);
|
|
366
|
-
const vectorB = new Vector([5, 5]);
|
|
367
|
-
const vectorC = new Vector([10, 5]);
|
|
368
|
-
const vectorD = new Vector([15, 0]);
|
|
369
|
-
const cubicBezierCurve = new CubicBezierCurve([pointA, vectorB, vectorC, vectorD]);
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
```javascript
|
|
373
|
-
// api
|
|
374
|
-
{
|
|
375
|
-
...Figure // All the Figure properties and methods.
|
|
376
|
-
|
|
377
|
-
criticalPoints: Point[]; // Returns the points (if any) where the derivative of the curve is zero, meaning points where the rate of change for x or y is zero. This is useful for finding peeks and valleys of the curve in the direction of either axis. This is essential, for example, for correctly calculating the bounding box of the curve.
|
|
378
|
-
}
|
|
379
|
-
```
|
|
380
|
-
|
|
381
|
-
#### Ellipse
|
|
382
|
-
|
|
383
|
-
`Ellipse` implements the geometric concept of ellipse, which is defined is the figure determined by all those points in a plane such that the sum of their distances from two fixed points in the plane, is constant. You may think of it as a circle with two radii instead of one, one for each axis. In its implementation it's defined by its center point, two radii and the angle between the x-axis of the ellipse and the coordinate system's x-axis, in other words, the angle at which it is rotated, if any.
|
|
384
|
-
|
|
385
|
-
```javascript
|
|
386
|
-
// constructor
|
|
387
|
-
new Ellipse(values: [center: Point, rx: Magnitude, ry: Magnitude, rotation: Angle])
|
|
388
|
-
|
|
389
|
-
// example
|
|
390
|
-
const center = new Point([0, 0]);
|
|
391
|
-
const rx = new Magnitude(5);
|
|
392
|
-
const ry = new Magnitude(10);
|
|
393
|
-
const rotation = new Angle(45, 'degrees');
|
|
394
|
-
const ellipse = new Ellipse([center, rx, ry, rotation]);
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
```javascript
|
|
398
|
-
// api
|
|
399
|
-
{
|
|
400
|
-
...Figure // All the Figure properties and methods.
|
|
401
|
-
|
|
402
|
-
center: Point; // Returns the center point of the ellipse.
|
|
403
|
-
phi: Angle; // Returns the angle of rotation of the ellipse, meaning the angle between the x-axis of the ellipse and the coordinate system's x-axis.
|
|
404
|
-
rx: Magnitude; // Returns the radius magnitude of the ellipse's x-axis.
|
|
405
|
-
ry: Magnitude; // Returns the radius magnitude of the ellipse's y-axis.
|
|
406
|
-
criticalPoints: [Point, Point, Point, Point]; // Returns the points (always 4) where the derivative of the curve of the ellipse is zero, meaning points where the rate of change for x or y is zero. This is useful for finding peeks and valleys of the ellipse's curve in the direction of either axis. This is essential, for example, for correctly calculating the bounding box of the ellipse.
|
|
407
|
-
computePointForTheta(theta: Angle): Point; // Returns the point belonging to the ellipse at a given angle.
|
|
408
|
-
computeThetaForPoint(point: Point): Angle; // Returns the angle at which a point belonging to the ellipse is found.
|
|
409
|
-
}
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
#### Circle
|
|
413
|
-
|
|
414
|
-
`Circle` implements the geometric concept of circle, which is defined is the figure figure in which the set of all its points in the plane are equidistant from a given point (center). You may think of it as an ellipse with equal radii. In contrast to the ellipse, as regardless of rotation of the circle its shape stays the same, there is no need for a rotation angle.
|
|
50
|
+
const line = new Line([pointA, pointB]);
|
|
415
51
|
|
|
416
|
-
|
|
417
|
-
//
|
|
418
|
-
|
|
52
|
+
// Check line properties
|
|
53
|
+
console.log(line.slope); // 1
|
|
54
|
+
console.log(line.yIntercept); // 0
|
|
419
55
|
|
|
420
|
-
//
|
|
421
|
-
const
|
|
422
|
-
const
|
|
423
|
-
|
|
56
|
+
// Transform with chaining
|
|
57
|
+
const vector = new Vector([2, 3]);
|
|
58
|
+
const angle = new Angle(90, 'degrees');
|
|
59
|
+
pointA.translate(vector).rotate(angle);
|
|
424
60
|
```
|
|
425
61
|
|
|
426
|
-
|
|
427
|
-
// api
|
|
428
|
-
{
|
|
429
|
-
...Figure // All the Figure properties and methods.
|
|
62
|
+
## Dependencies
|
|
430
63
|
|
|
431
|
-
|
|
432
|
-
radius: Magnitude; // Returns the radius magnitude of the circle.
|
|
433
|
-
criticalPoints: [Point, Point, Point, Point]; // Returns the points (always 4) where the derivative of the curve of the circle is zero, meaning points where the rate of change for x or y is zero. This is useful for finding peeks and valleys of the circle's curve in the direction of either axis. This is essential, for example, for correctly calculating the bounding box of the circle.
|
|
434
|
-
}
|
|
435
|
-
```
|
|
64
|
+
### Decimal.js
|
|
436
65
|
|
|
437
|
-
|
|
66
|
+
JavaScript has well-documented issues with floating-point arithmetic. This library uses [Decimal.js](https://mikemcl.github.io/decimal.js/) under the hood (via the `Calculator` utility class) to handle precision correctly.
|
|
438
67
|
|
|
439
|
-
|
|
68
|
+
You do **not** need to install Decimal.js separately - it is included as a dependency of this library. All math operations are routed through `Calculator`, which applies epsilon-based rounding (1e-8) to eliminate floating-point artifacts.
|
|
440
69
|
|
|
441
|
-
|
|
442
|
-
type TArcAbsoluteValues = [Point, Magnitude, Magnitude, Angle, Flag, Flag, Point];
|
|
443
|
-
type TArcRelativeValues = [Point, Magnitude, Magnitude, Angle, Flag, Flag, Vector]; // here the Vector is used to determine the end Point
|
|
444
|
-
type TArcValues = TArcAbsoluteValues | TArcRelativeValues;
|
|
70
|
+
## Documentation
|
|
445
71
|
|
|
446
|
-
|
|
447
|
-
|
|
72
|
+
- **API Reference**
|
|
73
|
+
- [Abstracts](./docs/api/abstracts.md) - Flag, Angle, Magnitude, Vector, Point, Figure
|
|
74
|
+
- [Figures](./docs/api/figures.md) - Line, Polygon, Ellipse, Circle, QuadraticBezierCurve, CubicBezierCurve, ArcCurve
|
|
75
|
+
- [Utilities](./docs/api/utilities.md) - Calculator, coordinateOrigin, xAxis, yAxis, PI2
|
|
76
|
+
- [Types](./docs/api/types.md) - All interfaces and type definitions
|
|
77
|
+
- **[Architecture](./docs/architecture.md)** - Design decisions, patterns, class hierarchy
|
|
78
|
+
- **[Contributing](./docs/contributing.md)** - Bug reports, PRs, coding standards
|
|
448
79
|
|
|
449
|
-
|
|
450
|
-
const pointA = new Point([0, 0]);
|
|
451
|
-
const pointB = new Point([10, 0]);
|
|
452
|
-
const rx = new Magnitude(5);
|
|
453
|
-
const ry = new Magnitude(10);
|
|
454
|
-
const xAxisRotation = new Angle(0, 'degrees');
|
|
455
|
-
const largeArc = new Flag(false); // choose the smaller arc
|
|
456
|
-
const sweep = new Flag(false); // sweep in negative angle increments
|
|
457
|
-
const arcCurve = new ArcCurve([pointA, rx, ry, xAxisRotation, largeArc, sweep, pointB]);
|
|
80
|
+
## References
|
|
458
81
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
const vectorB = new Point([10, 0]);
|
|
462
|
-
const rx = new Magnitude(5);
|
|
463
|
-
const ry = new Magnitude(10);
|
|
464
|
-
const xAxisRotation = new Angle(0, 'degrees');
|
|
465
|
-
const largeArc = new Flag(false); // choose the smaller arc
|
|
466
|
-
const sweep = new Flag(false); // sweep in negative angle increments
|
|
467
|
-
const arcCurve = new ArcCurve([pointA, rx, ry, xAxisRotation, largeArc, sweep, vectorB]);
|
|
468
|
-
```
|
|
82
|
+
- [Intro to Bezier curves](https://iquilezles.org/articles/bezierbbox) by [Inigo Quilez](https://iquilezles.org/).
|
|
83
|
+
- [Arc Implementation Notes](https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes) from the [SVG 2 Specification](https://www.w3.org/TR/SVG).
|
|
469
84
|
|
|
470
|
-
|
|
471
|
-
// api
|
|
472
|
-
{
|
|
473
|
-
...Figure // All the Figure properties and methods.
|
|
85
|
+
## License
|
|
474
86
|
|
|
475
|
-
|
|
476
|
-
criticalPoints: Point[]; // Returns the points (if any) where the derivative of the curve is zero, meaning points where the rate of change for x or y is zero. This is useful for finding peeks and valleys of the curve in the direction of either axis. This is essential, for example, for correctly calculating the bounding box of the curve.
|
|
477
|
-
}
|
|
478
|
-
```
|
|
87
|
+
This project is published and distributed under the [MIT License](./LICENSE).
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Angle = void 0;
|
|
4
|
-
const
|
|
5
|
-
const PI2 = +Calculator_1.Calculator.mul(Math.PI, 2);
|
|
4
|
+
const calculator_1 = require("../../utilities/calculator");
|
|
6
5
|
class Angle {
|
|
6
|
+
kind = 'angle';
|
|
7
7
|
_radians;
|
|
8
8
|
constructor(value, unit) {
|
|
9
9
|
this._radians = unit === 'radians' ? value : Angle.toRadians(value);
|
|
10
10
|
}
|
|
11
11
|
get cos() {
|
|
12
|
-
return +
|
|
12
|
+
return +calculator_1.Calculator.cos(this.radians);
|
|
13
13
|
}
|
|
14
14
|
get cot() {
|
|
15
|
-
return +
|
|
15
|
+
return +calculator_1.Calculator.div(1, this.tan);
|
|
16
16
|
}
|
|
17
17
|
get degrees() {
|
|
18
18
|
return Angle.toDegrees(this.radians);
|
|
@@ -21,16 +21,16 @@ class Angle {
|
|
|
21
21
|
return this._radians;
|
|
22
22
|
}
|
|
23
23
|
get sin() {
|
|
24
|
-
return +
|
|
24
|
+
return +calculator_1.Calculator.sin(this.radians);
|
|
25
25
|
}
|
|
26
26
|
get tan() {
|
|
27
|
-
return +
|
|
27
|
+
return +calculator_1.Calculator.tan(this.radians);
|
|
28
28
|
}
|
|
29
29
|
static toDegrees(radians) {
|
|
30
|
-
return +
|
|
30
|
+
return +calculator_1.Calculator.mul(radians, 180).div(Math.PI);
|
|
31
31
|
}
|
|
32
32
|
static toRadians(degrees) {
|
|
33
|
-
return +
|
|
33
|
+
return +calculator_1.Calculator.mul(degrees, Math.PI).div(180);
|
|
34
34
|
}
|
|
35
35
|
clone() {
|
|
36
36
|
return new Angle(this.radians, 'radians');
|
|
@@ -38,10 +38,10 @@ class Angle {
|
|
|
38
38
|
normalize() {
|
|
39
39
|
const { radians } = this;
|
|
40
40
|
if (radians < 0) {
|
|
41
|
-
this._radians = +
|
|
41
|
+
this._radians = +calculator_1.Calculator.add(radians, calculator_1.Calculator.PI2);
|
|
42
42
|
}
|
|
43
43
|
else if (radians > 0) {
|
|
44
|
-
this._radians = +
|
|
44
|
+
this._radians = +calculator_1.Calculator.mod(radians, calculator_1.Calculator.PI2);
|
|
45
45
|
}
|
|
46
46
|
return this;
|
|
47
47
|
}
|
|
@@ -50,7 +50,7 @@ class Angle {
|
|
|
50
50
|
return this;
|
|
51
51
|
}
|
|
52
52
|
scale(factor) {
|
|
53
|
-
this._radians = +
|
|
53
|
+
this._radians = +calculator_1.Calculator.mul(this.radians, factor);
|
|
54
54
|
return this;
|
|
55
55
|
}
|
|
56
56
|
valueOf() {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./Angle"), exports);
|
|
18
|
+
__exportStar(require("./Angle.types"), exports);
|