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
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
- ## Usage
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
- You may then `import` (ESM) any of the classes listed in the **API** section:
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
- const { Point } = require('geometric-library');
23
+ import { Point, Line, Vector, Angle } from 'geometric-library';
32
24
  ```
33
25
 
34
- If you're using TypeScript for your project you can also `import` types and interfaces for all the exported functionalities, which is recommended as it will make your life easier in terms of understading how everything works.
26
+ ## Importing (CommonJS)
35
27
 
36
28
  ```javascript
37
- import { IPoint, TPointValues } from 'geometric-library';
29
+ const { Point, Line, Vector, Angle } = require('geometric-library');
38
30
  ```
39
31
 
40
- ## Dependencies
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
- This project is open to contribution.
34
+ If you're using TypeScript, you can import types and interfaces for all exported functionalities:
53
35
 
54
- If you have found a bug please open an issue so it can be tracked and addressed as soon as possible. Please include information about how to reproduce it as well as the expected result and the actual result.
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
- ```javascript
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
- ```javascript
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
- ```javascript
116
- // api
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
- ### Figures
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 pointC = new Point([10, 5]);
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
- ```javascript
417
- // constructor
418
- new Circle(values: [center: Point, radius: Magnitude])
52
+ // Check line properties
53
+ console.log(line.slope); // 1
54
+ console.log(line.yIntercept); // 0
419
55
 
420
- // example
421
- const center = new Point([0, 0]);
422
- const radius = new Magnitude(5);
423
- const circle = new Circle([center, radius]);
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
- ```javascript
427
- // api
428
- {
429
- ...Figure // All the Figure properties and methods.
62
+ ## Dependencies
430
63
 
431
- center: Point; // Returns the center point of the circle.
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
- #### ArcCurve
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
- `ArcCurve` represents a defined segment of a rotatable ellipse and it is usually defined by centric parameters: a center point, an x radius, a y radius, an angle (phi) between the x-axis of the ellipse and the coordinate system's x-axis, an angle (theta1) representing the point at which the segment starts and an angle (theta2) representing the point at which the segment ends. As any two points of an ellipse can determine two different segments, a flag parameter is also necessary in order to determine whether the arc should be drawn in positive increments from the start angle (theta1) toward the end angle (theta2) or in negative increments (the "sweep" flag). In its implementation, an arc curve is defined by endpoint parameters, that is, instead of a center parameter we define two points that represent the start point and end point of the arc. Internally the center is computed and the radii are adjusted, if necessary, in order for all the calculations and transformations to be correct. This is useful when wanting to create an elliptical arc from point A to point B, which is usually the case. Since there are always two possible ellipses of a given angle and dimensions that can pass through the two given endpoints, now there are 4 possible arc segments to choose from and therefore one more flag is necessary (the "large arc" flag). See the [Arc Implementation Notes from the SVG 2 Specification](https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes) for a more thorough explanation.
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
- ```javascript
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
- // constructor
447
- new ArcCurve(values: TArcValues)
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
- // example
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
- // example (relative)
460
- const pointA = new Point([0, 0]);
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
- ```javascript
471
- // api
472
- {
473
- ...Figure // All the Figure properties and methods.
85
+ ## License
474
86
 
475
- center: Point; // Returns the center point of the ellipse.
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 Calculator_1 = require("../utilities/Calculator");
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 +Calculator_1.Calculator.cos(this.radians);
12
+ return +calculator_1.Calculator.cos(this.radians);
13
13
  }
14
14
  get cot() {
15
- return +Calculator_1.Calculator.div(1, this.tan);
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 +Calculator_1.Calculator.sin(this.radians);
24
+ return +calculator_1.Calculator.sin(this.radians);
25
25
  }
26
26
  get tan() {
27
- return +Calculator_1.Calculator.tan(this.radians);
27
+ return +calculator_1.Calculator.tan(this.radians);
28
28
  }
29
29
  static toDegrees(radians) {
30
- return +Calculator_1.Calculator.mul(radians, 180).div(Math.PI);
30
+ return +calculator_1.Calculator.mul(radians, 180).div(Math.PI);
31
31
  }
32
32
  static toRadians(degrees) {
33
- return +Calculator_1.Calculator.mul(degrees, Math.PI).div(180);
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 = +Calculator_1.Calculator.add(radians, PI2);
41
+ this._radians = +calculator_1.Calculator.add(radians, calculator_1.Calculator.PI2);
42
42
  }
43
43
  else if (radians > 0) {
44
- this._radians = +Calculator_1.Calculator.mod(radians, PI2);
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 = +Calculator_1.Calculator.mul(this.radians, factor);
53
+ this._radians = +calculator_1.Calculator.mul(this.radians, factor);
54
54
  return this;
55
55
  }
56
56
  valueOf() {
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -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);