plotboilerplate 1.23.2 → 1.24.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 (218) hide show
  1. package/README.md +6 -0
  2. package/dist/index.esm.js +8351 -6928
  3. package/dist/index.esm.js.map +1 -1
  4. package/dist/index.esm.min.js +1 -1
  5. package/dist/index.esm.min.js.map +1 -1
  6. package/dist/plotboilerplate.browser.min.js +1 -1
  7. package/dist/plotboilerplate.browser.min.js.map +1 -1
  8. package/dist/plotboilerplate.js +1590 -123
  9. package/dist/plotboilerplate.min.js +1 -1
  10. package/package.json +4 -2
  11. package/src/cjs/BezierPath.d.ts +41 -5
  12. package/src/cjs/BezierPath.js +52 -2
  13. package/src/cjs/BezierPath.js.map +1 -1
  14. package/src/cjs/Bounds.d.ts +67 -3
  15. package/src/cjs/Bounds.js +101 -3
  16. package/src/cjs/Bounds.js.map +1 -1
  17. package/src/cjs/Circle.d.ts +46 -4
  18. package/src/cjs/Circle.js +82 -3
  19. package/src/cjs/Circle.js.map +1 -1
  20. package/src/cjs/CircleSector.d.ts +51 -2
  21. package/src/cjs/CircleSector.js +112 -3
  22. package/src/cjs/CircleSector.js.map +1 -1
  23. package/src/cjs/CubicBezierCurve.d.ts +113 -7
  24. package/src/cjs/CubicBezierCurve.js +281 -33
  25. package/src/cjs/CubicBezierCurve.js.map +1 -1
  26. package/src/cjs/Line.d.ts +38 -3
  27. package/src/cjs/Line.js +64 -1
  28. package/src/cjs/Line.js.map +1 -1
  29. package/src/cjs/PlotBoilerplate.d.ts +4 -2
  30. package/src/cjs/PlotBoilerplate.js +9 -12
  31. package/src/cjs/PlotBoilerplate.js.map +1 -1
  32. package/src/cjs/Polygon.d.ts +153 -6
  33. package/src/cjs/Polygon.js +304 -23
  34. package/src/cjs/Polygon.js.map +1 -1
  35. package/src/cjs/Triangle.d.ts +73 -4
  36. package/src/cjs/Triangle.js +94 -2
  37. package/src/cjs/Triangle.js.map +1 -1
  38. package/src/cjs/VEllipse.d.ts +62 -3
  39. package/src/cjs/VEllipse.js +181 -17
  40. package/src/cjs/VEllipse.js.map +1 -1
  41. package/src/cjs/VEllipseSector.d.ts +86 -2
  42. package/src/cjs/VEllipseSector.js +148 -4
  43. package/src/cjs/VEllipseSector.js.map +1 -1
  44. package/src/cjs/Vector.d.ts +12 -2
  45. package/src/cjs/Vector.js +15 -2
  46. package/src/cjs/Vector.js.map +1 -1
  47. package/src/cjs/VertTuple.d.ts +39 -10
  48. package/src/cjs/VertTuple.js +49 -11
  49. package/src/cjs/VertTuple.js.map +1 -1
  50. package/src/cjs/Vertex.d.ts +18 -2
  51. package/src/cjs/Vertex.js +22 -2
  52. package/src/cjs/Vertex.js.map +1 -1
  53. package/src/cjs/draw.d.ts +1 -0
  54. package/src/cjs/draw.js +2 -1
  55. package/src/cjs/draw.js.map +1 -1
  56. package/src/cjs/drawutilssvg.js +24 -0
  57. package/src/cjs/drawutilssvg.js.map +1 -1
  58. package/src/cjs/geomutils.d.ts +32 -1
  59. package/src/cjs/geomutils.js +47 -1
  60. package/src/cjs/geomutils.js.map +1 -1
  61. package/src/cjs/interfaces/core.d.ts +39 -0
  62. package/src/cjs/interfaces/core.js +2 -0
  63. package/src/cjs/interfaces/core.js.map +1 -1
  64. package/src/cjs/utils/algorithms/PolygonInset.d.ts +184 -0
  65. package/src/cjs/utils/algorithms/PolygonInset.js +431 -0
  66. package/src/cjs/utils/algorithms/PolygonInset.js.map +1 -0
  67. package/src/cjs/utils/algorithms/clearDuplicateVertices.d.ts +5 -4
  68. package/src/cjs/utils/algorithms/clearDuplicateVertices.js +6 -3
  69. package/src/cjs/utils/algorithms/clearDuplicateVertices.js.map +1 -1
  70. package/src/cjs/utils/algorithms/convexPolygonIncircle.d.ts +2 -1
  71. package/src/cjs/utils/algorithms/convexPolygonIncircle.js +14 -6
  72. package/src/cjs/utils/algorithms/convexPolygonIncircle.js.map +1 -1
  73. package/src/cjs/utils/algorithms/findPolygonSelfIntersections.d.ts +2 -1
  74. package/src/cjs/utils/algorithms/findPolygonSelfIntersections.js +3 -3
  75. package/src/cjs/utils/algorithms/findPolygonSelfIntersections.js.map +1 -1
  76. package/src/cjs/utils/algorithms/splitPolygonToNonIntersecting.d.ts +3 -2
  77. package/src/cjs/utils/algorithms/splitPolygonToNonIntersecting.js +11 -9
  78. package/src/cjs/utils/algorithms/splitPolygonToNonIntersecting.js.map +1 -1
  79. package/src/cjs/utils/createRandomizedPolygon.d.ts +14 -0
  80. package/src/cjs/utils/createRandomizedPolygon.js +32 -0
  81. package/src/cjs/utils/createRandomizedPolygon.js.map +1 -0
  82. package/src/cjs/utils/detectDarkMode.js.map +1 -1
  83. package/src/cjs/utils/dom/guiSizeToggler.d.ts +2 -1
  84. package/src/cjs/utils/dom/guiSizeToggler.js +5 -3
  85. package/src/cjs/utils/dom/guiSizeToggler.js.map +1 -1
  86. package/src/cjs/utils/helpers/BezierPathInteractionHelper.d.ts +9 -7
  87. package/src/cjs/utils/helpers/BezierPathInteractionHelper.js +37 -23
  88. package/src/cjs/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
  89. package/src/cjs/utils/helpers/CircleSectorHelper.d.ts +10 -1
  90. package/src/cjs/utils/helpers/CircleSectorHelper.js +19 -20
  91. package/src/cjs/utils/helpers/CircleSectorHelper.js.map +1 -1
  92. package/src/cjs/utils/helpers/VEllipseHelper.d.ts +30 -0
  93. package/src/cjs/utils/helpers/VEllipseHelper.js +86 -0
  94. package/src/cjs/utils/helpers/VEllipseHelper.js.map +1 -0
  95. package/src/cjs/utils/helpers/VEllipseSectorHelper.d.ts +42 -3
  96. package/src/cjs/utils/helpers/VEllipseSectorHelper.js +107 -25
  97. package/src/cjs/utils/helpers/VEllipseSectorHelper.js.map +1 -1
  98. package/src/createDemoDrawables.js +3 -1
  99. package/src/esm/BezierPath.d.ts +41 -5
  100. package/src/esm/BezierPath.js +50 -2
  101. package/src/esm/BezierPath.js.map +1 -1
  102. package/src/esm/Bounds.d.ts +67 -3
  103. package/src/esm/Bounds.js +101 -3
  104. package/src/esm/Bounds.js.map +1 -1
  105. package/src/esm/Circle.d.ts +46 -4
  106. package/src/esm/Circle.js +79 -3
  107. package/src/esm/Circle.js.map +1 -1
  108. package/src/esm/CircleSector.d.ts +51 -2
  109. package/src/esm/CircleSector.js +108 -3
  110. package/src/esm/CircleSector.js.map +1 -1
  111. package/src/esm/CubicBezierCurve.d.ts +113 -7
  112. package/src/esm/CubicBezierCurve.js +277 -33
  113. package/src/esm/CubicBezierCurve.js.map +1 -1
  114. package/src/esm/Line.d.ts +38 -3
  115. package/src/esm/Line.js +62 -1
  116. package/src/esm/Line.js.map +1 -1
  117. package/src/esm/PlotBoilerplate.d.ts +4 -2
  118. package/src/esm/PlotBoilerplate.js +9 -12
  119. package/src/esm/PlotBoilerplate.js.map +1 -1
  120. package/src/esm/Polygon.d.ts +153 -6
  121. package/src/esm/Polygon.js +301 -23
  122. package/src/esm/Polygon.js.map +1 -1
  123. package/src/esm/Triangle.d.ts +73 -4
  124. package/src/esm/Triangle.js +91 -2
  125. package/src/esm/Triangle.js.map +1 -1
  126. package/src/esm/VEllipse.d.ts +62 -3
  127. package/src/esm/VEllipse.js +178 -17
  128. package/src/esm/VEllipse.js.map +1 -1
  129. package/src/esm/VEllipseSector.d.ts +86 -2
  130. package/src/esm/VEllipseSector.js +146 -7
  131. package/src/esm/VEllipseSector.js.map +1 -1
  132. package/src/esm/Vector.d.ts +12 -2
  133. package/src/esm/Vector.js +15 -2
  134. package/src/esm/Vector.js.map +1 -1
  135. package/src/esm/VertTuple.d.ts +39 -10
  136. package/src/esm/VertTuple.js +49 -11
  137. package/src/esm/VertTuple.js.map +1 -1
  138. package/src/esm/Vertex.d.ts +18 -2
  139. package/src/esm/Vertex.js +22 -2
  140. package/src/esm/Vertex.js.map +1 -1
  141. package/src/esm/draw.d.ts +1 -0
  142. package/src/esm/draw.js +2 -1
  143. package/src/esm/draw.js.map +1 -1
  144. package/src/esm/drawutilssvg.js +24 -0
  145. package/src/esm/drawutilssvg.js.map +1 -1
  146. package/src/esm/geomutils.d.ts +32 -1
  147. package/src/esm/geomutils.js +47 -1
  148. package/src/esm/geomutils.js.map +1 -1
  149. package/src/esm/interfaces/core.d.ts +39 -0
  150. package/src/esm/interfaces/core.js +2 -0
  151. package/src/esm/interfaces/core.js.map +1 -1
  152. package/src/esm/utils/algorithms/PolygonInset.d.ts +184 -0
  153. package/src/esm/utils/algorithms/PolygonInset.js +424 -0
  154. package/src/esm/utils/algorithms/PolygonInset.js.map +1 -0
  155. package/src/esm/utils/algorithms/clearDuplicateVertices.d.ts +5 -4
  156. package/src/esm/utils/algorithms/clearDuplicateVertices.js +6 -3
  157. package/src/esm/utils/algorithms/clearDuplicateVertices.js.map +1 -1
  158. package/src/esm/utils/algorithms/convexPolygonIncircle.d.ts +2 -1
  159. package/src/esm/utils/algorithms/convexPolygonIncircle.js +15 -7
  160. package/src/esm/utils/algorithms/convexPolygonIncircle.js.map +1 -1
  161. package/src/esm/utils/algorithms/createRandomizedPolygon.d.ts +14 -0
  162. package/src/esm/utils/algorithms/createRandomizedPolygon.js +28 -0
  163. package/src/esm/utils/algorithms/createRandomizedPolygon.js.map +1 -0
  164. package/src/esm/utils/algorithms/findPolygonSelfIntersections.d.ts +2 -1
  165. package/src/esm/utils/algorithms/findPolygonSelfIntersections.js +3 -3
  166. package/src/esm/utils/algorithms/findPolygonSelfIntersections.js.map +1 -1
  167. package/src/esm/utils/algorithms/splitPolygonToNonIntersecting.d.ts +3 -2
  168. package/src/esm/utils/algorithms/splitPolygonToNonIntersecting.js +11 -9
  169. package/src/esm/utils/algorithms/splitPolygonToNonIntersecting.js.map +1 -1
  170. package/src/esm/utils/createRandomizedPolygon.d.ts +14 -0
  171. package/src/esm/utils/createRandomizedPolygon.js +28 -0
  172. package/src/esm/utils/createRandomizedPolygon.js.map +1 -0
  173. package/src/esm/utils/detectDarkMode.js.map +1 -1
  174. package/src/esm/utils/dom/guiSizeToggler.d.ts +2 -1
  175. package/src/esm/utils/dom/guiSizeToggler.js +4 -2
  176. package/src/esm/utils/dom/guiSizeToggler.js.map +1 -1
  177. package/src/esm/utils/helpers/BezierPathInteractionHelper.d.ts +9 -7
  178. package/src/esm/utils/helpers/BezierPathInteractionHelper.js +35 -22
  179. package/src/esm/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
  180. package/src/esm/utils/helpers/CircleSectorHelper.d.ts +10 -1
  181. package/src/esm/utils/helpers/CircleSectorHelper.js +19 -20
  182. package/src/esm/utils/helpers/CircleSectorHelper.js.map +1 -1
  183. package/src/esm/utils/helpers/VEllipseHelper.d.ts +30 -0
  184. package/src/esm/utils/helpers/VEllipseHelper.js +81 -0
  185. package/src/esm/utils/helpers/VEllipseHelper.js.map +1 -0
  186. package/src/esm/utils/helpers/VEllipseSectorHelper.d.ts +42 -3
  187. package/src/esm/utils/helpers/VEllipseSectorHelper.js +106 -24
  188. package/src/esm/utils/helpers/VEllipseSectorHelper.js.map +1 -1
  189. package/src/ts/BezierPath.ts +58 -5
  190. package/src/ts/Bounds.ts +110 -6
  191. package/src/ts/Circle.ts +87 -5
  192. package/src/ts/CircleSector.ts +115 -5
  193. package/src/ts/CubicBezierCurve.ts +332 -42
  194. package/src/ts/Line.ts +66 -3
  195. package/src/ts/PlotBoilerplate.ts +10 -12
  196. package/src/ts/Polygon.ts +329 -27
  197. package/src/ts/Triangle.ts +101 -5
  198. package/src/ts/VEllipse.ts +214 -19
  199. package/src/ts/VEllipseSector.ts +154 -8
  200. package/src/ts/Vector.ts +16 -2
  201. package/src/ts/VertTuple.ts +53 -13
  202. package/src/ts/Vertex.ts +24 -3
  203. package/src/ts/draw.ts +2 -1
  204. package/src/ts/drawutilssvg.ts +29 -0
  205. package/src/ts/geomutils.ts +49 -1
  206. package/src/ts/interfaces/core.ts +42 -0
  207. package/src/ts/utils/algorithms/PolygonInset.ts +529 -0
  208. package/src/ts/utils/algorithms/clearDuplicateVertices.ts +11 -8
  209. package/src/ts/utils/algorithms/convexPolygonIncircle.ts +82 -78
  210. package/src/ts/utils/algorithms/findPolygonSelfIntersections.ts +25 -26
  211. package/src/ts/utils/algorithms/splitPolygonToNonIntersecting.ts +92 -99
  212. package/src/ts/utils/createRandomizedPolygon.ts +31 -0
  213. package/src/ts/utils/detectDarkMode.ts +1 -3
  214. package/src/ts/utils/dom/guiSizeToggler.ts +4 -2
  215. package/src/ts/utils/helpers/BezierPathInteractionHelper.ts +45 -29
  216. package/src/ts/utils/helpers/CircleSectorHelper.ts +115 -125
  217. package/src/ts/utils/helpers/VEllipseHelper.ts +113 -0
  218. package/src/ts/utils/helpers/VEllipseSectorHelper.ts +142 -25
package/src/ts/Circle.ts CHANGED
@@ -12,15 +12,18 @@
12
12
  * @modified 2022-08-15 Added the `containsPoint` function.
13
13
  * @modified 2022-08-23 Added the `lineIntersection` function.
14
14
  * @modified 2022-08-23 Added the `closestPoint` function.
15
- * @version 1.4.0
15
+ * @modified 2025-04-09 Added the `Circle.move(amount: XYCoords)` method.
16
+ * @modified 2025-04-16 Class `Circle` now implements interface `Intersectable`.
17
+ * @version 1.5.0
16
18
  **/
17
19
 
20
+ import { Bounds } from "./Bounds";
18
21
  import { Line } from "./Line";
19
22
  import { UIDGenerator } from "./UIDGenerator";
20
23
  import { Vector } from "./Vector";
21
24
  import { VertTuple } from "./VertTuple";
22
25
  import { Vertex } from "./Vertex";
23
- import { SVGSerializable, UID, XYCoords } from "./interfaces";
26
+ import { IBounded, Intersectable, SVGSerializable, UID, XYCoords } from "./interfaces";
24
27
 
25
28
  /**
26
29
  * @classdesc A simple circle: center point and radius.
@@ -33,7 +36,7 @@ import { SVGSerializable, UID, XYCoords } from "./interfaces";
33
36
  * @requires UID
34
37
  * @requires UIDGenerator
35
38
  **/
36
- export class Circle implements SVGSerializable {
39
+ export class Circle implements IBounded, Intersectable, SVGSerializable {
37
40
  /**
38
41
  * Required to generate proper CSS classes and other class related IDs.
39
42
  **/
@@ -85,6 +88,20 @@ export class Circle implements SVGSerializable {
85
88
  this.radius = radius;
86
89
  }
87
90
 
91
+ /**
92
+ * Move the circle by the given amount.
93
+ *
94
+ * @method move
95
+ * @param {XYCoords} amount - The amount to move.
96
+ * @instance
97
+ * @memberof Circle
98
+ * @return {Circle} this for chaining
99
+ **/
100
+ move(amount: XYCoords): Circle {
101
+ this.center.add(amount);
102
+ return this;
103
+ }
104
+
88
105
  /**
89
106
  * Check if the given circle is fully contained inside this circle.
90
107
  *
@@ -159,8 +176,26 @@ export class Circle implements SVGSerializable {
159
176
  const pointA: Vertex = Circle.circleUtils.vertAt(angle, this.radius);
160
177
  // Construct the perpendicular of the line in point a. Then move relative to center.
161
178
  return (new Vector(pointA, new Vertex(0, 0)).add(this.center) as Vector).perp() as Vector;
179
+ // return (new Vector(this.center.clone(), pointA).add(pointA) as Vector).perp() as Vector;
162
180
  }
163
181
 
182
+ //--- BEGIN --- Implement interface `Intersectable`
183
+ /**
184
+ * Get the bounding box (bounds) of this Circle.
185
+ *
186
+ * @method getBounds
187
+ * @instance
188
+ * @memberof Circle
189
+ * @return {Bounds} The rectangular bounds of this Circle.
190
+ **/
191
+ getBounds(): Bounds {
192
+ return new Bounds(
193
+ this.center.clone().subXY(Math.abs(this.radius), Math.abs(this.radius)),
194
+ this.center.clone().addXY(Math.abs(this.radius), Math.abs(this.radius))
195
+ );
196
+ }
197
+ //--- END --- Implement interface `Intersectable`
198
+
164
199
  /**
165
200
  * Calculate the intersection points (if exists) with the given circle.
166
201
  *
@@ -221,7 +256,7 @@ export class Circle implements SVGSerializable {
221
256
  * @instance
222
257
  * @memberof Circle
223
258
  * @param {Vertex} a- The first of the two points defining the line.
224
- * @param {Vertex} b - The second of the two points defining the line.
259
+ * @param {XYCoords} b - The second of the two points defining the line.
225
260
  * @return {Line|null} The intersection points (as a line) or null if this circle does not intersect the line given.
226
261
  **/
227
262
  lineIntersection(a: Vertex, b: XYCoords): Line | null {
@@ -262,9 +297,56 @@ export class Circle implements SVGSerializable {
262
297
  interB.y = (-det * diff.x - Math.abs(diff.y) * sqrt) / distSquared;
263
298
 
264
299
  return new Line(interA.add(this.center), interB.add(this.center));
265
- // return new Line(interA, interB);
266
300
  }
267
301
 
302
+ //--- BEGIN --- Implement interface `Intersectable`
303
+ /**
304
+ * Get all line intersections with this circle.
305
+ *
306
+ * This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.
307
+ *
308
+ * @param {VertTuple} line - The line to find intersections with.
309
+ * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).
310
+ * @returns {Array<Vertex>} - An array of all intersections with the circle outline.
311
+ */
312
+ lineIntersections(line: VertTuple<any>, inVectorBoundsOnly: boolean = false): Array<Vertex> {
313
+ // Find the intersections of all lines inside the edge bounds
314
+ const intersectioLine: Line | null = this.lineIntersection(line.a, line.b);
315
+ if (!intersectioLine) {
316
+ return [];
317
+ }
318
+ if (inVectorBoundsOnly) {
319
+ // const maxDist = line.length();
320
+ return [intersectioLine.a, intersectioLine.b].filter((vert: Vertex) => line.hasPoint(vert, true));
321
+ } else {
322
+ return [intersectioLine.a, intersectioLine.b];
323
+ }
324
+ }
325
+
326
+ /**
327
+ * Get all line intersections of this polygon and their tangents along the shape.
328
+ *
329
+ * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.
330
+ *
331
+ * @param line
332
+ * @param lineIntersectionTangents
333
+ * @returns
334
+ */
335
+ lineIntersectionTangents(line: VertTuple<any>, inVectorBoundsOnly: boolean = false): Array<Vector> {
336
+ // Find the intersections of all lines plus their tangents inside the circle bounds
337
+ const interSectionPoints: Array<Vertex> = this.lineIntersections(line, inVectorBoundsOnly);
338
+ return interSectionPoints.map((vert: Vertex) => {
339
+ // Calculate angle
340
+ const lineFromCenter = new Line(this.center, vert);
341
+ const angle: number = lineFromCenter.angle();
342
+ // console.log("angle", (angle / Math.PI) * 180.0);
343
+ // const angle = Math.random() * Math.PI * 2; // TODO
344
+ // Calculate tangent at angle
345
+ return this.tangentAt(angle);
346
+ });
347
+ }
348
+ //--- END --- Implement interface `Intersectable`
349
+
268
350
  /**
269
351
  * Calculate the closest point on the outline of this circle to the given point.
270
352
  *
@@ -8,14 +8,22 @@
8
8
  * @modified 2024-03-08 Added the `containsAngle` method.
9
9
  * @modified 2024-03-09 Added the `circleSectorIntersection` method to find coherent sector intersections..
10
10
  * @modified 2024-03-09 Added the `angleAt` method to determine any angle at some ratio.
11
+ * @modified 2025-04-02 Adding the `CircleSector.lineIntersections` and `CircleSector.lineIntersectionTangents` and implementing `Intersectable`.
12
+ * @modified 2025-04-09 Adding the `CircleSector.move()` method.
13
+ * @modified 2025-04-19 Tweaking the `CircleSector.containsAngle` method: all values (input angle, start- and end- angle) are wrapped into [0,2*PI) now.
14
+ * @modified 2025-04-19 Class `CircleSector` implements interface `Bounded` now (method `getBounds` added).
11
15
  * @version 1.2.0
12
16
  **/
13
17
 
18
+ import { Bounds } from "./Bounds";
14
19
  import { Circle } from "./Circle";
15
20
  import { Line } from "./Line";
16
21
  import { UIDGenerator } from "./UIDGenerator";
22
+ import { Vector } from "./Vector";
23
+ import { VertTuple } from "./VertTuple";
17
24
  import { Vertex } from "./Vertex";
18
- import { PathSegment, SVGPathParams, SVGSerializable, UID, XYCoords } from "./interfaces";
25
+ import { geomutils } from "./geomutils";
26
+ import { IBounded, Intersectable, SVGPathParams, SVGSerializable, UID, XYCoords } from "./interfaces";
19
27
 
20
28
  /**
21
29
  * @classdesc A simple circle sector: circle, start- and end-angle.
@@ -26,7 +34,7 @@ import { PathSegment, SVGPathParams, SVGSerializable, UID, XYCoords } from "./in
26
34
  * @requires UIDGenerator
27
35
  * @requires XYCoords
28
36
  **/
29
- export class CircleSector implements SVGSerializable {
37
+ export class CircleSector implements IBounded, Intersectable, SVGSerializable {
30
38
  /**
31
39
  * Required to generate proper CSS classes and other class related IDs.
32
40
  **/
@@ -87,6 +95,52 @@ export class CircleSector implements SVGSerializable {
87
95
  this.endAngle = endAngle;
88
96
  }
89
97
 
98
+ //--- BEGIN --- Implement interface `IBounded`
99
+ /**
100
+ * Get the bounds of this ellipse.
101
+ *
102
+ * The bounds are approximated by the underlying segment buffer; the more segment there are,
103
+ * the more accurate will be the returned bounds.
104
+ *
105
+ * @method getBounds
106
+ * @instance
107
+ * @memberof VEllipse
108
+ * @return {Bounds} The bounds of this curve.
109
+ **/
110
+ getBounds(): Bounds {
111
+ const _self = this;
112
+ const circleBounds : Bounds = this.circle.getBounds();
113
+ // Calculage angles from east, west, north and south box points and check if they are inside
114
+ const candidates : Array<Vertex> = [
115
+ circleBounds.getNorthPoint(),
116
+ circleBounds.getSouthPoint(),
117
+ circleBounds.getWestPoint(),
118
+ circleBounds.getEastPoint()
119
+ ].filter( (point : Vertex) => {
120
+ // Check for each candidate points if they are contained in this sector. Drop if not.
121
+ const angle : number = new Line(_self.circle.center, point).angle();
122
+ return _self.containsAngle(angle);
123
+ });
124
+ // Compute bounds and inlcude start end end point (they are definitely part of the bounds)
125
+ return Bounds.computeFromVertices(candidates.concat([this.getStartPoint(), this.getEndPoint()]));
126
+ }
127
+ //--- BEGIN --- Implement interface `IBounded`
128
+
129
+
130
+ /**
131
+ * Move the circle sector by the given amount.
132
+ *
133
+ * @method move
134
+ * @param {XYCoords} amount - The amount to move.
135
+ * @instance
136
+ * @memberof CircleSector
137
+ * @return {CircleSector} this for chaining
138
+ **/
139
+ move(amount: XYCoords): CircleSector {
140
+ this.circle.move(amount);
141
+ return this;
142
+ }
143
+
90
144
  /**
91
145
  * Checks wether the given angle (must be inside 0 and PI*2) is contained inside this sector.
92
146
  *
@@ -97,11 +151,21 @@ export class CircleSector implements SVGSerializable {
97
151
  * @return {boolean} True if (and only if) this sector contains the given angle.
98
152
  */
99
153
  containsAngle(angle: number) {
100
- if (this.startAngle <= this.endAngle) {
101
- return angle >= this.startAngle && angle < this.endAngle;
154
+ var wrappedAngle = geomutils.mapAngleTo2PI(angle);
155
+ var wrappedStart = geomutils.mapAngleTo2PI(this.startAngle);
156
+ var wrappedEnd = geomutils.mapAngleTo2PI(this.endAngle);
157
+ // TODO: cleanup
158
+ // if (this.startAngle <= this.endAngle) {
159
+ // return angle >= this.startAngle && angle < this.endAngle;
160
+ // } else {
161
+ // // startAngle > endAngle
162
+ // return angle >= this.startAngle || angle < this.endAngle;
163
+ // }
164
+ if (wrappedStart <= wrappedEnd) {
165
+ return wrappedAngle >= wrappedStart && wrappedAngle < wrappedEnd;
102
166
  } else {
103
167
  // startAngle > endAngle
104
- return angle >= this.startAngle || angle < this.endAngle;
168
+ return wrappedAngle >= wrappedStart || wrappedAngle < wrappedEnd;
105
169
  }
106
170
  }
107
171
 
@@ -206,6 +270,52 @@ export class CircleSector implements SVGSerializable {
206
270
  return resultSector;
207
271
  }
208
272
 
273
+ //--- BEGIN --- Implement interface `Intersectable`
274
+ /**
275
+ * Get the line intersections as vectors with this ellipse.
276
+ *
277
+ * @method lineIntersections
278
+ * @instance
279
+ * @param {VertTuple<Vector> ray - The line/ray to intersect this ellipse with.
280
+ * @param {boolean} inVectorBoundsOnly - (default=false) Set to true if only intersections within the vector bounds are of interest.
281
+ * @returns
282
+ */
283
+ lineIntersections(ray: VertTuple<Vector>, inVectorBoundsOnly: boolean = false): Array<Vertex> {
284
+ // First get all line intersections from underlying ellipse.
285
+ const ellipseIntersections: Array<Vertex> = this.circle.lineIntersections(ray, inVectorBoundsOnly);
286
+ // Drop all intersection points that are not contained in the circle sectors bounds.
287
+ const tmpLine = new Line(this.circle.center, new Vertex());
288
+ return ellipseIntersections.filter((intersectionPoint: Vertex) => {
289
+ tmpLine.b.set(intersectionPoint);
290
+ const lineAngle = tmpLine.angle();
291
+ return this.containsAngle(geomutils.wrapMinMax(lineAngle, 0, Math.PI * 2));
292
+ });
293
+ }
294
+
295
+ /**
296
+ * Get all line intersections of this polygon and their tangents along the shape.
297
+ *
298
+ * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.
299
+ *
300
+ * @param line
301
+ * @param lineIntersectionTangents
302
+ * @returns
303
+ */
304
+ lineIntersectionTangents(line: VertTuple<any>, inVectorBoundsOnly: boolean = false): Array<Vector> {
305
+ // Find the intersections of all lines plus their tangents inside the circle bounds
306
+ const interSectionPoints: Array<Vertex> = this.lineIntersections(line, inVectorBoundsOnly);
307
+ return interSectionPoints.map((vert: Vertex) => {
308
+ // Calculate angle
309
+ const lineFromCenter = new Line(this.circle.center, vert);
310
+ const angle: number = lineFromCenter.angle();
311
+ // console.log("angle", (angle / Math.PI) * 180.0);
312
+ // const angle = Math.random() * Math.PI * 2; // TODO
313
+ // Calculate tangent at angle
314
+ return this.circle.tangentAt(angle);
315
+ });
316
+ }
317
+ //--- END --- Implement interface `Intersectable`
318
+
209
319
  /**
210
320
  * This function should invalidate any installed listeners and invalidate this object.
211
321
  * After calling this function the object might not hold valid data any more and