plotboilerplate 1.24.0 → 1.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -1
- package/dist/index.esm.js +433 -162
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/dist/plotboilerplate.browser.min.js +1 -1
- package/dist/plotboilerplate.browser.min.js.map +1 -1
- package/dist/plotboilerplate.js +12312 -12041
- package/dist/plotboilerplate.min.js +1 -1
- package/package.json +9 -5
- package/src/cjs/Bounds.d.ts +79 -25
- package/src/cjs/Bounds.js +102 -29
- package/src/cjs/Bounds.js.map +1 -1
- package/src/cjs/CircleSector.d.ts +3 -0
- package/src/cjs/CircleSector.js +28 -1
- package/src/cjs/CircleSector.js.map +1 -1
- package/src/cjs/PlotBoilerplate.d.ts +37 -6
- package/src/cjs/PlotBoilerplate.js +222 -116
- package/src/cjs/PlotBoilerplate.js.map +1 -1
- package/src/cjs/Polygon.d.ts +26 -7
- package/src/cjs/Polygon.js +56 -10
- package/src/cjs/Polygon.js.map +1 -1
- package/src/cjs/Triangle.js +2 -2
- package/src/cjs/Triangle.js.map +1 -1
- package/src/cjs/Vertex.d.ts +15 -3
- package/src/cjs/Vertex.js +18 -1
- package/src/cjs/Vertex.js.map +1 -1
- package/src/cjs/drawutilssvg.d.ts +2 -1
- package/src/cjs/drawutilssvg.js +9 -3
- package/src/cjs/drawutilssvg.js.map +1 -1
- package/src/cjs/interfaces/core.d.ts +28 -0
- package/src/cjs/interfaces/core.js +2 -0
- package/src/cjs/interfaces/core.js.map +1 -1
- package/src/cjs/utils/LissajousFigure.d.ts +34 -0
- package/src/cjs/utils/LissajousFigure.js +100 -0
- package/src/cjs/utils/LissajousFigure.js.map +1 -0
- package/src/cjs/utils/PerlinNoise.d.ts +19 -0
- package/src/cjs/utils/PerlinNoise.js +352 -0
- package/src/cjs/utils/PerlinNoise.js.map +1 -0
- package/src/cjs/utils/SVGPathUtils.d.ts +22 -0
- package/src/cjs/utils/SVGPathUtils.js +45 -0
- package/src/cjs/utils/SVGPathUtils.js.map +1 -0
- package/src/cjs/utils/algorithms/pixelCornersToRoundPaths.d.ts +23 -0
- package/src/cjs/utils/algorithms/pixelCornersToRoundPaths.js +270 -0
- package/src/cjs/utils/algorithms/pixelCornersToRoundPaths.js.map +1 -0
- package/src/cjs/utils/datastructures/Color.d.ts +147 -1
- package/src/cjs/utils/datastructures/Color.js +385 -41
- package/src/cjs/utils/datastructures/Color.js.map +1 -1
- package/src/cjs/utils/datastructures/ColorGradient.d.ts +79 -0
- package/src/cjs/utils/datastructures/ColorGradient.js +171 -0
- package/src/cjs/utils/datastructures/ColorGradient.js.map +1 -0
- package/src/cjs/utils/datastructures/DataGrid2d.d.ts +6 -0
- package/src/cjs/utils/datastructures/DataGrid2dArrayMatrix.d.ts +88 -0
- package/src/cjs/utils/datastructures/DataGrid2dArrayMatrix.js +155 -0
- package/src/cjs/utils/datastructures/DataGrid2dArrayMatrix.js.map +1 -0
- package/src/cjs/utils/datastructures/DataGrid2dListAdapter.d.ts +1 -7
- package/src/cjs/utils/datastructures/DataGrid2dListAdapter.js +3 -3
- package/src/cjs/utils/datastructures/DataGrid2dListAdapter.js.map +1 -1
- package/src/cjs/utils/datastructures/GeometryMesh.d.ts +49 -0
- package/src/cjs/utils/datastructures/GeometryMesh.js +58 -0
- package/src/cjs/utils/datastructures/GeometryMesh.js.map +1 -0
- package/src/cjs/utils/detectDarkMode.js +16 -7
- package/src/cjs/utils/detectDarkMode.js.map +1 -1
- package/src/cjs/utils/dom/components/ColorGradientPicker.d.ts +246 -0
- package/src/cjs/utils/dom/components/ColorGradientPicker.js +667 -0
- package/src/cjs/utils/dom/components/ColorGradientPicker.js.map +1 -0
- package/src/cjs/utils/dom/components/ColorGradientPickerJSX.d.ts +129 -0
- package/src/cjs/utils/dom/components/ColorGradientPickerJSX.js +520 -0
- package/src/cjs/utils/dom/components/ColorGradientPickerJSX.js.map +1 -0
- package/src/cjs/utils/dom/components/ColorGradientSelector.d.ts +118 -0
- package/src/cjs/utils/dom/components/ColorGradientSelector.js +327 -0
- package/src/cjs/utils/dom/components/ColorGradientSelector.js.map +1 -0
- package/src/cjs/utils/dom/components/Test.d.ts +7 -0
- package/src/cjs/utils/dom/components/Test.js +30 -0
- package/src/cjs/utils/dom/components/Test.js.map +1 -0
- package/src/cjs/utils/dom/guiSizeToggler.js +1 -1
- package/src/cjs/utils/dom/guiSizeToggler.js.map +1 -1
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.d.ts +9 -3
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.js +20 -13
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
- package/src/cjs/utils/helpers/CircleHelper.d.ts +10 -1
- package/src/cjs/utils/helpers/CircleHelper.js +13 -2
- package/src/cjs/utils/helpers/CircleHelper.js.map +1 -1
- package/src/cjs/utils/helpers/CircleSectorHelper.d.ts +2 -2
- package/src/cjs/utils/helpers/CircleSectorHelper.js +1 -0
- package/src/cjs/utils/helpers/CircleSectorHelper.js.map +1 -1
- package/src/cjs/utils/helpers/TriangleHelper.d.ts +57 -0
- package/src/cjs/utils/helpers/TriangleHelper.js +83 -0
- package/src/cjs/utils/helpers/TriangleHelper.js.map +1 -0
- package/src/cjs/utils/helpers/VEllipseHelper.d.ts +6 -4
- package/src/cjs/utils/helpers/VEllipseHelper.js +4 -2
- package/src/cjs/utils/helpers/VEllipseHelper.js.map +1 -1
- package/src/cjs/utils/helpers/VEllipseSectorHelper.d.ts +3 -2
- package/src/cjs/utils/helpers/VEllipseSectorHelper.js +1 -0
- package/src/cjs/utils/helpers/VEllipseSectorHelper.js.map +1 -1
- package/src/cjs/utils/parsers/LinearColorGradientParser.d.ts +78 -0
- package/src/cjs/utils/parsers/LinearColorGradientParser.js +224 -0
- package/src/cjs/utils/parsers/LinearColorGradientParser.js.map +1 -0
- package/src/cjs/utils/parsers/svg/types.d.ts +8 -8
- package/src/createDemoDrawables.js +1 -0
- package/src/esm/Bounds.d.ts +79 -25
- package/src/esm/Bounds.js +102 -29
- package/src/esm/Bounds.js.map +1 -1
- package/src/esm/CircleSector.d.ts +3 -0
- package/src/esm/CircleSector.js +28 -1
- package/src/esm/CircleSector.js.map +1 -1
- package/src/esm/PlotBoilerplate.d.ts +37 -6
- package/src/esm/PlotBoilerplate.js +222 -116
- package/src/esm/PlotBoilerplate.js.map +1 -1
- package/src/esm/Polygon.d.ts +26 -7
- package/src/esm/Polygon.js +53 -10
- package/src/esm/Polygon.js.map +1 -1
- package/src/esm/Triangle.js +2 -2
- package/src/esm/Triangle.js.map +1 -1
- package/src/esm/Vertex.d.ts +15 -3
- package/src/esm/Vertex.js +18 -1
- package/src/esm/Vertex.js.map +1 -1
- package/src/esm/drawutilssvg.d.ts +2 -1
- package/src/esm/drawutilssvg.js +9 -3
- package/src/esm/drawutilssvg.js.map +1 -1
- package/src/esm/interfaces/core.d.ts +28 -0
- package/src/esm/interfaces/core.js +2 -0
- package/src/esm/interfaces/core.js.map +1 -1
- package/src/esm/utils/LissajousFigure.d.ts +34 -0
- package/src/esm/utils/LissajousFigure.js +95 -0
- package/src/esm/utils/LissajousFigure.js.map +1 -0
- package/src/esm/utils/PerlinNoise.d.ts +19 -0
- package/src/esm/utils/PerlinNoise.js +346 -0
- package/src/esm/utils/PerlinNoise.js.map +1 -0
- package/src/esm/utils/SVGPathUtils.d.ts +22 -0
- package/src/esm/utils/SVGPathUtils.js +42 -0
- package/src/esm/utils/SVGPathUtils.js.map +1 -0
- package/src/esm/utils/algorithms/pixelCornersToRoundPaths.d.ts +23 -0
- package/src/esm/utils/algorithms/pixelCornersToRoundPaths.js +266 -0
- package/src/esm/utils/algorithms/pixelCornersToRoundPaths.js.map +1 -0
- package/src/esm/utils/datastructures/Color.d.ts +147 -1
- package/src/esm/utils/datastructures/Color.js +386 -42
- package/src/esm/utils/datastructures/Color.js.map +1 -1
- package/src/esm/utils/datastructures/ColorGradient.d.ts +79 -0
- package/src/esm/utils/datastructures/ColorGradient.js +166 -0
- package/src/esm/utils/datastructures/ColorGradient.js.map +1 -0
- package/src/esm/utils/datastructures/DataGrid2d.d.ts +6 -0
- package/src/esm/utils/datastructures/DataGrid2dArrayMatrix.d.ts +88 -0
- package/src/esm/utils/datastructures/DataGrid2dArrayMatrix.js +150 -0
- package/src/esm/utils/datastructures/DataGrid2dArrayMatrix.js.map +1 -0
- package/src/esm/utils/datastructures/DataGrid2dListAdapter.d.ts +1 -7
- package/src/esm/utils/datastructures/DataGrid2dListAdapter.js +3 -3
- package/src/esm/utils/datastructures/DataGrid2dListAdapter.js.map +1 -1
- package/src/esm/utils/datastructures/GeometryMesh.d.ts +49 -0
- package/src/esm/utils/datastructures/GeometryMesh.js +53 -0
- package/src/esm/utils/datastructures/GeometryMesh.js.map +1 -0
- package/src/esm/utils/detectDarkMode.js +16 -7
- package/src/esm/utils/detectDarkMode.js.map +1 -1
- package/src/esm/utils/dom/components/ColorGradientPicker.d.ts +246 -0
- package/src/esm/utils/dom/components/ColorGradientPicker.js +743 -0
- package/src/esm/utils/dom/components/ColorGradientPicker.js.map +1 -0
- package/src/esm/utils/dom/components/ColorGradientPickerJSX.d.ts +129 -0
- package/src/esm/utils/dom/components/ColorGradientPickerJSX.js +582 -0
- package/src/esm/utils/dom/components/ColorGradientPickerJSX.js.map +1 -0
- package/src/esm/utils/dom/components/ColorGradientSelector.d.ts +118 -0
- package/src/esm/utils/dom/components/ColorGradientSelector.js +339 -0
- package/src/esm/utils/dom/components/ColorGradientSelector.js.map +1 -0
- package/src/esm/utils/dom/components/Test.d.ts +7 -0
- package/src/esm/utils/dom/components/Test.js +26 -0
- package/src/esm/utils/dom/components/Test.js.map +1 -0
- package/src/esm/utils/dom/guiSizeToggler.js +1 -1
- package/src/esm/utils/dom/guiSizeToggler.js.map +1 -1
- package/src/esm/utils/helpers/BezierPathInteractionHelper.d.ts +9 -3
- package/src/esm/utils/helpers/BezierPathInteractionHelper.js +20 -13
- package/src/esm/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
- package/src/esm/utils/helpers/CircleHelper.d.ts +10 -1
- package/src/esm/utils/helpers/CircleHelper.js +13 -2
- package/src/esm/utils/helpers/CircleHelper.js.map +1 -1
- package/src/esm/utils/helpers/CircleSectorHelper.d.ts +2 -2
- package/src/esm/utils/helpers/CircleSectorHelper.js +1 -0
- package/src/esm/utils/helpers/CircleSectorHelper.js.map +1 -1
- package/src/esm/utils/helpers/TriangleHelper.d.ts +57 -0
- package/src/esm/utils/helpers/TriangleHelper.js +78 -0
- package/src/esm/utils/helpers/TriangleHelper.js.map +1 -0
- package/src/esm/utils/helpers/VEllipseHelper.d.ts +6 -4
- package/src/esm/utils/helpers/VEllipseHelper.js +4 -2
- package/src/esm/utils/helpers/VEllipseHelper.js.map +1 -1
- package/src/esm/utils/helpers/VEllipseSectorHelper.d.ts +3 -2
- package/src/esm/utils/helpers/VEllipseSectorHelper.js +1 -0
- package/src/esm/utils/helpers/VEllipseSectorHelper.js.map +1 -1
- package/src/esm/utils/parsers/LinearColorGradientParser.d.ts +78 -0
- package/src/esm/utils/parsers/LinearColorGradientParser.js +217 -0
- package/src/esm/utils/parsers/LinearColorGradientParser.js.map +1 -0
- package/src/esm/utils/parsers/svg/types.d.ts +8 -8
- package/src/external.d.ts +9 -0
- package/src/ts/Bounds.ts +107 -22
- package/src/ts/CircleSector.ts +39 -6
- package/src/ts/PlotBoilerplate.ts +233 -105
- package/src/ts/Polygon.ts +68 -14
- package/src/ts/Triangle.ts +2 -2
- package/src/ts/Vertex.ts +21 -3
- package/src/ts/drawutilssvg.ts +8 -3
- package/src/ts/interfaces/core.ts +31 -0
- package/src/ts/utils/LissajousFigure.ts +110 -0
- package/src/ts/utils/PerlinNoise.ts +368 -0
- package/src/ts/utils/SVGPathUtils.ts +55 -0
- package/src/ts/utils/algorithms/pixelCornersToRoundPaths.ts +379 -0
- package/src/ts/utils/datastructures/Color.ts +423 -44
- package/src/ts/utils/datastructures/ColorGradient.ts +196 -0
- package/src/ts/utils/datastructures/DataGrid2d.ts +7 -0
- package/src/ts/utils/datastructures/DataGrid2dArrayMatrix.ts +182 -0
- package/src/ts/utils/datastructures/DataGrid2dListAdapter.ts +4 -11
- package/src/ts/utils/datastructures/GeometryMesh.ts +79 -0
- package/src/ts/utils/detectDarkMode.ts +17 -8
- package/src/ts/utils/dom/components/ColorGradientPicker.tsx +889 -0
- package/src/ts/utils/dom/components/ColorGradientSelector.tsx +452 -0
- package/src/ts/utils/dom/components/Test.tsx +44 -0
- package/src/ts/utils/dom/components/_ColorGradientPicker_raw.ts_ +392 -0
- package/src/ts/utils/dom/guiSizeToggler.ts +1 -1
- package/src/ts/utils/helpers/BezierPathInteractionHelper.ts +25 -15
- package/src/ts/utils/helpers/CircleHelper.ts +17 -3
- package/src/ts/utils/helpers/CircleSectorHelper.ts +4 -2
- package/src/ts/utils/helpers/TriangleHelper.ts +102 -0
- package/src/ts/utils/helpers/VEllipseHelper.ts +6 -4
- package/src/ts/utils/helpers/VEllipseSectorHelper.ts +3 -2
- package/src/ts/utils/parsers/LinearColorGradientParser.ts +297 -0
- package/src/ts/utils/parsers/svg/types.ts +8 -8
|
@@ -86,8 +86,13 @@
|
|
|
86
86
|
* @modified 2024-07-08 Adding `PlotBoilerplate.getGUI()` to retrieve the GUI instance.
|
|
87
87
|
* @modified 2024-08-25 Extending main class `PlotBoilerplate` optional param `isBackdropFiltersEnabled`.
|
|
88
88
|
* @modified 2024-12-02 Adding the `triggerRedraw` to the `removeAll` method.
|
|
89
|
+
* @modified 2025-05-07 Changing the return type of `removeVertex` from `void` to `boolean`.
|
|
90
|
+
* @modified 2025-05-07 Handling content changes now with `contentChangeListeners`.
|
|
91
|
+
* @modified 2025-05-07 Added `PlogBoilerplate.addContentChangeListener` and `.removeContentChangeListener`.
|
|
92
|
+
* @modified 2025-05-07 Moving full vectors now by default when vector point a is moved.
|
|
93
|
+
* @modified 2025-05-20 Applying `lineWith` parameter in the draw routine for vectors (had been missing).
|
|
89
94
|
*
|
|
90
|
-
* @version 1.
|
|
95
|
+
* @version 1.21.1
|
|
91
96
|
*
|
|
92
97
|
* @file PlotBoilerplate
|
|
93
98
|
* @fileoverview The main class.
|
|
@@ -131,7 +136,8 @@ import {
|
|
|
131
136
|
XYCoords,
|
|
132
137
|
XYDimension,
|
|
133
138
|
DatGuiProps, // DEPRECATED. Please do not use any more.
|
|
134
|
-
LilGuiProps
|
|
139
|
+
LilGuiProps,
|
|
140
|
+
PBContentChangeListener
|
|
135
141
|
} from "./interfaces";
|
|
136
142
|
import { PBText } from "./PBText";
|
|
137
143
|
import { AlloyFingerOptions } from "alloyfinger-typescript/src/cjs/alloy_finger";
|
|
@@ -313,6 +319,11 @@ export class PlotBoilerplate {
|
|
|
313
319
|
*/
|
|
314
320
|
hooks: IHooks;
|
|
315
321
|
|
|
322
|
+
/**
|
|
323
|
+
* A list of content change listeners.
|
|
324
|
+
*/
|
|
325
|
+
contentChangeListeners: Array<PBContentChangeListener> = [];
|
|
326
|
+
|
|
316
327
|
/**
|
|
317
328
|
* @member {KeyHandler|undefined}
|
|
318
329
|
* @memberof PlotBoilerplate
|
|
@@ -804,6 +815,55 @@ export class PlotBoilerplate {
|
|
|
804
815
|
}
|
|
805
816
|
}
|
|
806
817
|
|
|
818
|
+
/**
|
|
819
|
+
* Adds a new content change listener to this instance. Adding duplicates is not possible.
|
|
820
|
+
*
|
|
821
|
+
* @param {PBContentChangeListener} listener - The listenre to add.
|
|
822
|
+
* @method addContentChangeListener
|
|
823
|
+
* @instance
|
|
824
|
+
* @memberof PlotBoilerplate
|
|
825
|
+
* @returns {void}
|
|
826
|
+
*/
|
|
827
|
+
addContentChangeListener(listener: PBContentChangeListener) {
|
|
828
|
+
for (var i in this.contentChangeListeners) {
|
|
829
|
+
if (this.contentChangeListeners[i] === listener) {
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
this.contentChangeListeners.push(listener);
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
/**
|
|
837
|
+
* Removes an existing content change listener from this instance.
|
|
838
|
+
*
|
|
839
|
+
* @param {PBContentChangeListener} listener - The listenre to add.
|
|
840
|
+
* @method removeContentChangeListener
|
|
841
|
+
* @instance
|
|
842
|
+
* @memberof PlotBoilerplate
|
|
843
|
+
* @returns {void}
|
|
844
|
+
*/
|
|
845
|
+
removeContentChangeListener(listener: PBContentChangeListener) {
|
|
846
|
+
for (var i = 0; i < this.contentChangeListeners.length; i++) {
|
|
847
|
+
if (this.contentChangeListeners[i] === listener) {
|
|
848
|
+
this.contentChangeListeners.splice(i, 1);
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
private _fireContentChanged(addedDrawables: Drawable[], removedDrawables: Drawable[]): void {
|
|
855
|
+
for (var i in this.contentChangeListeners) {
|
|
856
|
+
const listener = this.contentChangeListeners[i];
|
|
857
|
+
if (listener && typeof listener === "function") {
|
|
858
|
+
listener({
|
|
859
|
+
type: addedDrawables.length > 0 ? "DRAWABLES_ADDED" : "DRAWABLES_REMOVED",
|
|
860
|
+
addedDrawables: addedDrawables,
|
|
861
|
+
removedDrawables: removedDrawables
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
|
|
807
867
|
/**
|
|
808
868
|
* Add a drawable object.<br>
|
|
809
869
|
* <br>
|
|
@@ -828,87 +888,115 @@ export class PlotBoilerplate {
|
|
|
828
888
|
* @memberof PlotBoilerplate
|
|
829
889
|
* @return {void}
|
|
830
890
|
**/
|
|
831
|
-
add(drawable: Drawable | Array<Drawable>, redraw?: boolean) {
|
|
891
|
+
add(drawable: Drawable | Array<Drawable>, redraw?: boolean, doNotFireEvent?: boolean) {
|
|
832
892
|
if (Array.isArray(drawable)) {
|
|
833
893
|
const arr: Array<Drawable> = drawable as Array<Drawable>;
|
|
834
894
|
for (var i = 0; i < arr.length; i++) {
|
|
835
|
-
this.add(arr[i], false);
|
|
836
|
-
}
|
|
837
|
-
} else if (drawable instanceof Vertex) {
|
|
838
|
-
this.drawables.push(drawable);
|
|
839
|
-
this.vertices.push(drawable);
|
|
840
|
-
} else if (drawable instanceof Line) {
|
|
841
|
-
// Add some lines
|
|
842
|
-
this.drawables.push(drawable);
|
|
843
|
-
this.vertices.push(drawable.a);
|
|
844
|
-
this.vertices.push(drawable.b);
|
|
845
|
-
} else if (drawable instanceof Vector) {
|
|
846
|
-
this.drawables.push(drawable);
|
|
847
|
-
this.vertices.push(drawable.a);
|
|
848
|
-
this.vertices.push(drawable.b);
|
|
849
|
-
} else if (drawable instanceof VEllipse) {
|
|
850
|
-
this.vertices.push(drawable.center);
|
|
851
|
-
this.vertices.push(drawable.axis);
|
|
852
|
-
this.drawables.push(drawable);
|
|
853
|
-
drawable.center.listeners.addDragListener((event: VertEvent) => {
|
|
854
|
-
drawable.axis.add(event.params.dragAmount);
|
|
855
|
-
});
|
|
856
|
-
} else if (drawable instanceof VEllipseSector) {
|
|
857
|
-
this.vertices.push(drawable.ellipse.center);
|
|
858
|
-
this.vertices.push(drawable.ellipse.axis);
|
|
859
|
-
this.drawables.push(drawable);
|
|
860
|
-
drawable.ellipse.center.listeners.addDragListener((event: VertEvent) => {
|
|
861
|
-
drawable.ellipse.axis.add(event.params.dragAmount);
|
|
862
|
-
});
|
|
863
|
-
} else if (drawable instanceof Circle) {
|
|
864
|
-
this.vertices.push(drawable.center);
|
|
865
|
-
this.drawables.push(drawable);
|
|
866
|
-
} else if (drawable instanceof CircleSector) {
|
|
867
|
-
this.vertices.push(drawable.circle.center);
|
|
868
|
-
this.drawables.push(drawable);
|
|
869
|
-
} else if (drawable instanceof Polygon) {
|
|
870
|
-
this.drawables.push(drawable);
|
|
871
|
-
for (var i = 0; i < drawable.vertices.length; i++) {
|
|
872
|
-
this.vertices.push(drawable.vertices[i]);
|
|
895
|
+
this.add(arr[i], false, doNotFireEvent);
|
|
873
896
|
}
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
897
|
+
// !doNotFireEvent && this._fireContentChanged(arr, []);
|
|
898
|
+
} else {
|
|
899
|
+
const addedDrawables: Array<Drawable> = [drawable];
|
|
900
|
+
if (drawable instanceof Vertex) {
|
|
901
|
+
this.drawables.push(drawable);
|
|
902
|
+
this.vertices.push(drawable);
|
|
903
|
+
} else if (drawable instanceof Line) {
|
|
904
|
+
// Add some lines
|
|
905
|
+
this.drawables.push(drawable);
|
|
906
|
+
this.vertices.push(drawable.a);
|
|
907
|
+
this.vertices.push(drawable.b);
|
|
908
|
+
addedDrawables.push(drawable.a, drawable.b);
|
|
909
|
+
} else if (drawable instanceof Vector) {
|
|
910
|
+
this.drawables.push(drawable);
|
|
911
|
+
this.vertices.push(drawable.a);
|
|
912
|
+
this.vertices.push(drawable.b);
|
|
913
|
+
addedDrawables.push(drawable.a, drawable.b);
|
|
914
|
+
drawable.a.listeners.addDragListener((event: VertEvent) => {
|
|
915
|
+
drawable.b.add(event.params.dragAmount);
|
|
916
|
+
});
|
|
917
|
+
} else if (drawable instanceof VEllipse) {
|
|
918
|
+
this.vertices.push(drawable.center);
|
|
919
|
+
this.vertices.push(drawable.axis);
|
|
920
|
+
addedDrawables.push(drawable.center, drawable.axis);
|
|
921
|
+
this.drawables.push(drawable);
|
|
922
|
+
drawable.center.listeners.addDragListener((event: VertEvent) => {
|
|
923
|
+
drawable.axis.add(event.params.dragAmount);
|
|
924
|
+
});
|
|
925
|
+
} else if (drawable instanceof VEllipseSector) {
|
|
926
|
+
this.vertices.push(drawable.ellipse.center);
|
|
927
|
+
this.vertices.push(drawable.ellipse.axis);
|
|
928
|
+
addedDrawables.push(drawable.ellipse.center, drawable.ellipse.axis);
|
|
929
|
+
|
|
930
|
+
this.drawables.push(drawable);
|
|
931
|
+
drawable.ellipse.center.listeners.addDragListener((event: VertEvent) => {
|
|
932
|
+
drawable.ellipse.axis.add(event.params.dragAmount);
|
|
933
|
+
});
|
|
934
|
+
} else if (drawable instanceof Circle) {
|
|
935
|
+
this.vertices.push(drawable.center);
|
|
936
|
+
addedDrawables.push(drawable.center);
|
|
937
|
+
this.drawables.push(drawable);
|
|
938
|
+
} else if (drawable instanceof CircleSector) {
|
|
939
|
+
this.vertices.push(drawable.circle.center);
|
|
940
|
+
addedDrawables.push(drawable.circle.center);
|
|
941
|
+
this.drawables.push(drawable);
|
|
942
|
+
} else if (drawable instanceof Polygon) {
|
|
943
|
+
this.drawables.push(drawable);
|
|
944
|
+
for (var i = 0; i < drawable.vertices.length; i++) {
|
|
945
|
+
this.vertices.push(drawable.vertices[i]);
|
|
946
|
+
addedDrawables.push(drawable.vertices[i]);
|
|
885
947
|
}
|
|
886
|
-
|
|
887
|
-
this.
|
|
888
|
-
this.vertices.push(
|
|
889
|
-
|
|
890
|
-
|
|
948
|
+
} else if (drawable instanceof Triangle) {
|
|
949
|
+
this.drawables.push(drawable);
|
|
950
|
+
this.vertices.push(drawable.a);
|
|
951
|
+
this.vertices.push(drawable.b);
|
|
952
|
+
this.vertices.push(drawable.c);
|
|
953
|
+
addedDrawables.push(drawable.a, drawable.b, drawable.c);
|
|
954
|
+
} else if (drawable instanceof BezierPath) {
|
|
955
|
+
this.drawables.push(drawable);
|
|
956
|
+
const bezierPath: BezierPath = drawable as BezierPath;
|
|
957
|
+
for (var i = 0; i < bezierPath.bezierCurves.length; i++) {
|
|
958
|
+
if (!drawable.adjustCircular && i == 0) {
|
|
959
|
+
this.vertices.push(bezierPath.bezierCurves[i].startPoint);
|
|
960
|
+
addedDrawables.push(bezierPath.bezierCurves[i].startPoint);
|
|
961
|
+
}
|
|
962
|
+
this.vertices.push(bezierPath.bezierCurves[i].endPoint);
|
|
963
|
+
this.vertices.push(bezierPath.bezierCurves[i].startControlPoint);
|
|
964
|
+
this.vertices.push(bezierPath.bezierCurves[i].endControlPoint);
|
|
965
|
+
addedDrawables.push(
|
|
966
|
+
bezierPath.bezierCurves[i].endPoint,
|
|
967
|
+
bezierPath.bezierCurves[i].startControlPoint,
|
|
968
|
+
bezierPath.bezierCurves[i].endControlPoint
|
|
969
|
+
);
|
|
970
|
+
bezierPath.bezierCurves[i].startControlPoint.attr.selectable = false;
|
|
971
|
+
bezierPath.bezierCurves[i].endControlPoint.attr.selectable = false;
|
|
972
|
+
}
|
|
973
|
+
PlotBoilerplate.utils.enableBezierPathAutoAdjust(drawable);
|
|
974
|
+
} else if (drawable instanceof PBImage) {
|
|
975
|
+
this.vertices.push(drawable.upperLeft);
|
|
976
|
+
this.vertices.push(drawable.lowerRight);
|
|
977
|
+
addedDrawables.push(drawable.upperLeft, drawable.lowerRight);
|
|
978
|
+
this.drawables.push(drawable);
|
|
979
|
+
// Todo: think about a IDragEvent interface
|
|
980
|
+
drawable.upperLeft.listeners.addDragListener((e: VertEvent) => {
|
|
981
|
+
drawable.lowerRight.add(e.params.dragAmount);
|
|
982
|
+
});
|
|
983
|
+
drawable.lowerRight.attr.selectable = false;
|
|
984
|
+
} else if (drawable instanceof PBText) {
|
|
985
|
+
this.vertices.push(drawable.anchor);
|
|
986
|
+
addedDrawables.push(drawable.anchor);
|
|
987
|
+
this.drawables.push(drawable);
|
|
988
|
+
drawable.anchor.attr.selectable = false;
|
|
989
|
+
} else {
|
|
990
|
+
throw "Cannot add drawable of unrecognized type: " + typeof drawable + ".";
|
|
891
991
|
}
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
this.vertices.push(drawable.upperLeft);
|
|
895
|
-
this.vertices.push(drawable.lowerRight);
|
|
896
|
-
this.drawables.push(drawable);
|
|
897
|
-
// Todo: think about a IDragEvent interface
|
|
898
|
-
drawable.upperLeft.listeners.addDragListener((e: VertEvent) => {
|
|
899
|
-
drawable.lowerRight.add(e.params.dragAmount);
|
|
900
|
-
});
|
|
901
|
-
drawable.lowerRight.attr.selectable = false;
|
|
902
|
-
} else if (drawable instanceof PBText) {
|
|
903
|
-
this.vertices.push(drawable.anchor);
|
|
904
|
-
this.drawables.push(drawable);
|
|
905
|
-
drawable.anchor.attr.selectable = false;
|
|
906
|
-
} else {
|
|
907
|
-
throw "Cannot add drawable of unrecognized type: " + typeof drawable + ".";
|
|
992
|
+
|
|
993
|
+
!doNotFireEvent && this._fireContentChanged(addedDrawables, []);
|
|
908
994
|
}
|
|
909
995
|
|
|
910
996
|
// This is a workaround for backwards compatibility when the 'redraw' param was not yet present.
|
|
911
|
-
if (redraw || typeof redraw == "undefined")
|
|
997
|
+
if (redraw || typeof redraw == "undefined") {
|
|
998
|
+
this.redraw();
|
|
999
|
+
}
|
|
912
1000
|
}
|
|
913
1001
|
|
|
914
1002
|
/**
|
|
@@ -929,79 +1017,114 @@ export class PlotBoilerplate {
|
|
|
929
1017
|
*
|
|
930
1018
|
* @param {Drawable|Array<Drawable>} drawable - The drawable (of one of the allowed class instance) to remove.
|
|
931
1019
|
* @param {boolean} [redraw=false]
|
|
1020
|
+
* @param {removeWidth}
|
|
932
1021
|
* @method remove
|
|
933
1022
|
* @instance
|
|
934
1023
|
* @memberof PlotBoilerplate
|
|
935
1024
|
* @return {void}
|
|
936
1025
|
**/
|
|
937
|
-
remove(
|
|
1026
|
+
remove(
|
|
1027
|
+
drawable: Drawable | Array<Drawable>,
|
|
1028
|
+
redraw?: boolean,
|
|
1029
|
+
removeWithVertices?: boolean,
|
|
1030
|
+
doNotFireEvent?: boolean
|
|
1031
|
+
): boolean {
|
|
938
1032
|
if (Array.isArray(drawable)) {
|
|
1033
|
+
const removedDrawables: Array<Drawable> = [];
|
|
939
1034
|
for (var i = 0; i < drawable.length; i++) {
|
|
940
|
-
this.remove(drawable[i], false, removeWithVertices)
|
|
1035
|
+
if (this.remove(drawable[i], false, removeWithVertices, true)) {
|
|
1036
|
+
removedDrawables.push(drawable[i]);
|
|
1037
|
+
}
|
|
941
1038
|
}
|
|
942
1039
|
if (redraw) {
|
|
943
1040
|
this.redraw();
|
|
944
1041
|
}
|
|
945
|
-
|
|
1042
|
+
!doNotFireEvent && this._fireContentChanged([], removedDrawables);
|
|
1043
|
+
return removedDrawables.length > 0;
|
|
946
1044
|
}
|
|
947
1045
|
if (drawable instanceof Vertex) {
|
|
948
|
-
this.removeVertex(drawable, false);
|
|
1046
|
+
const wasRemoved: boolean = this.removeVertex(drawable, false, false);
|
|
949
1047
|
if (redraw) {
|
|
950
1048
|
this.redraw();
|
|
951
1049
|
}
|
|
1050
|
+
!doNotFireEvent && this._fireContentChanged([], [drawable]);
|
|
1051
|
+
return wasRemoved;
|
|
952
1052
|
}
|
|
1053
|
+
let wasRemoved: boolean = false;
|
|
1054
|
+
const removedDrawables: Array<Drawable> = [];
|
|
953
1055
|
for (var i = 0; i < this.drawables.length; i++) {
|
|
954
1056
|
if (this.drawables[i] === drawable || this.drawables[i].uid === drawable.uid) {
|
|
955
1057
|
this.drawables.splice(i, 1);
|
|
1058
|
+
removedDrawables.push(drawable);
|
|
956
1059
|
|
|
957
1060
|
if (removeWithVertices) {
|
|
958
1061
|
// Check if some listeners need to be removed
|
|
959
1062
|
if (drawable instanceof Line) {
|
|
960
1063
|
// Add some lines
|
|
961
|
-
this.removeVertex(drawable.a, false);
|
|
962
|
-
this.removeVertex(drawable.b, false);
|
|
1064
|
+
this.removeVertex(drawable.a, false, true);
|
|
1065
|
+
this.removeVertex(drawable.b, false, true);
|
|
1066
|
+
removedDrawables.push(drawable.a, drawable.b);
|
|
963
1067
|
} else if (drawable instanceof Vector) {
|
|
964
|
-
this.removeVertex(drawable.a, false);
|
|
965
|
-
this.removeVertex(drawable.b, false);
|
|
1068
|
+
this.removeVertex(drawable.a, false, true);
|
|
1069
|
+
this.removeVertex(drawable.b, false, true);
|
|
1070
|
+
removedDrawables.push(drawable.a, drawable.b);
|
|
966
1071
|
} else if (drawable instanceof VEllipse) {
|
|
967
|
-
this.removeVertex(drawable.center, false);
|
|
968
|
-
this.removeVertex(drawable.axis, false);
|
|
1072
|
+
this.removeVertex(drawable.center, false, true);
|
|
1073
|
+
this.removeVertex(drawable.axis, false, true);
|
|
1074
|
+
removedDrawables.push(drawable.center, drawable.axis);
|
|
969
1075
|
} else if (drawable instanceof VEllipseSector) {
|
|
970
|
-
this.removeVertex(drawable.ellipse.center);
|
|
971
|
-
this.removeVertex(drawable.ellipse.axis);
|
|
1076
|
+
this.removeVertex(drawable.ellipse.center, false, true);
|
|
1077
|
+
this.removeVertex(drawable.ellipse.axis, false, true);
|
|
1078
|
+
removedDrawables.push(drawable.ellipse.center, drawable.ellipse.axis);
|
|
972
1079
|
} else if (drawable instanceof Circle) {
|
|
973
|
-
this.removeVertex(drawable.center, false);
|
|
1080
|
+
this.removeVertex(drawable.center, false, true);
|
|
974
1081
|
} else if (drawable instanceof CircleSector) {
|
|
975
|
-
this.removeVertex(drawable.circle.center, false);
|
|
1082
|
+
this.removeVertex(drawable.circle.center, false, true);
|
|
1083
|
+
removedDrawables.push(drawable.circle.center);
|
|
976
1084
|
} else if (drawable instanceof Polygon) {
|
|
977
1085
|
// for( var i in drawable.vertices )
|
|
978
|
-
for (var i = 0; i < drawable.vertices.length; i++)
|
|
1086
|
+
for (var i = 0; i < drawable.vertices.length; i++) {
|
|
1087
|
+
this.removeVertex(drawable.vertices[i], false, true);
|
|
1088
|
+
removedDrawables.push(drawable.vertices[i]);
|
|
1089
|
+
}
|
|
979
1090
|
} else if (drawable instanceof Triangle) {
|
|
980
|
-
this.removeVertex(drawable.a, false);
|
|
981
|
-
this.removeVertex(drawable.b, false);
|
|
982
|
-
this.removeVertex(drawable.c, false);
|
|
1091
|
+
this.removeVertex(drawable.a, false, true);
|
|
1092
|
+
this.removeVertex(drawable.b, false, true);
|
|
1093
|
+
this.removeVertex(drawable.c, false, true);
|
|
1094
|
+
removedDrawables.push(drawable.a, drawable.b, drawable.c);
|
|
983
1095
|
} else if (drawable instanceof BezierPath) {
|
|
984
1096
|
for (var i = 0; i < drawable.bezierCurves.length; i++) {
|
|
985
|
-
this.removeVertex(drawable.bezierCurves[i].startPoint, false);
|
|
986
|
-
this.removeVertex(drawable.bezierCurves[i].startControlPoint, false);
|
|
987
|
-
this.removeVertex(drawable.bezierCurves[i].endControlPoint, false);
|
|
1097
|
+
this.removeVertex(drawable.bezierCurves[i].startPoint, false, true);
|
|
1098
|
+
this.removeVertex(drawable.bezierCurves[i].startControlPoint, false, true);
|
|
1099
|
+
this.removeVertex(drawable.bezierCurves[i].endControlPoint, false, true);
|
|
1100
|
+
removedDrawables.push(
|
|
1101
|
+
drawable.bezierCurves[i].startPoint,
|
|
1102
|
+
drawable.bezierCurves[i].startControlPoint,
|
|
1103
|
+
drawable.bezierCurves[i].endControlPoint
|
|
1104
|
+
);
|
|
988
1105
|
if (i + 1 == drawable.bezierCurves.length) {
|
|
989
|
-
this.removeVertex(drawable.bezierCurves[i].endPoint, false);
|
|
1106
|
+
this.removeVertex(drawable.bezierCurves[i].endPoint, false, true);
|
|
1107
|
+
removedDrawables.push(drawable.bezierCurves[i].endPoint);
|
|
990
1108
|
}
|
|
991
1109
|
}
|
|
992
1110
|
} else if (drawable instanceof PBImage) {
|
|
993
|
-
this.removeVertex(drawable.upperLeft, false);
|
|
994
|
-
this.removeVertex(drawable.lowerRight, false);
|
|
1111
|
+
this.removeVertex(drawable.upperLeft, false, true);
|
|
1112
|
+
this.removeVertex(drawable.lowerRight, false, true);
|
|
1113
|
+
removedDrawables.push(drawable.upperLeft, drawable.lowerRight);
|
|
995
1114
|
} else if (drawable instanceof PBText) {
|
|
996
|
-
this.removeVertex(drawable.anchor, false);
|
|
1115
|
+
this.removeVertex(drawable.anchor, false, true);
|
|
1116
|
+
removedDrawables.push(drawable.anchor);
|
|
997
1117
|
}
|
|
998
1118
|
} // END removeWithVertices
|
|
999
1119
|
|
|
1000
1120
|
if (redraw) {
|
|
1001
1121
|
this.redraw();
|
|
1002
1122
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
1123
|
+
!doNotFireEvent && this._fireContentChanged([], removedDrawables);
|
|
1124
|
+
wasRemoved = true;
|
|
1125
|
+
} // END if
|
|
1126
|
+
} // END for
|
|
1127
|
+
return wasRemoved;
|
|
1005
1128
|
}
|
|
1006
1129
|
|
|
1007
1130
|
/**
|
|
@@ -1012,18 +1135,20 @@ export class PlotBoilerplate {
|
|
|
1012
1135
|
* @method removeVertex
|
|
1013
1136
|
* @instance
|
|
1014
1137
|
* @memberof PlotBoilerplate
|
|
1015
|
-
* @return {
|
|
1138
|
+
* @return {boolean}
|
|
1016
1139
|
**/
|
|
1017
|
-
removeVertex(vert: Vertex, redraw?: boolean):
|
|
1140
|
+
removeVertex(vert: Vertex, redraw?: boolean, doNotFireEvent?: boolean): boolean {
|
|
1018
1141
|
for (var i = 0; i < this.vertices.length; i++) {
|
|
1019
1142
|
if (this.vertices[i] === vert) {
|
|
1020
1143
|
this.vertices.splice(i, 1);
|
|
1021
1144
|
if (redraw) {
|
|
1022
1145
|
this.redraw();
|
|
1023
1146
|
}
|
|
1024
|
-
|
|
1147
|
+
!doNotFireEvent && this._fireContentChanged([], [vert]);
|
|
1148
|
+
return true;
|
|
1025
1149
|
}
|
|
1026
1150
|
}
|
|
1151
|
+
return false;
|
|
1027
1152
|
}
|
|
1028
1153
|
|
|
1029
1154
|
/**
|
|
@@ -1039,13 +1164,16 @@ export class PlotBoilerplate {
|
|
|
1039
1164
|
* @return {void}
|
|
1040
1165
|
*/
|
|
1041
1166
|
removeAll(keepVertices?: boolean, triggerRedraw?: boolean) {
|
|
1167
|
+
let removedDrawables: Array<Drawable> = this.drawables;
|
|
1042
1168
|
this.drawables = [];
|
|
1043
1169
|
if (!Boolean(keepVertices)) {
|
|
1170
|
+
removedDrawables = removedDrawables.concat(this.vertices);
|
|
1044
1171
|
this.vertices = [];
|
|
1045
1172
|
}
|
|
1046
1173
|
if (triggerRedraw || typeof triggerRedraw === "undefined") {
|
|
1047
1174
|
this.redraw();
|
|
1048
1175
|
}
|
|
1176
|
+
removedDrawables.length > 0 && this._fireContentChanged([], removedDrawables);
|
|
1049
1177
|
}
|
|
1050
1178
|
|
|
1051
1179
|
/**
|
|
@@ -1365,7 +1493,7 @@ export class PlotBoilerplate {
|
|
|
1365
1493
|
if (!this.drawConfig.drawHandlePoints || !d.a.attr.selectable) d.a.attr.renderTime = renderTime;
|
|
1366
1494
|
if (!this.drawConfig.drawHandlePoints || !d.b.attr.selectable) d.b.attr.renderTime = renderTime;
|
|
1367
1495
|
} else if (d instanceof Vector) {
|
|
1368
|
-
draw.arrow(d.a, d.b, this.drawConfig.vector.color);
|
|
1496
|
+
draw.arrow(d.a, d.b, this.drawConfig.vector.color, this.drawConfig.vector.lineWidth);
|
|
1369
1497
|
if (this.drawConfig.drawHandlePoints && d.b.attr.selectable && d.b.attr.visible) {
|
|
1370
1498
|
draw.setCurrentId(`${d.uid}_h0`);
|
|
1371
1499
|
draw.setCurrentClassName(`${d.className}-handle`);
|
package/src/ts/Polygon.ts
CHANGED
|
@@ -36,7 +36,9 @@
|
|
|
36
36
|
* @modified 2025-03-28 Added the `Polygon.lineIntersectionTangents` method.
|
|
37
37
|
* @modified 2025-04-09 Added the `Polygon.getCentroid` method.
|
|
38
38
|
* @modified 2025-05-16 Class `Polygon` now implements `IBounded`.
|
|
39
|
-
* @
|
|
39
|
+
* @modified 2025-05-20 Tweaking `Polygon.getInnerAngleAt` and `Polygo.isAngleAcute` to handle indices out of array bounds as well.
|
|
40
|
+
* @modified 2025-06-07 Adding `Polygon.closestLineIntersectionIndex` to determine line intersections plus detected edge index.
|
|
41
|
+
* @version 1.16.0
|
|
40
42
|
*
|
|
41
43
|
* @file Polygon
|
|
42
44
|
* @public
|
|
@@ -51,7 +53,7 @@ import { Vector } from "./Vector";
|
|
|
51
53
|
import { VertTuple } from "./VertTuple";
|
|
52
54
|
import { Vertex } from "./Vertex";
|
|
53
55
|
import { geomutils } from "./geomutils";
|
|
54
|
-
import { XYCoords, SVGSerializable, UID, Intersectable, IBounded } from "./interfaces";
|
|
56
|
+
import { XYCoords, SVGSerializable, UID, Intersectable, IBounded, PolygonIntersectionTuple } from "./interfaces";
|
|
55
57
|
|
|
56
58
|
/**
|
|
57
59
|
* @classdesc A polygon class. Any polygon consists of an array of vertices; polygons can be open or closed.
|
|
@@ -195,7 +197,7 @@ export class Polygon implements IBounded, Intersectable, SVGSerializable {
|
|
|
195
197
|
* @returns {boolean} `true` is angle is acute, `false` is obtuse.
|
|
196
198
|
*/
|
|
197
199
|
getInnerAngleAt(vertIndex: number): number {
|
|
198
|
-
const p2: Vertex = this.vertices[vertIndex];
|
|
200
|
+
const p2: Vertex = this.vertices[vertIndex % this.vertices.length];
|
|
199
201
|
const p1: Vertex = this.vertices[(vertIndex + this.vertices.length - 1) % this.vertices.length].clone();
|
|
200
202
|
const p3: Vertex = this.vertices[(vertIndex + 1) % this.vertices.length].clone();
|
|
201
203
|
|
|
@@ -235,7 +237,7 @@ export class Polygon implements IBounded, Intersectable, SVGSerializable {
|
|
|
235
237
|
*/
|
|
236
238
|
isAngleAcute(vertIndex: number): boolean {
|
|
237
239
|
const A: Vertex = this.vertices[(vertIndex + this.vertices.length - 1) % this.vertices.length].clone();
|
|
238
|
-
const B: Vertex = this.vertices[vertIndex];
|
|
240
|
+
const B: Vertex = this.vertices[vertIndex % this.vertices.length];
|
|
239
241
|
const C: Vertex = this.vertices[(vertIndex + 1) % this.vertices.length].clone();
|
|
240
242
|
|
|
241
243
|
// Find local winding number for triangle A B C
|
|
@@ -307,7 +309,9 @@ export class Polygon implements IBounded, Intersectable, SVGSerializable {
|
|
|
307
309
|
yj: number = this.vertices[j].y;
|
|
308
310
|
|
|
309
311
|
var intersect: boolean = yi > vert.y != yj > vert.y && vert.x < ((xj - xi) * (vert.y - yi)) / (yj - yi) + xi;
|
|
310
|
-
if (intersect)
|
|
312
|
+
if (intersect) {
|
|
313
|
+
inside = !inside;
|
|
314
|
+
}
|
|
311
315
|
}
|
|
312
316
|
return inside;
|
|
313
317
|
}
|
|
@@ -526,7 +530,7 @@ export class Polygon implements IBounded, Intersectable, SVGSerializable {
|
|
|
526
530
|
// Find the intersections of all lines inside the edge bounds
|
|
527
531
|
return Polygon.utils
|
|
528
532
|
.locateLineIntersecion(line, this.vertices, this.isOpen, inVectorBoundsOnly)
|
|
529
|
-
.map(intersectionTuple => intersectionTuple.
|
|
533
|
+
.map(intersectionTuple => intersectionTuple.intersection);
|
|
530
534
|
}
|
|
531
535
|
|
|
532
536
|
/**
|
|
@@ -542,11 +546,34 @@ export class Polygon implements IBounded, Intersectable, SVGSerializable {
|
|
|
542
546
|
// Find the intersection tangents of all lines inside the edge bounds
|
|
543
547
|
return Polygon.utils.locateLineIntersecion(line, this.vertices, this.isOpen, inVectorBoundsOnly).map(intersectionTuple => {
|
|
544
548
|
const polyLine = this.getEdgeAt(intersectionTuple.edgeIndex);
|
|
545
|
-
return new Vector(polyLine.a.clone(), polyLine.b.clone()).moveTo(intersectionTuple.
|
|
549
|
+
return new Vector(polyLine.a.clone(), polyLine.b.clone()).moveTo(intersectionTuple.intersection) as Vector;
|
|
546
550
|
});
|
|
547
551
|
}
|
|
548
552
|
//--- END --- Implement interface `Intersectable`
|
|
549
553
|
|
|
554
|
+
/**
|
|
555
|
+
* Get all line intersections of this polygon and their tangents along the shape.
|
|
556
|
+
*
|
|
557
|
+
* This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.
|
|
558
|
+
*
|
|
559
|
+
* @param line
|
|
560
|
+
* @param inVectorBoundsOnly
|
|
561
|
+
* @returns
|
|
562
|
+
*/
|
|
563
|
+
lineIntersectionTangentsIndices(
|
|
564
|
+
line: VertTuple<any>,
|
|
565
|
+
inVectorBoundsOnly: boolean = false
|
|
566
|
+
): Array<PolygonIntersectionTuple<Vector>> {
|
|
567
|
+
// Find the intersection tangents of all lines inside the edge bounds
|
|
568
|
+
return Polygon.utils.locateLineIntersecion(line, this.vertices, this.isOpen, inVectorBoundsOnly).map(intersectionTuple => {
|
|
569
|
+
const polyLine = this.getEdgeAt(intersectionTuple.edgeIndex);
|
|
570
|
+
return {
|
|
571
|
+
intersection: new Vector(polyLine.a.clone(), polyLine.b.clone()).moveTo(intersectionTuple.intersection) as Vector,
|
|
572
|
+
edgeIndex: intersectionTuple.edgeIndex
|
|
573
|
+
};
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
|
|
550
577
|
/**
|
|
551
578
|
* Get the closest line-polygon-intersection point (closest the line point A).
|
|
552
579
|
*
|
|
@@ -554,27 +581,54 @@ export class Polygon implements IBounded, Intersectable, SVGSerializable {
|
|
|
554
581
|
*
|
|
555
582
|
* @param {VertTuple} line - The line to find intersections with.
|
|
556
583
|
* @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are considered (located strictly between start and end vertex).
|
|
557
|
-
* @returns {
|
|
584
|
+
* @returns {Vertex | null} - The intersection point within the polygon bounds.
|
|
558
585
|
*/
|
|
559
586
|
closestLineIntersection(line: VertTuple<any>, inVectorBoundsOnly: boolean = false): Vertex | null {
|
|
587
|
+
var closestInterSectionIndex: PolygonIntersectionTuple<Vertex> | null = this.closestLineIntersectionIndex(
|
|
588
|
+
line,
|
|
589
|
+
inVectorBoundsOnly
|
|
590
|
+
);
|
|
591
|
+
if (closestInterSectionIndex) {
|
|
592
|
+
return closestInterSectionIndex.intersection;
|
|
593
|
+
} else {
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Get the closest line-polygon-intersection point (closest the line point A) plus the edge index..
|
|
600
|
+
*
|
|
601
|
+
* See demo `63-measure-angles-on-polygon` for how it works.
|
|
602
|
+
*
|
|
603
|
+
* @param {VertTuple} line - The line to find intersections with.
|
|
604
|
+
* @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are considered (located strictly between start and end vertex).
|
|
605
|
+
* @returns {PolygonIntersectionTuple| null} - A pair containing the intersection point and the affected polygon edge index.
|
|
606
|
+
*/
|
|
607
|
+
closestLineIntersectionIndex(
|
|
608
|
+
line: VertTuple<any>,
|
|
609
|
+
inVectorBoundsOnly: boolean = false
|
|
610
|
+
): PolygonIntersectionTuple<Vertex> | null {
|
|
560
611
|
const allIntersections = this.lineIntersections(line, inVectorBoundsOnly);
|
|
561
612
|
if (allIntersections.length <= 0) {
|
|
562
613
|
// Empty polygon -> no intersections
|
|
563
614
|
return null;
|
|
564
615
|
}
|
|
565
616
|
// Find the closest intersection
|
|
566
|
-
let closestIntersection = new Vertex(Number.MAX_VALUE, Number.MAX_VALUE);
|
|
617
|
+
let closestIntersection: Vertex = new Vertex(Number.MAX_VALUE, Number.MAX_VALUE);
|
|
618
|
+
let closestInterSectionIndex: number = -1;
|
|
567
619
|
let curDist = Number.MAX_VALUE;
|
|
568
|
-
for (var i
|
|
620
|
+
for (var i = 0; i < allIntersections.length; i++) {
|
|
569
621
|
const curVert = allIntersections[i];
|
|
570
622
|
const dist = curVert.distance(line.a);
|
|
571
623
|
if (dist < curDist) {
|
|
572
624
|
// && line.hasPoint(curVert)) {
|
|
573
625
|
curDist = dist;
|
|
574
626
|
closestIntersection = curVert;
|
|
627
|
+
closestInterSectionIndex = i;
|
|
575
628
|
}
|
|
576
629
|
}
|
|
577
|
-
return closestIntersection;
|
|
630
|
+
// return [closestIntersection, closestInterSectionIndex];
|
|
631
|
+
return { edgeIndex: closestInterSectionIndex, intersection: closestIntersection };
|
|
578
632
|
}
|
|
579
633
|
|
|
580
634
|
/**
|
|
@@ -949,9 +1003,9 @@ export class Polygon implements IBounded, Intersectable, SVGSerializable {
|
|
|
949
1003
|
vertices: Array<Vertex>,
|
|
950
1004
|
isOpen: boolean,
|
|
951
1005
|
inVectorBoundsOnly: boolean
|
|
952
|
-
): Array<
|
|
1006
|
+
): Array<PolygonIntersectionTuple<Vertex>> {
|
|
953
1007
|
// Find the intersections of all lines inside the edge bounds
|
|
954
|
-
const intersectionPoints: Array<
|
|
1008
|
+
const intersectionPoints: Array<PolygonIntersectionTuple<Vertex>> = [];
|
|
955
1009
|
var n = isOpen ? vertices.length - 1 : vertices.length;
|
|
956
1010
|
for (var i = 0; i < n; i++) {
|
|
957
1011
|
const polyLine = new Line(vertices[i % n], vertices[(i + 1) % n]);
|
|
@@ -963,7 +1017,7 @@ export class Polygon implements IBounded, Intersectable, SVGSerializable {
|
|
|
963
1017
|
polyLine.hasPoint(intersection, true) &&
|
|
964
1018
|
(!inVectorBoundsOnly || line.hasPoint(intersection, inVectorBoundsOnly))
|
|
965
1019
|
) {
|
|
966
|
-
intersectionPoints.push({ edgeIndex: i,
|
|
1020
|
+
intersectionPoints.push({ edgeIndex: i, intersection: intersection });
|
|
967
1021
|
}
|
|
968
1022
|
}
|
|
969
1023
|
return intersectionPoints;
|
package/src/ts/Triangle.ts
CHANGED
|
@@ -405,7 +405,7 @@ export class Triangle implements IBounded, SVGSerializable, Intersectable {
|
|
|
405
405
|
// Find the intersections of all lines inside the edge bounds
|
|
406
406
|
return Polygon.utils
|
|
407
407
|
.locateLineIntersecion(line, [this.a, this.b, this.c], false, inVectorBoundsOnly)
|
|
408
|
-
.map(intersectionTuple => intersectionTuple.
|
|
408
|
+
.map(intersectionTuple => intersectionTuple.intersection);
|
|
409
409
|
}
|
|
410
410
|
|
|
411
411
|
/**
|
|
@@ -424,7 +424,7 @@ export class Triangle implements IBounded, SVGSerializable, Intersectable {
|
|
|
424
424
|
.map(intersectionTuple => {
|
|
425
425
|
// const polyLine = this.getEdgeAt(intersectionTuple.edgeIndex);
|
|
426
426
|
const polyLine = this.getEdgeAt(intersectionTuple.edgeIndex);
|
|
427
|
-
return new Vector(polyLine.a.clone(), polyLine.b.clone()).moveTo(intersectionTuple.
|
|
427
|
+
return new Vector(polyLine.a.clone(), polyLine.b.clone()).moveTo(intersectionTuple.intersection) as Vector;
|
|
428
428
|
});
|
|
429
429
|
}
|
|
430
430
|
//--- END --- Implement interface `Intersectable`
|