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
@@ -1,47 +1,129 @@
1
1
  /**
2
2
  * A helper for VEllipseSectors.
3
3
  *
4
- * @author Ikaros Kappler
5
- * @date 2021-03-24
6
- * @version 1.0.0
4
+ * @author Ikaros Kappler
5
+ * @date 2021-03-24
6
+ * @modified 2025-04-02 Adding `VEllipseSectorHelper.drawHandleLines`.
7
+ * @modified 2025-04-07 Modifying the calculation of `startAngle` and `endAngle` from the rotation control point: wrapping result into [0,TWO_PI).
8
+ * @modified 2025-04-09 Adding the `VEllipseSectorHelper.destroy` method.
9
+ * @version 1.1.0
7
10
  */
8
11
  import { Line } from "../../Line";
12
+ import { geomutils } from "../../geomutils";
9
13
  export class VEllipseSectorHelper {
10
14
  constructor(sector, startAngleControlPoint, endAngleControlPoint, rotationControlPoint) {
11
- const rotationControlLine = new Line(sector.ellipse.center, rotationControlPoint);
12
- const startAngleControlLine = new Line(sector.ellipse.center, startAngleControlPoint);
13
- const endAngleControlLine = new Line(sector.ellipse.center, endAngleControlPoint);
15
+ this.sector = sector;
16
+ this.startAngleControlPoint = startAngleControlPoint;
17
+ this.endAngleControlPoint = endAngleControlPoint;
18
+ this.rotationControlPoint = rotationControlPoint;
19
+ // const rotationControlLine: Line = new Line(sector.ellipse.center, rotationControlPoint);
20
+ this._rotationControlLine = new Line(sector.ellipse.center, rotationControlPoint);
21
+ // const startAngleControlLine: Line = new Line(sector.ellipse.center, startAngleControlPoint);
22
+ this._startAngleControlLine = new Line(sector.ellipse.center, startAngleControlPoint);
23
+ // const endAngleControlLine: Line = new Line(sector.ellipse.center, endAngleControlPoint);
24
+ this._endAngleControlLine = new Line(sector.ellipse.center, endAngleControlPoint);
14
25
  // +---------------------------------------------------------------------
15
26
  // | Listen for the center to be moved.
16
27
  // +-------------------------------------------
17
- sector.ellipse.center.listeners.addDragListener((event) => {
18
- startAngleControlPoint.add(event.params.dragAmount);
19
- endAngleControlPoint.add(event.params.dragAmount);
20
- rotationControlPoint.add(event.params.dragAmount);
21
- });
28
+ sector.ellipse.center.listeners.addDragListener((this._centerHandler = this._handleDragCenterPoint()));
22
29
  // +---------------------------------------------------------------------
23
30
  // | Listen for rotation changes.
24
31
  // +-------------------------------------------
25
- rotationControlPoint.listeners.addDragListener((event) => {
26
- var newRotation = rotationControlLine.angle();
27
- var rDiff = newRotation - sector.ellipse.rotation;
28
- sector.ellipse.rotation = newRotation;
29
- sector.ellipse.axis.rotate(rDiff, sector.ellipse.center);
30
- startAngleControlPoint.rotate(rDiff, sector.ellipse.center);
31
- endAngleControlPoint.rotate(rDiff, sector.ellipse.center);
32
- });
32
+ rotationControlPoint.listeners.addDragListener((this._rotationHandler = this._handleDragRotationControlPoint()));
33
33
  // +---------------------------------------------------------------------
34
34
  // | Listen for start angle changes.
35
35
  // +-------------------------------------------
36
- startAngleControlPoint.listeners.addDragListener((event) => {
37
- sector.startAngle = startAngleControlLine.angle() - sector.ellipse.rotation;
38
- });
36
+ startAngleControlPoint.listeners.addDragListener((this._startAngleHandler = this._handleDragStartAngleControlPoint()));
39
37
  // +---------------------------------------------------------------------
40
38
  // | Listen for end angle changes.
41
39
  // +-------------------------------------------
42
- endAngleControlPoint.listeners.addDragListener((event) => {
43
- sector.endAngle = endAngleControlLine.angle() - sector.ellipse.rotation;
40
+ endAngleControlPoint.listeners.addDragListener((this._endAngleHandler = this._handleDragEndAngleControlPoint()));
41
+ }
42
+ /**
43
+ * Creates a new drag handler for the circle sector's start control point.
44
+ *
45
+ * @private
46
+ * @method _handleDragStartControlPoint
47
+ * @instance
48
+ * @memberof CircleSectorHelper
49
+ * @returns A new event handler.
50
+ */
51
+ _handleDragCenterPoint() {
52
+ const _self = this;
53
+ return (event) => {
54
+ _self.startAngleControlPoint.add(event.params.dragAmount);
55
+ _self.endAngleControlPoint.add(event.params.dragAmount);
56
+ _self.rotationControlPoint.add(event.params.dragAmount);
57
+ };
58
+ }
59
+ _handleDragRotationControlPoint() {
60
+ const _self = this;
61
+ return (event) => {
62
+ const newRotation = _self._rotationControlLine.angle();
63
+ const rDiff = newRotation - _self.sector.ellipse.rotation;
64
+ _self.sector.ellipse.rotation = newRotation;
65
+ _self.sector.ellipse.axis.rotate(rDiff, _self.sector.ellipse.center);
66
+ _self.startAngleControlPoint.rotate(rDiff, _self.sector.ellipse.center);
67
+ _self.endAngleControlPoint.rotate(rDiff, _self.sector.ellipse.center);
68
+ };
69
+ }
70
+ _handleDragStartAngleControlPoint() {
71
+ const _self = this;
72
+ return (_event) => {
73
+ // sector.startAngle = startAngleControlLine.angle() - sector.ellipse.rotation;
74
+ _self.sector.startAngle = geomutils.mapAngleTo2PI(_self._startAngleControlLine.angle() - _self.sector.ellipse.rotation);
75
+ };
76
+ }
77
+ _handleDragEndAngleControlPoint() {
78
+ const _self = this;
79
+ return (event) => {
80
+ _self.sector.endAngle = geomutils.mapAngleTo2PI(_self._endAngleControlLine.angle() - _self.sector.ellipse.rotation);
81
+ };
82
+ }
83
+ /**
84
+ * Draw grey handle lines.
85
+ *
86
+ * @param {DrawLib<any>} draw - The draw library instance to use.
87
+ * @param {DrawLib<any>} fill - The fill library instance to use.
88
+ */
89
+ drawHandleLines(draw, fill) {
90
+ draw.line(this.sector.ellipse.center, this.startAngleControlPoint, "rgba(64,192,128,0.333)", 1.0, {
91
+ dashOffset: 0.0,
92
+ dashArray: [4, 2]
93
+ });
94
+ draw.line(this.sector.ellipse.center, this.endAngleControlPoint, "rgba(64,192,128,0.333)", 1.0, {
95
+ dashOffset: 0.0,
96
+ dashArray: [4, 2]
97
+ });
98
+ // Draw rotation handle line
99
+ draw.line(this.sector.ellipse.center, this.rotationControlPoint, "rgba(192,64,128,0.333)", 1.0, {
100
+ dashOffset: 0.0,
101
+ dashArray: [4, 2]
102
+ });
103
+ // Draw helper box
104
+ draw.line(this.sector.ellipse.center
105
+ .clone()
106
+ .add(0, this.sector.ellipse.signedRadiusV())
107
+ .rotate(this.sector.ellipse.rotation, this.sector.ellipse.center), this.sector.ellipse.axis, "rgba(64,128,192,0.333)", 1.0, {
108
+ dashOffset: 0.0,
109
+ dashArray: [4, 2]
110
+ });
111
+ draw.line(this.sector.ellipse.center
112
+ .clone()
113
+ .add(this.sector.ellipse.signedRadiusH(), 0)
114
+ .rotate(this.sector.ellipse.rotation, this.sector.ellipse.center), this.sector.ellipse.axis, "rgba(64,128,192,0.333)", 1.0, {
115
+ dashOffset: 0.0,
116
+ dashArray: [4, 2]
44
117
  });
118
+ } // END drawHandleLines
119
+ /**
120
+ * Destroy this VEllipseHandler which means: all listeners are being removed.
121
+ */
122
+ destroy() {
123
+ this.sector.ellipse.center.listeners.removeDragListener(this._centerHandler);
124
+ this.rotationControlPoint.listeners.removeDragListener(this._rotationHandler);
125
+ this.startAngleControlPoint.listeners.removeDragListener(this._startAngleHandler);
126
+ this.endAngleControlPoint.listeners.removeDragListener(this._endAngleHandler);
45
127
  }
46
128
  }
47
129
  //# sourceMappingURL=VEllipseSectorHelper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VEllipseSectorHelper.js","sourceRoot":"","sources":["../../../ts/utils/helpers/VEllipseSectorHelper.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAKlC,MAAM,OAAO,oBAAoB;IAC/B,YACE,MAAsB,EACtB,sBAA8B,EAC9B,oBAA4B,EAC5B,oBAA4B;QAE5B,MAAM,mBAAmB,GAAS,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;QACxF,MAAM,qBAAqB,GAAS,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;QAC5F,MAAM,mBAAmB,GAAS,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;QAExF,yEAAyE;QACzE,uCAAuC;QACvC,+CAA+C;QAC/C,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,KAAgB,EAAE,EAAE;YACnE,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACpD,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAClD,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,yEAAyE;QACzE,iCAAiC;QACjC,+CAA+C;QAC/C,oBAAoB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,KAAgB,EAAE,EAAE;YAClE,IAAI,WAAW,GAAG,mBAAmB,CAAC,KAAK,EAAE,CAAC;YAC9C,IAAI,KAAK,GAAG,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;YAClD,MAAM,CAAC,OAAO,CAAC,QAAQ,GAAG,WAAW,CAAC;YACtC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACzD,sBAAsB,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC5D,oBAAoB,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEH,yEAAyE;QACzE,oCAAoC;QACpC,+CAA+C;QAC/C,sBAAsB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,KAAgB,EAAE,EAAE;YACpE,MAAM,CAAC,UAAU,GAAG,qBAAqB,CAAC,KAAK,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC9E,CAAC,CAAC,CAAC;QAEH,yEAAyE;QACzE,kCAAkC;QAClC,+CAA+C;QAC/C,oBAAoB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,KAAgB,EAAE,EAAE;YAClE,MAAM,CAAC,QAAQ,GAAG,mBAAmB,CAAC,KAAK,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC1E,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
1
+ {"version":3,"file":"VEllipseSectorHelper.js","sourceRoot":"","sources":["../../../ts/utils/helpers/VEllipseSectorHelper.ts"],"names":[],"mappings":"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"}
@@ -25,7 +25,10 @@
25
25
  * @modified 2022-02-02 Cleared the `toSVGString` function (deprecated). Use `drawutilssvg` instead.
26
26
  * @modified 2023-10-06 Adding the `BezierPath.toPathPoints()` method.
27
27
  * @modified 2023-10-07 Adding the `BezierPath.fromCurve(CubicBezierCurve)` static function.
28
- * @version 2.6.0
28
+ * @modified 2025-04-09 Added the `BezierPath.move` method to match the convention – which just calls `translate`.
29
+ * @modified 2025-04-09 Modified the `BezierPath.translate` method: chaning parameter `Vertex` to more generalized `XYCoords`.
30
+ * @modified 2025-04-14 Class `BezierPath` is now implementing interface `Intersectable`.
31
+ * @version 2.7.0
29
32
  *
30
33
  * @file BezierPath
31
34
  * @public
@@ -34,8 +37,10 @@
34
37
  import { Bounds } from "./Bounds";
35
38
  import { CubicBezierCurve } from "./CubicBezierCurve";
36
39
  import { UIDGenerator } from "./UIDGenerator";
40
+ import { Vector } from "./Vector";
41
+ import { VertTuple } from "./VertTuple";
37
42
  import { Vertex } from "./Vertex";
38
- import { XYCoords, SVGSerializable, UID } from "./interfaces";
43
+ import { XYCoords, SVGSerializable, UID, Intersectable, IBounded } from "./interfaces";
39
44
 
40
45
  /**
41
46
  * @classdesc A BezierPath class.
@@ -50,7 +55,7 @@ import { XYCoords, SVGSerializable, UID } from "./interfaces";
50
55
  * @requires UID
51
56
  * @requires UIDGenerator
52
57
  **/
53
- export class BezierPath implements SVGSerializable {
58
+ export class BezierPath implements IBounded, Intersectable, SVGSerializable {
54
59
  /**
55
60
  * Required to generate proper CSS classes and other class related IDs.
56
61
  **/
@@ -309,13 +314,13 @@ export class BezierPath implements SVGSerializable {
309
314
  * Move the whole bezier path by the given (x,y)-amount.
310
315
  *
311
316
  * @method translate
312
- * @param {Vertex} amount - The amount to be added (amount.x and amount.y)
317
+ * @param {XYCoords} amount - The amount to be added (amount.x and amount.y)
313
318
  * to each vertex of the curve.
314
319
  * @instance
315
320
  * @memberof BezierPath
316
321
  * @return {BezierPath} this for chaining
317
322
  **/
318
- translate(amount: Vertex): BezierPath {
323
+ translate(amount: XYCoords): BezierPath {
319
324
  for (var i = 0; i < this.bezierCurves.length; i++) {
320
325
  var curve = this.bezierCurves[i];
321
326
  curve.getStartPoint().add(amount);
@@ -331,6 +336,20 @@ export class BezierPath implements SVGSerializable {
331
336
  return this;
332
337
  }
333
338
 
339
+ /**
340
+ * Move the whole bezier path by the given (x,y)-amount.
341
+ *
342
+ * @method move
343
+ * @param {XYCoords} amount - The amount to be added (amount.x and amount.y)
344
+ * to each vertex of the curve.
345
+ * @instance
346
+ * @memberof BezierPath
347
+ * @return {BezierPath} this for chaining
348
+ **/
349
+ move(amount: XYCoords): BezierPath {
350
+ return this.translate(amount);
351
+ }
352
+
334
353
  /**
335
354
  * Scale the whole bezier path by the given uniform factor.
336
355
  *
@@ -559,6 +578,38 @@ export class BezierPath implements SVGSerializable {
559
578
  return bCurve.getPerpendicular(relativeU);
560
579
  }
561
580
 
581
+ //--- BEGIN --- Implement interface `Intersectable`
582
+ /**
583
+ * Get all line intersections with this shape.
584
+ *
585
+ * This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.
586
+ *
587
+ * @param {VertTuple} line - The line to find intersections with.
588
+ * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).
589
+ * @returns {Array<Vertex>} - An array of all intersections with the shape's outline.
590
+ */
591
+ lineIntersections(line: VertTuple<any>, inVectorBoundsOnly: boolean = false): Array<Vertex> {
592
+ return this.bezierCurves.reduce((accu: Array<Vertex>, curCurve: CubicBezierCurve) => {
593
+ return accu.concat(curCurve.lineIntersections(line, inVectorBoundsOnly));
594
+ }, []);
595
+ }
596
+
597
+ /**
598
+ * Get all line intersections of this polygon and their tangents along the shape.
599
+ *
600
+ * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.
601
+ *
602
+ * @param line
603
+ * @param lineIntersectionTangents
604
+ * @returns
605
+ */
606
+ lineIntersectionTangents(line: VertTuple<any>, inVectorBoundsOnly: boolean = false): Array<Vector> {
607
+ return this.bezierCurves.reduce((accu: Array<Vector>, curCurve: CubicBezierCurve) => {
608
+ return accu.concat(curCurve.lineIntersectionTangents(line, inVectorBoundsOnly));
609
+ }, []);
610
+ }
611
+ //--- END --- Implement interface `Intersectable`
612
+
562
613
  /**
563
614
  * This is a helper function to locate the curve index for a given
564
615
  * absolute path position u.
@@ -816,6 +867,7 @@ export class BezierPath implements SVGSerializable {
816
867
  neighbourCurve.updateArcLengths();
817
868
  }
818
869
 
870
+ //--- BEGIN --- Implement interface `IBounded`
819
871
  /**
820
872
  * Get the bounds of this Bézier path.
821
873
  *
@@ -837,6 +889,7 @@ export class BezierPath implements SVGSerializable {
837
889
  }
838
890
  return new Bounds(min, max);
839
891
  }
892
+ //--- END --- Implement interface `IBounded`
840
893
 
841
894
  /**
842
895
  * Get n 'equally' distributed vertices along this Bézier path.
package/src/ts/Bounds.ts CHANGED
@@ -9,13 +9,16 @@
9
9
  * @modified 2022-10-09 Added the `fromDimension` function.
10
10
  * @modified 2022-11-28 Added the `clone` method.
11
11
  * @modified 2023-09-29 Added the `randomPoint` method.
12
- * @version 1.7.0
12
+ * @modified 2025-03-23 Added the `getMinDimension` and `getMaxDimension` methods.
13
+ * @modified 2025-04-18 Change parameter type in `Bounds.computeFromVertices` from `Vertex` to more general `XYCoords`.
14
+ * @modified 2025-04-19 Added methods to `Bounds` class: `getNorthPoint`, `getSouthPoint`, `getEastPoint` and `getWestPoint`.
15
+ * @modified 2025-04-26 Added static method `Bounds.computeFromBoundsSet` to calculate containing bounds for a set of bounding boxes.
16
+ * @version 1.8.0
13
17
  **/
14
18
 
15
19
  import { Polygon } from "./Polygon";
16
20
  import { XYCoords, IBounds, XYDimension } from "./interfaces";
17
21
  import { Vertex } from "./Vertex";
18
- import { VertTuple } from "./VertTuple";
19
22
 
20
23
  /**
21
24
  * @classdesc A bounds class with min and max values. Implementing IBounds.
@@ -72,6 +75,55 @@ export class Bounds implements IBounds, XYDimension {
72
75
  this.height = max.y - min.y;
73
76
  }
74
77
 
78
+ /**
79
+ * Get the center point of the north bound.
80
+ *
81
+ * @method getNorthPoint
82
+ * @instance
83
+ * @memberof Bounds
84
+ * @return {Vertex} The "northmost" centered point of this bounding box.
85
+ */
86
+ getNorthPoint() : Vertex {
87
+ return new Vertex(this.min.x + this.width/2.0, this.min.y );
88
+ };
89
+
90
+ /**
91
+ * Get the center point of the south bound.
92
+ *
93
+ * @method getNorthPoint
94
+ * @instance
95
+ * @memberof Bounds
96
+ * @return {Vertex} The "southhmost" centered point of this bounding box.
97
+ */
98
+ getSouthPoint() : Vertex {
99
+ return new Vertex( this.min.x + this.width/2.0, this.max.y );
100
+ };
101
+
102
+ /**
103
+ * Get the center point of the west bound.
104
+ *
105
+ * @method getWestPoint
106
+ * @instance
107
+ * @memberof Bounds
108
+ * @return {Vertex} The "westhmost" centered point of this bounding box.
109
+ */
110
+ getWestPoint() : Vertex {
111
+ return new Vertex( this.min.x, this.min.y + this.height/2.0 );
112
+ };
113
+
114
+ /**
115
+ * Get the center point of the east bound.
116
+ *
117
+ * @method getEastPoint
118
+ * @instance
119
+ * @memberof Bounds
120
+ * @return {Vertex} The "easthmost" centered point of this bounding box.
121
+ */
122
+ getEastPoint() : Vertex {
123
+ return new Vertex( this.max.x, this.min.y + this.height/2.0 );
124
+ };
125
+
126
+
75
127
  /**
76
128
  * Convert this rectangular bounding box to a polygon with four vertices.
77
129
  *
@@ -99,6 +151,24 @@ export class Bounds implements IBounds, XYDimension {
99
151
  return new Vertex(this.min.x + (this.max.x - this.min.x) / 2.0, this.min.y + (this.max.y - this.min.y) / 2);
100
152
  }
101
153
 
154
+ /**
155
+ * Get the minimum of `width` and `height`.
156
+ *
157
+ * @returns {number} The value of Math.min( this.width, this.height )
158
+ */
159
+ getMinDimension(): number {
160
+ return Math.min(this.width, this.height);
161
+ }
162
+
163
+ /**
164
+ * Get the minimum of `width` and `height`.
165
+ *
166
+ * @returns {number} The value of Math.min( this.width, this.height )
167
+ */
168
+ getMaxDimension(): number {
169
+ return Math.max(this.width, this.height);
170
+ }
171
+
102
172
  /**
103
173
  * Generate a random point inside this bounds object. Safe areas at the border to avoid
104
174
  * included.
@@ -156,18 +226,20 @@ export class Bounds implements IBounds, XYDimension {
156
226
  * @static
157
227
  * @method computeFromVertices
158
228
  * @memberof Bounds
159
- * @param {Array<Vertex>} vertices - The set of vertices you want to get the bounding box for.
229
+ * @param {Array<XYCoords>} vertices - The set of vertices you want to get the bounding box for.
160
230
  * @return The minimal Bounds for the given vertices.
161
231
  **/
162
- static computeFromVertices(vertices: Array<Vertex>): Bounds {
163
- if (vertices.length == 0) return new Bounds(new Vertex(0, 0), new Vertex(0, 0));
232
+ static computeFromVertices(vertices: Array<XYCoords>): Bounds {
233
+ if (vertices.length == 0) {
234
+ return new Bounds(new Vertex(0, 0), new Vertex(0, 0));
235
+ }
164
236
 
165
237
  let xMin = vertices[0].x;
166
238
  let xMax = vertices[0].x;
167
239
  let yMin = vertices[0].y;
168
240
  let yMax = vertices[0].y;
169
241
 
170
- let vert: Vertex;
242
+ let vert: XYCoords;
171
243
  for (var i in vertices) {
172
244
  vert = vertices[i];
173
245
  xMin = Math.min(xMin, vert.x);
@@ -178,6 +250,38 @@ export class Bounds implements IBounds, XYDimension {
178
250
  return new Bounds(new Vertex(xMin, yMin), new Vertex(xMax, yMax));
179
251
  }
180
252
 
253
+ /**
254
+ * Compute the minimal bounding box for a given set of existing bounding boxes.
255
+ *
256
+ * An empty vertex array will return an empty bounding box located at (0,0).
257
+ *
258
+ * @static
259
+ * @method computeFromBoundsSet
260
+ * @memberof Bounds
261
+ * @param {Array<IBounds>} boundingBoxes - The set of existing bounding boxes to get the containing bounding box for.
262
+ * @return The minimal Bounds for the given bounds instances.
263
+ **/
264
+ static computeFromBoundsSet(boundingBoxes:Array<IBounds>) : Bounds {
265
+ if (boundingBoxes.length == 0) {
266
+ return new Bounds(new Vertex(0, 0), new Vertex(0, 0));
267
+ }
268
+
269
+ let xMin = boundingBoxes[0].min.x;
270
+ let xMax = boundingBoxes[0].max.x;
271
+ let yMin = boundingBoxes[0].min.y;
272
+ let yMax = boundingBoxes[0].min.y;
273
+
274
+ let bounds: IBounds;
275
+ for (var i in boundingBoxes) {
276
+ bounds = boundingBoxes[i];
277
+ xMin = Math.min(xMin, bounds.min.x);
278
+ xMax = Math.max(xMax, bounds.max.x);
279
+ yMin = Math.min(yMin, bounds.min.y);
280
+ yMax = Math.max(yMax, bounds.min.y);
281
+ }
282
+ return new Bounds(new Vertex(xMin, yMin), new Vertex(xMax, yMax));
283
+ }
284
+
181
285
  /**
182
286
  * Create a new `Bounds` instance just from `width` and `height`, located at (0,0) or the optionally given origin.
183
287
  *
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
  *