plotboilerplate 1.23.3 → 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 (159) hide show
  1. package/README.md +6 -0
  2. package/dist/index.esm.js +1390 -265
  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 +1264 -99
  9. package/dist/plotboilerplate.min.js +1 -1
  10. package/package.json +1 -1
  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.js +2 -9
  30. package/src/cjs/PlotBoilerplate.js.map +1 -1
  31. package/src/cjs/Polygon.d.ts +48 -4
  32. package/src/cjs/Polygon.js +91 -16
  33. package/src/cjs/Polygon.js.map +1 -1
  34. package/src/cjs/Triangle.d.ts +52 -3
  35. package/src/cjs/Triangle.js +80 -1
  36. package/src/cjs/Triangle.js.map +1 -1
  37. package/src/cjs/VEllipse.d.ts +62 -3
  38. package/src/cjs/VEllipse.js +181 -17
  39. package/src/cjs/VEllipse.js.map +1 -1
  40. package/src/cjs/VEllipseSector.d.ts +86 -2
  41. package/src/cjs/VEllipseSector.js +148 -4
  42. package/src/cjs/VEllipseSector.js.map +1 -1
  43. package/src/cjs/Vector.d.ts +12 -2
  44. package/src/cjs/Vector.js +15 -2
  45. package/src/cjs/Vector.js.map +1 -1
  46. package/src/cjs/VertTuple.d.ts +28 -4
  47. package/src/cjs/VertTuple.js +36 -3
  48. package/src/cjs/VertTuple.js.map +1 -1
  49. package/src/cjs/Vertex.d.ts +17 -2
  50. package/src/cjs/Vertex.js +18 -1
  51. package/src/cjs/Vertex.js.map +1 -1
  52. package/src/cjs/interfaces/core.d.ts +39 -0
  53. package/src/cjs/interfaces/core.js +2 -0
  54. package/src/cjs/interfaces/core.js.map +1 -1
  55. package/src/cjs/utils/algorithms/convexPolygonIncircle.d.ts +2 -1
  56. package/src/cjs/utils/algorithms/convexPolygonIncircle.js +14 -6
  57. package/src/cjs/utils/algorithms/convexPolygonIncircle.js.map +1 -1
  58. package/src/cjs/utils/createRandomizedPolygon.d.ts +14 -0
  59. package/src/cjs/utils/createRandomizedPolygon.js +32 -0
  60. package/src/cjs/utils/createRandomizedPolygon.js.map +1 -0
  61. package/src/cjs/utils/helpers/BezierPathInteractionHelper.d.ts +9 -7
  62. package/src/cjs/utils/helpers/BezierPathInteractionHelper.js +37 -23
  63. package/src/cjs/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
  64. package/src/cjs/utils/helpers/CircleSectorHelper.d.ts +10 -1
  65. package/src/cjs/utils/helpers/CircleSectorHelper.js +19 -20
  66. package/src/cjs/utils/helpers/CircleSectorHelper.js.map +1 -1
  67. package/src/cjs/utils/helpers/VEllipseHelper.d.ts +30 -0
  68. package/src/cjs/utils/helpers/VEllipseHelper.js +86 -0
  69. package/src/cjs/utils/helpers/VEllipseHelper.js.map +1 -0
  70. package/src/cjs/utils/helpers/VEllipseSectorHelper.d.ts +42 -3
  71. package/src/cjs/utils/helpers/VEllipseSectorHelper.js +107 -25
  72. package/src/cjs/utils/helpers/VEllipseSectorHelper.js.map +1 -1
  73. package/src/createDemoDrawables.js +3 -1
  74. package/src/esm/BezierPath.d.ts +41 -5
  75. package/src/esm/BezierPath.js +50 -2
  76. package/src/esm/BezierPath.js.map +1 -1
  77. package/src/esm/Bounds.d.ts +67 -3
  78. package/src/esm/Bounds.js +101 -3
  79. package/src/esm/Bounds.js.map +1 -1
  80. package/src/esm/Circle.d.ts +46 -4
  81. package/src/esm/Circle.js +79 -3
  82. package/src/esm/Circle.js.map +1 -1
  83. package/src/esm/CircleSector.d.ts +51 -2
  84. package/src/esm/CircleSector.js +108 -3
  85. package/src/esm/CircleSector.js.map +1 -1
  86. package/src/esm/CubicBezierCurve.d.ts +113 -7
  87. package/src/esm/CubicBezierCurve.js +277 -33
  88. package/src/esm/CubicBezierCurve.js.map +1 -1
  89. package/src/esm/Line.d.ts +38 -3
  90. package/src/esm/Line.js +62 -1
  91. package/src/esm/Line.js.map +1 -1
  92. package/src/esm/PlotBoilerplate.js +2 -9
  93. package/src/esm/PlotBoilerplate.js.map +1 -1
  94. package/src/esm/Polygon.d.ts +48 -4
  95. package/src/esm/Polygon.js +89 -16
  96. package/src/esm/Polygon.js.map +1 -1
  97. package/src/esm/Triangle.d.ts +52 -3
  98. package/src/esm/Triangle.js +77 -1
  99. package/src/esm/Triangle.js.map +1 -1
  100. package/src/esm/VEllipse.d.ts +62 -3
  101. package/src/esm/VEllipse.js +178 -17
  102. package/src/esm/VEllipse.js.map +1 -1
  103. package/src/esm/VEllipseSector.d.ts +86 -2
  104. package/src/esm/VEllipseSector.js +146 -7
  105. package/src/esm/VEllipseSector.js.map +1 -1
  106. package/src/esm/Vector.d.ts +12 -2
  107. package/src/esm/Vector.js +15 -2
  108. package/src/esm/Vector.js.map +1 -1
  109. package/src/esm/VertTuple.d.ts +28 -4
  110. package/src/esm/VertTuple.js +36 -3
  111. package/src/esm/VertTuple.js.map +1 -1
  112. package/src/esm/Vertex.d.ts +17 -2
  113. package/src/esm/Vertex.js +18 -1
  114. package/src/esm/Vertex.js.map +1 -1
  115. package/src/esm/interfaces/core.d.ts +39 -0
  116. package/src/esm/interfaces/core.js +2 -0
  117. package/src/esm/interfaces/core.js.map +1 -1
  118. package/src/esm/utils/algorithms/convexPolygonIncircle.d.ts +2 -1
  119. package/src/esm/utils/algorithms/convexPolygonIncircle.js +15 -7
  120. package/src/esm/utils/algorithms/convexPolygonIncircle.js.map +1 -1
  121. package/src/esm/utils/algorithms/createRandomizedPolygon.d.ts +14 -0
  122. package/src/esm/utils/algorithms/createRandomizedPolygon.js +28 -0
  123. package/src/esm/utils/algorithms/createRandomizedPolygon.js.map +1 -0
  124. package/src/esm/utils/createRandomizedPolygon.d.ts +14 -0
  125. package/src/esm/utils/createRandomizedPolygon.js +28 -0
  126. package/src/esm/utils/createRandomizedPolygon.js.map +1 -0
  127. package/src/esm/utils/helpers/BezierPathInteractionHelper.d.ts +9 -7
  128. package/src/esm/utils/helpers/BezierPathInteractionHelper.js +35 -22
  129. package/src/esm/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
  130. package/src/esm/utils/helpers/CircleSectorHelper.d.ts +10 -1
  131. package/src/esm/utils/helpers/CircleSectorHelper.js +19 -20
  132. package/src/esm/utils/helpers/CircleSectorHelper.js.map +1 -1
  133. package/src/esm/utils/helpers/VEllipseHelper.d.ts +30 -0
  134. package/src/esm/utils/helpers/VEllipseHelper.js +81 -0
  135. package/src/esm/utils/helpers/VEllipseHelper.js.map +1 -0
  136. package/src/esm/utils/helpers/VEllipseSectorHelper.d.ts +42 -3
  137. package/src/esm/utils/helpers/VEllipseSectorHelper.js +106 -24
  138. package/src/esm/utils/helpers/VEllipseSectorHelper.js.map +1 -1
  139. package/src/ts/BezierPath.ts +58 -5
  140. package/src/ts/Bounds.ts +110 -6
  141. package/src/ts/Circle.ts +87 -5
  142. package/src/ts/CircleSector.ts +115 -5
  143. package/src/ts/CubicBezierCurve.ts +332 -42
  144. package/src/ts/Line.ts +66 -3
  145. package/src/ts/PlotBoilerplate.ts +3 -9
  146. package/src/ts/Polygon.ts +103 -22
  147. package/src/ts/Triangle.ts +85 -3
  148. package/src/ts/VEllipse.ts +214 -19
  149. package/src/ts/VEllipseSector.ts +154 -8
  150. package/src/ts/Vector.ts +16 -2
  151. package/src/ts/VertTuple.ts +39 -4
  152. package/src/ts/Vertex.ts +20 -2
  153. package/src/ts/interfaces/core.ts +42 -0
  154. package/src/ts/utils/algorithms/convexPolygonIncircle.ts +82 -78
  155. package/src/ts/utils/createRandomizedPolygon.ts +31 -0
  156. package/src/ts/utils/helpers/BezierPathInteractionHelper.ts +45 -29
  157. package/src/ts/utils/helpers/CircleSectorHelper.ts +115 -125
  158. package/src/ts/utils/helpers/VEllipseHelper.ts +113 -0
  159. package/src/ts/utils/helpers/VEllipseSectorHelper.ts +142 -25
package/src/ts/Vertex.ts CHANGED
@@ -33,7 +33,9 @@
33
33
  * @modified 2023-09-29 Added the `Vertex.abs()` method as it seems useful.
34
34
  * @modified 2024-03-08 Added the optional `precision` param to the `toString` method.
35
35
  * @modified 2024-12-17 Outsourced the euclidean distance calculation of `Vertex.distance` to `geomutils.dist4`.
36
- * @version 2.9.1
36
+ * @modified 2025-03-24 Making the second parameter `center` of the `Vertex.rotate` method optional.
37
+ * @modified 2025-04-13 Adding the `Vertex.move(amount: XYCoords)` method (does the same as `add`, added by naming convention).
38
+ * @version 2.10.0
37
39
  *
38
40
  * @file Vertex
39
41
  * @public
@@ -272,6 +274,22 @@ export class Vertex implements XYCoords, SVGSerializable {
272
274
  return this;
273
275
  }
274
276
 
277
+ /**
278
+ * Move this point by the given amount.
279
+ *
280
+ * This method just calls `add(amount).
281
+ *
282
+ *
283
+ * @method move
284
+ * @param {Vertex} amount - The amount to move this vertex.
285
+ * @return {Vertex} this - For chaining.
286
+ * @instance
287
+ * @memberof Vertex
288
+ */
289
+ move(amount: XYCoords): Vertex {
290
+ return this.add(amount);
291
+ }
292
+
275
293
  /**
276
294
  * Add the passed amounts to the x- and y- components of this vertex.
277
295
  *
@@ -554,7 +572,7 @@ export class Vertex implements XYCoords, SVGSerializable {
554
572
  * @instance
555
573
  * @memberof Vertex
556
574
  **/
557
- rotate(angle: number, center: XYCoords | undefined): Vertex {
575
+ rotate(angle: number, center?: XYCoords | undefined): Vertex {
558
576
  if (!center || typeof center === "undefined") {
559
577
  center = { x: 0, y: 0 };
560
578
  }
@@ -20,6 +20,8 @@
20
20
  * @modified 2023-02-10 All non-function attributes of the `Config` interface are now mandatory.
21
21
  * @modified 2023-09-29 Added the `randomPoint(...)` function declaration to the IBounds interface.
22
22
  * @modified 2024-08-25 Added the `CSSBackdropFilterParams` params to the global params (all optional).
23
+ * @modified 2025-03-29 Added interface `Intersectable`.
24
+ * @modified 2025-04-16 Added interface `IBounded`.
23
25
  **/
24
26
 
25
27
  import { Vertex } from "../Vertex";
@@ -37,6 +39,7 @@ import { PlotBoilerplate } from "../PlotBoilerplate";
37
39
  import { DrawLib } from "./DrawLib";
38
40
  import { PBText } from "../PBText";
39
41
  import { CSSBackdropFilterParams } from "./externals";
42
+ import { VertTuple } from "../VertTuple";
40
43
 
41
44
  /**
42
45
  * @classdesc Coordinates (x,y) on the plane.
@@ -261,3 +264,42 @@ export interface IDraggable {
261
264
  isVertex(): boolean;
262
265
  setVIndex(vindex: number): IDraggable;
263
266
  }
267
+
268
+ /**
269
+ * Shapes should implement this interface if they support intersection calculation.
270
+ */
271
+ export interface Intersectable {
272
+ /**
273
+ * Get all line intersections with this polygon.
274
+ *
275
+ * This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.
276
+ *
277
+ * See demo `47-closest-vector-projection-on-polygon` for how it works.
278
+ *
279
+ * @param {VertTuple} line - The line to find intersections with.
280
+ * @param {boolean} inVectorBoundsOnly - (default=false) If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).
281
+ * @returns {Array<Vertex>} - An array of all intersections within this shape's bounds.
282
+ */
283
+ lineIntersections(line: VertTuple<any>, inVectorBoundsOnly?: boolean): Array<Vertex>;
284
+
285
+ /**
286
+ * Get all line intersections of this polygon and their tangents along the shape.
287
+ *
288
+ * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.
289
+ *
290
+ * @param {VertTuple} line - The line to find intersections with.
291
+ * @param {boolean} inVectorBoundsOnly - (default=false) If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).
292
+ * @returns {Array<Vector>} - An array of all intersection tangents within this shape's bounds.
293
+ */
294
+ lineIntersectionTangents(line: VertTuple<any>, inVectorBoundsOnly?: boolean): Array<Vector>;
295
+ }
296
+
297
+ export interface IBounded {
298
+ /**
299
+ * Get the bounding box (bounds) of this shape.
300
+ *
301
+ * @method getBounds
302
+ * @return {Bounds} The rectangular bounds of this shape.
303
+ **/
304
+ getBounds(): IBounds;
305
+ }
@@ -1,8 +1,9 @@
1
- /**
1
+ /**
2
2
  * @author mbostock, extended and ported to TypeScript by Ikaros Kappler
3
3
  * @date 2020-05-19
4
4
  * @modified 2021-02-08 Fixed a lot of es2015 compatibility issues.
5
- * @version 1.0.2
5
+ * @modified 2024-03-24 Fixing some unstrict types to match with the new Typescript settings.
6
+ * @version 1.0.3
6
7
  * @file contextPolygonIncircle
7
8
  * @public
8
9
  */
@@ -14,17 +15,16 @@ import { Polygon } from "../../Polygon";
14
15
  import { Triangle } from "../../Triangle";
15
16
  import { Vertex } from "../../Vertex";
16
17
 
17
-
18
18
  /**
19
19
  * For circle-polygon-intersection-count detection we need an epsilon to
20
20
  * eliminate smaller precision errors.
21
21
  */
22
- const EPS : number = 0.000001;
22
+ const EPS: number = 0.000001;
23
23
 
24
24
  export interface PolygonIncircle {
25
- circle : Circle;
26
- triangle : Triangle;
27
- };
25
+ circle: Circle;
26
+ triangle: Triangle;
27
+ }
28
28
 
29
29
  /**
30
30
  * Compute the max sized inlying circle in the given convex (!) polygon - also called the
@@ -50,54 +50,60 @@ export interface PolygonIncircle {
50
50
  * @param {Polygon} convexHull - The actual convex polygon.
51
51
  * @return {PolygonIncircle} A pair of a circle (the incircle) and a triangle (the three points where the circle is touching the polygon).
52
52
  */
53
- export const convexPolygonIncircle = ( convexHull:Polygon ) : PolygonIncircle => {
54
- var n : number = convexHull.vertices.length;
55
- var bestCircle : Circle|undefined = undefined;
56
- var bestTriangle : Triangle|undefined = undefined;
57
- for( var a = 0; a < n; a++ ) {
58
- for( var b = a+1; b < n; b++ ) {
59
- for( var c = b+1; c < n; c++ ) {
60
- // As these lines are part of the convex hull, we know that
61
- // * line a preceeds line b and
62
- // * line b preceeds line c :)
63
- let lineA : Line = new Line( convexHull.vertices[a], convexHull.vertices[(a+1)%n] );
64
- let lineB : Line = new Line( convexHull.vertices[b], convexHull.vertices[(b+1)%n] );
65
- let lineC : Line = new Line( convexHull.vertices[c], convexHull.vertices[(c+1)%n] );
66
-
67
- // Find intersections by expanding the lines
68
- let vertB : Vertex = lineA.intersection(lineB);
69
- let vertC : Vertex = lineB.intersection(lineC);
70
-
71
- // An object: { center: Vertex, radius: number }
72
- let triangle : Triangle = getTangentTriangle4( lineA.a, vertB, vertC, lineC.b );
73
- // Workaround. There will be a future version where the 'getCircumCircle()' functions
74
- // returns a real Circle instance.
75
- let _circle : Circle = triangle.getCircumcircle();
76
- let circle : Circle = new Circle( _circle.center, _circle.radius );
77
-
78
- // Count the number of intersections with the convex hull:
79
- // If there are exactly three, we have found an in-lying circle.
80
- // * Check if this one is better (bigger) than the old one.
81
- // * Also check if the circle is located inside the polygon;
82
- // The construction can, in some cases, produce an out-lying circle.
83
- if( !convexHull.containsVert(circle.center) ) {
84
- continue;
85
- }
86
- var circleIntersections : Array<number> = findCircleIntersections( convexHull, circle );
87
- if( circleIntersections.length == 3 && (bestCircle == undefined || bestCircle.radius < circle.radius) ) {
88
- bestCircle = circle;
89
- bestTriangle = triangle;
90
- }
91
- }
92
- }
53
+ export const convexPolygonIncircle = (convexHull: Polygon): PolygonIncircle => {
54
+ var n: number = convexHull.vertices.length;
55
+ var bestCircle: Circle | null = null;
56
+ var bestTriangle: Triangle | null = null;
57
+ for (var a = 0; a < n; a++) {
58
+ for (var b = a + 1; b < n; b++) {
59
+ for (var c = b + 1; c < n; c++) {
60
+ // As these lines are part of the convex hull, we know that
61
+ // * line a preceeds line b and
62
+ // * line b preceeds line c :)
63
+ let lineA: Line = new Line(convexHull.vertices[a], convexHull.vertices[(a + 1) % n]);
64
+ let lineB: Line = new Line(convexHull.vertices[b], convexHull.vertices[(b + 1) % n]);
65
+ let lineC: Line = new Line(convexHull.vertices[c], convexHull.vertices[(c + 1) % n]);
66
+
67
+ // Find intersections by expanding the lines
68
+ let vertB: Vertex | null = lineA.intersection(lineB);
69
+ let vertC: Vertex | null = lineB.intersection(lineC);
70
+
71
+ if (!vertB || !vertC) {
72
+ continue;
73
+ }
74
+
75
+ // An object: { center: Vertex, radius: number }
76
+ let triangle: Triangle | null = getTangentTriangle4(lineA.a, vertB, vertC, lineC.b);
77
+ if (!triangle) {
78
+ continue;
79
+ }
80
+
81
+ // Workaround. There will be a future version where the 'getCircumCircle()' functions
82
+ // returns a real Circle instance.
83
+ let _circle: Circle = triangle.getCircumcircle();
84
+ let circle: Circle = new Circle(_circle.center, _circle.radius);
85
+
86
+ // Count the number of intersections with the convex hull:
87
+ // If there are exactly three, we have found an in-lying circle.
88
+ // * Check if this one is better (bigger) than the old one.
89
+ // * Also check if the circle is located inside the polygon;
90
+ // The construction can, in some cases, produce an out-lying circle.
91
+ if (!convexHull.containsVert(circle.center)) {
92
+ continue;
93
+ }
94
+ var circleIntersections: Array<number> = findCircleIntersections(convexHull, circle);
95
+ if (circleIntersections.length == 3 && (bestCircle == undefined || bestCircle.radius < circle.radius)) {
96
+ bestCircle = circle;
97
+ bestTriangle = triangle;
98
+ }
99
+ }
93
100
  }
94
- return { circle : bestCircle,
95
- triangle : bestTriangle };
101
+ }
102
+ return { circle: bestCircle as Circle, triangle: bestTriangle as Triangle };
96
103
  };
97
104
 
98
-
99
105
  /**
100
- * This function computes the three points for the inner maximum circle
106
+ * This function computes the three points for the inner maximum circle
101
107
  * lying tangential to the three subsequential lines (given by four points).
102
108
  *
103
109
  * Compute the circle from that triangle by using Triangle.getCircumcircle().
@@ -114,26 +120,26 @@ export const convexPolygonIncircle = ( convexHull:Polygon ) : PolygonIncircle =>
114
120
  * @param {Vertex} vertD - The fourth point of the three connected lines.
115
121
  * @return {Triangle} The triangle of the circular tangential points with the given lines (3 or 4 of them).
116
122
  */
117
- const getTangentTriangle4 = ( vertA : Vertex,
118
- vertB : Vertex,
119
- vertC : Vertex,
120
- vertD : Vertex ) : Triangle => {
121
- const lineA : Line = new Line(vertA,vertB);
122
- const lineB : Line = new Line(vertB,vertC);
123
- const lineC : Line = new Line(vertC,vertD);
123
+ const getTangentTriangle4 = (vertA: Vertex, vertB: Vertex, vertC: Vertex, vertD: Vertex): Triangle | null => {
124
+ const lineA: Line = new Line(vertA, vertB);
125
+ const lineB: Line = new Line(vertB, vertC);
126
+ const lineC: Line = new Line(vertC, vertD);
124
127
 
125
- const bisector1 : Line = geomutils.nsectAngle( vertB, vertA, vertC, 2 )[0]; // bisector of first triangle
126
- const bisector2 : Line = geomutils.nsectAngle( vertC, vertB, vertD, 2 )[0]; // bisector of second triangle
127
- const intersection : Vertex = bisector1.intersection( bisector2 );
128
+ const bisector1: Line = geomutils.nsectAngle(vertB, vertA, vertC, 2)[0]; // bisector of first triangle
129
+ const bisector2: Line = geomutils.nsectAngle(vertC, vertB, vertD, 2)[0]; // bisector of second triangle
130
+ const intersection: Vertex | null = bisector1.intersection(bisector2);
128
131
 
129
- // Find the closest points on one of the polygon lines (all have same distance by construction)
130
- const circleIntersA : Vertex = lineA.getClosestPoint( intersection );
131
- const circleIntersB : Vertex = lineB.getClosestPoint( intersection );
132
- const circleIntersC : Vertex = lineC.getClosestPoint( intersection );
132
+ if (!intersection) {
133
+ return null;
134
+ }
133
135
 
134
- return new Triangle(circleIntersA, circleIntersB, circleIntersC);
135
- };
136
+ // Find the closest points on one of the polygon lines (all have same distance by construction)
137
+ const circleIntersA: Vertex = lineA.getClosestPoint(intersection);
138
+ const circleIntersB: Vertex = lineB.getClosestPoint(intersection);
139
+ const circleIntersC: Vertex = lineC.getClosestPoint(intersection);
136
140
 
141
+ return new Triangle(circleIntersA, circleIntersB, circleIntersC);
142
+ };
137
143
 
138
144
  /**
139
145
  * Find all intersecting lines (indices) on the polyon that intersect the circle.
@@ -142,16 +148,14 @@ const getTangentTriangle4 = ( vertA : Vertex,
142
148
  * @param {Circle} circle - The circle to detect the intersections with.
143
149
  * @return {Array<number>} The indices of those lines that intersect (or touch) the circle.
144
150
  **/
145
- const findCircleIntersections = ( convexHull:Polygon, circle:Circle ) : Array<number> => {
146
- var result = [];
147
- for( var i = 0; i < convexHull.vertices.length; i++ ) {
148
- var line : Line = new Line( convexHull.vertices[i], convexHull.vertices[(i+1)%convexHull.vertices.length] );
149
- // Use an epsilon here because circle coordinates can be kind of unprecise in the detail.
150
- if( circle.lineDistance(line) < EPS ) {
151
- result.push( i );
152
- }
151
+ const findCircleIntersections = (convexHull: Polygon, circle: Circle): Array<number> => {
152
+ const result: Array<number> = [];
153
+ for (var i = 0; i < convexHull.vertices.length; i++) {
154
+ var line: Line = new Line(convexHull.vertices[i], convexHull.vertices[(i + 1) % convexHull.vertices.length]);
155
+ // Use an epsilon here because circle coordinates can be kind of unprecise in the detail.
156
+ if (circle.lineDistance(line) < EPS) {
157
+ result.push(i);
153
158
  }
154
- return result;
159
+ }
160
+ return result;
155
161
  };
156
-
157
-
@@ -0,0 +1,31 @@
1
+ /**
2
+ * A helper function to generate randmoized non-intersecting polygons.
3
+ *
4
+ * @author Ikaros Kappler
5
+ * @date 2025-03-23 (ported to Typescript from a helper script from 2024)
6
+ * @version 1.0.0
7
+ */
8
+
9
+ import { Bounds } from "../Bounds";
10
+ import { Polygon } from "../Polygon";
11
+ import { Vertex } from "../Vertex";
12
+
13
+ /**
14
+ * @param numVertices
15
+ * @returns
16
+ */
17
+
18
+ export const createRandomizedPolygon = (numVertices: number, viewport: Bounds, createClockwise?: boolean) => {
19
+ const polygon = new Polygon();
20
+ for (var i = 0; i < numVertices; i++) {
21
+ const vert = new Vertex(viewport.getMinDimension() * 0.33, 0.0);
22
+ vert.rotate(((Math.PI * 2) / numVertices) * i);
23
+ vert.addXY(viewport.width * 0.1 * (1.0 - Math.random() * 2), viewport.height * 0.1 * (1.0 - Math.random() * 2));
24
+ polygon.addVertex(vert);
25
+ }
26
+ if (createClockwise && !polygon.isClockwise()) {
27
+ // Reverse
28
+ polygon.vertices = polygon.vertices.reverse();
29
+ }
30
+ return polygon;
31
+ };
@@ -22,16 +22,18 @@
22
22
  * @modified 2021-03-31 Fixed the issue with the new AlloyFinger (Typescript).
23
23
  * @modified 2022-02-03 Changing the element to catch events (eventCatcher instead of canvas).
24
24
  * @modified 2024-03-10 Fixing some types for Typescript 5 compatibility.
25
- * @version 1.1.3
25
+ * @modified 2025-04-14 Added the `BezierPathInteractionHelper.drawHandleLines` method.
26
+ * @modified 2025-04-14 Fixing correct event types for touch events in `BezierPathInteractionHelper`.
27
+ * @modified 2025-04-14 BezierPathInteractionHelper: Changed default value of `HelperOptions.autoAdjustPaths` from `true` to `false`.
28
+ * @version 1.2.0
26
29
  *
27
30
  * @file BezierPathInteractionHelper
28
31
  * @public
29
32
  **/
30
33
 
31
- // import { AlloyFinger } from "alloyfinger"; // node_modules
32
34
  // I would like to use AlloyFinger from the node_modules, but it seems
33
35
  // AlloyTeam has forgotten to publish their d.ts file.
34
- import { AlloyFinger } from "../../../../lib/alloy_finger";
36
+ import AlloyFinger from "alloyfinger-typescript";
35
37
  import { BezierPath } from "../../BezierPath";
36
38
  import { CubicBezierCurve } from "../../CubicBezierCurve";
37
39
  import { KeyHandler } from "../../KeyHandler";
@@ -40,7 +42,8 @@ import { PlotBoilerplate } from "../../PlotBoilerplate";
40
42
  import { VertListener } from "../../VertexListeners";
41
43
  import { Vertex } from "../../Vertex";
42
44
  import { XMouseEvent } from "../../MouseHandler";
43
- import { XYCoords } from "../../interfaces";
45
+ import { DrawLib, XYCoords } from "../../interfaces";
46
+ import { AFTouchEvent } from "alloyfinger-typescript/src/cjs/alloy_finger";
44
47
 
45
48
  /**
46
49
  * Handler type for mouse-pointer-moved listeners.
@@ -153,7 +156,9 @@ export class BezierPathInteractionHelper {
153
156
  this.pb = pb;
154
157
  this.paths = [];
155
158
  this.onPointerMoved =
156
- typeof options.onPointerMoved === "function" ? options.onPointerMoved : (i: number, a: Vertex | null, b: Vertex | null, t: number) => {};
159
+ typeof options.onPointerMoved === "function"
160
+ ? options.onPointerMoved
161
+ : (i: number, a: Vertex | null, b: Vertex | null, t: number) => {};
157
162
  this.onVertexInserted =
158
163
  typeof options.onVertexInserted === "function"
159
164
  ? options.onVertexInserted
@@ -163,7 +168,7 @@ export class BezierPathInteractionHelper {
163
168
  ? options.onVerticesDeleted
164
169
  : (i: number, r: Array<number>, n: BezierPath, o: BezierPath) => {};
165
170
  this.onPathRemoved = typeof options.onPathRemoved === "function" ? options.onPathRemoved : (i: number, o: BezierPath) => {};
166
- this.autoAdjustPaths = typeof options.autoAdjustPaths === "boolean" ? options.autoAdjustPaths : true;
171
+ this.autoAdjustPaths = typeof options.autoAdjustPaths === "boolean" ? options.autoAdjustPaths : false; // true;
167
172
  this.allowPathRemoval = typeof options.allowPathRemoval === "boolean" ? options.allowPathRemoval : true;
168
173
  this.maxDetectDistance = typeof options.maxDetectDistance === "number" ? options.maxDetectDistance : Number.MAX_VALUE;
169
174
 
@@ -192,7 +197,9 @@ export class BezierPathInteractionHelper {
192
197
  this._keyHandler = this._installKeyListener();
193
198
 
194
199
  // Paths might have changed by auto-adjustment.
195
- if (this.autoAdjustPaths) pb.redraw();
200
+ if (this.autoAdjustPaths) {
201
+ pb.redraw();
202
+ }
196
203
  }
197
204
 
198
205
  /**
@@ -263,6 +270,24 @@ export class BezierPathInteractionHelper {
263
270
  this._handleMoveEvent(this.currentB.x, this.currentB.y);
264
271
  }
265
272
 
273
+ /**
274
+ * Draw grey handle lines.
275
+ *
276
+ */
277
+ drawHandleLines() {
278
+ this.paths.forEach((path: BezierPath) => {
279
+ path.bezierCurves.forEach((curve: CubicBezierCurve) => {
280
+ this.pb.draw.line(curve.startPoint, curve.startControlPoint, "rgba(64,192,128,0.333)", 1.0, {
281
+ dashOffset: 0.0,
282
+ dashArray: [4, 2]
283
+ });
284
+ this.pb.draw.line(curve.endPoint, curve.endControlPoint, "rgba(64,192,128,0.333)", 1.0, {
285
+ dashOffset: 0.0,
286
+ dashArray: [4, 2]
287
+ });
288
+ });
289
+ });
290
+ }
266
291
  /**
267
292
  * This function should invalidate any installed listeners and invalidate this object.
268
293
  * After calling this function the object might not hold valid data any more and
@@ -438,22 +463,31 @@ export class BezierPathInteractionHelper {
438
463
  var _self: BezierPathInteractionHelper = this;
439
464
  const afProps = {
440
465
  // Todo: which event types does AlloyFinger use?
441
- touchStart: function (_event: TouchEvent) {
466
+ // touchStart: function (_event: TouchEvent) {
467
+ // _self.mouseIsOver = true;
468
+ // },
469
+ // /* TouchMoveEvent , AFTouchEvent<"touchStart"> */
470
+ touchStart: function (_event: AFTouchEvent<"touchStart">) {
442
471
  _self.mouseIsOver = true;
443
472
  },
444
- touchMove: function (event: TouchEvent) {
473
+ touchMove: function (event: AFTouchEvent<"touchMove">) {
474
+ // TouchEvent) {
445
475
  if (_self.pb.getDraggedElementCount() == 0 && event.touches.length > 0) {
446
476
  // console.log('touchmove');
447
477
  _self._handleMoveEvent(event.touches[0].clientX, event.touches[0].clientY);
448
478
  }
449
479
  },
450
- touchEnd: function (_event: TouchEvent) {
480
+ touchEnd: function (_event: AFTouchEvent<"touchEnd">) {
481
+ // TouchEvent) {
451
482
  _self.mouseIsOver = false;
452
483
  _self._clearMoveEvent();
453
484
  }
454
485
  };
455
486
  if (window["createAlloyFinger" as keyof Object]) {
456
- return (window["createAlloyFinger" as keyof Object] as any)(this.pb.eventCatcher ? this.pb.eventCatcher : this.pb.eventCatcher, afProps);
487
+ return (window["createAlloyFinger" as keyof Object] as any)(
488
+ this.pb.eventCatcher ? this.pb.eventCatcher : this.pb.eventCatcher,
489
+ afProps
490
+ );
457
491
  } else {
458
492
  return new AlloyFinger(this.pb.eventCatcher ? this.pb.eventCatcher : this.pb.eventCatcher, afProps);
459
493
  }
@@ -578,24 +612,6 @@ export class BezierPathInteractionHelper {
578
612
  path.updateArcLengths();
579
613
  }
580
614
 
581
- /**
582
- * A helper function to add drag-start-listener to given vertices.
583
- */
584
- /* private static _addVertsDragStartListener( verts:Array<Vertex>, dragStartListener:VertListener ) : void {
585
- for( var i in verts ) {
586
- verts[i].addDragStartListener( dragStartListener );
587
- }
588
- }; */
589
-
590
- /**
591
- * A helper function to remove drag-start-listener to given vertices.
592
- */
593
- /* private static _removeVertsDragStartListener( verts:Array<Vertex>, dragEndListener:VertListener ) : void {
594
- for( var i in verts ) {
595
- verts[i].removeDragStartListener( dragStartListener );
596
- }
597
- }; */
598
-
599
615
  /**
600
616
  * A helper function to add drag-start listeners to all vertices of the given path.
601
617
  *