plotboilerplate 1.23.2 → 1.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/index.esm.js +8351 -6928
- 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 +1590 -123
- package/dist/plotboilerplate.min.js +1 -1
- package/package.json +4 -2
- package/src/cjs/BezierPath.d.ts +41 -5
- package/src/cjs/BezierPath.js +52 -2
- package/src/cjs/BezierPath.js.map +1 -1
- package/src/cjs/Bounds.d.ts +67 -3
- package/src/cjs/Bounds.js +101 -3
- package/src/cjs/Bounds.js.map +1 -1
- package/src/cjs/Circle.d.ts +46 -4
- package/src/cjs/Circle.js +82 -3
- package/src/cjs/Circle.js.map +1 -1
- package/src/cjs/CircleSector.d.ts +51 -2
- package/src/cjs/CircleSector.js +112 -3
- package/src/cjs/CircleSector.js.map +1 -1
- package/src/cjs/CubicBezierCurve.d.ts +113 -7
- package/src/cjs/CubicBezierCurve.js +281 -33
- package/src/cjs/CubicBezierCurve.js.map +1 -1
- package/src/cjs/Line.d.ts +38 -3
- package/src/cjs/Line.js +64 -1
- package/src/cjs/Line.js.map +1 -1
- package/src/cjs/PlotBoilerplate.d.ts +4 -2
- package/src/cjs/PlotBoilerplate.js +9 -12
- package/src/cjs/PlotBoilerplate.js.map +1 -1
- package/src/cjs/Polygon.d.ts +153 -6
- package/src/cjs/Polygon.js +304 -23
- package/src/cjs/Polygon.js.map +1 -1
- package/src/cjs/Triangle.d.ts +73 -4
- package/src/cjs/Triangle.js +94 -2
- package/src/cjs/Triangle.js.map +1 -1
- package/src/cjs/VEllipse.d.ts +62 -3
- package/src/cjs/VEllipse.js +181 -17
- package/src/cjs/VEllipse.js.map +1 -1
- package/src/cjs/VEllipseSector.d.ts +86 -2
- package/src/cjs/VEllipseSector.js +148 -4
- package/src/cjs/VEllipseSector.js.map +1 -1
- package/src/cjs/Vector.d.ts +12 -2
- package/src/cjs/Vector.js +15 -2
- package/src/cjs/Vector.js.map +1 -1
- package/src/cjs/VertTuple.d.ts +39 -10
- package/src/cjs/VertTuple.js +49 -11
- package/src/cjs/VertTuple.js.map +1 -1
- package/src/cjs/Vertex.d.ts +18 -2
- package/src/cjs/Vertex.js +22 -2
- package/src/cjs/Vertex.js.map +1 -1
- package/src/cjs/draw.d.ts +1 -0
- package/src/cjs/draw.js +2 -1
- package/src/cjs/draw.js.map +1 -1
- package/src/cjs/drawutilssvg.js +24 -0
- package/src/cjs/drawutilssvg.js.map +1 -1
- package/src/cjs/geomutils.d.ts +32 -1
- package/src/cjs/geomutils.js +47 -1
- package/src/cjs/geomutils.js.map +1 -1
- package/src/cjs/interfaces/core.d.ts +39 -0
- package/src/cjs/interfaces/core.js +2 -0
- package/src/cjs/interfaces/core.js.map +1 -1
- package/src/cjs/utils/algorithms/PolygonInset.d.ts +184 -0
- package/src/cjs/utils/algorithms/PolygonInset.js +431 -0
- package/src/cjs/utils/algorithms/PolygonInset.js.map +1 -0
- package/src/cjs/utils/algorithms/clearDuplicateVertices.d.ts +5 -4
- package/src/cjs/utils/algorithms/clearDuplicateVertices.js +6 -3
- package/src/cjs/utils/algorithms/clearDuplicateVertices.js.map +1 -1
- package/src/cjs/utils/algorithms/convexPolygonIncircle.d.ts +2 -1
- package/src/cjs/utils/algorithms/convexPolygonIncircle.js +14 -6
- package/src/cjs/utils/algorithms/convexPolygonIncircle.js.map +1 -1
- package/src/cjs/utils/algorithms/findPolygonSelfIntersections.d.ts +2 -1
- package/src/cjs/utils/algorithms/findPolygonSelfIntersections.js +3 -3
- package/src/cjs/utils/algorithms/findPolygonSelfIntersections.js.map +1 -1
- package/src/cjs/utils/algorithms/splitPolygonToNonIntersecting.d.ts +3 -2
- package/src/cjs/utils/algorithms/splitPolygonToNonIntersecting.js +11 -9
- package/src/cjs/utils/algorithms/splitPolygonToNonIntersecting.js.map +1 -1
- package/src/cjs/utils/createRandomizedPolygon.d.ts +14 -0
- package/src/cjs/utils/createRandomizedPolygon.js +32 -0
- package/src/cjs/utils/createRandomizedPolygon.js.map +1 -0
- package/src/cjs/utils/detectDarkMode.js.map +1 -1
- package/src/cjs/utils/dom/guiSizeToggler.d.ts +2 -1
- package/src/cjs/utils/dom/guiSizeToggler.js +5 -3
- package/src/cjs/utils/dom/guiSizeToggler.js.map +1 -1
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.d.ts +9 -7
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.js +37 -23
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
- package/src/cjs/utils/helpers/CircleSectorHelper.d.ts +10 -1
- package/src/cjs/utils/helpers/CircleSectorHelper.js +19 -20
- package/src/cjs/utils/helpers/CircleSectorHelper.js.map +1 -1
- package/src/cjs/utils/helpers/VEllipseHelper.d.ts +30 -0
- package/src/cjs/utils/helpers/VEllipseHelper.js +86 -0
- package/src/cjs/utils/helpers/VEllipseHelper.js.map +1 -0
- package/src/cjs/utils/helpers/VEllipseSectorHelper.d.ts +42 -3
- package/src/cjs/utils/helpers/VEllipseSectorHelper.js +107 -25
- package/src/cjs/utils/helpers/VEllipseSectorHelper.js.map +1 -1
- package/src/createDemoDrawables.js +3 -1
- package/src/esm/BezierPath.d.ts +41 -5
- package/src/esm/BezierPath.js +50 -2
- package/src/esm/BezierPath.js.map +1 -1
- package/src/esm/Bounds.d.ts +67 -3
- package/src/esm/Bounds.js +101 -3
- package/src/esm/Bounds.js.map +1 -1
- package/src/esm/Circle.d.ts +46 -4
- package/src/esm/Circle.js +79 -3
- package/src/esm/Circle.js.map +1 -1
- package/src/esm/CircleSector.d.ts +51 -2
- package/src/esm/CircleSector.js +108 -3
- package/src/esm/CircleSector.js.map +1 -1
- package/src/esm/CubicBezierCurve.d.ts +113 -7
- package/src/esm/CubicBezierCurve.js +277 -33
- package/src/esm/CubicBezierCurve.js.map +1 -1
- package/src/esm/Line.d.ts +38 -3
- package/src/esm/Line.js +62 -1
- package/src/esm/Line.js.map +1 -1
- package/src/esm/PlotBoilerplate.d.ts +4 -2
- package/src/esm/PlotBoilerplate.js +9 -12
- package/src/esm/PlotBoilerplate.js.map +1 -1
- package/src/esm/Polygon.d.ts +153 -6
- package/src/esm/Polygon.js +301 -23
- package/src/esm/Polygon.js.map +1 -1
- package/src/esm/Triangle.d.ts +73 -4
- package/src/esm/Triangle.js +91 -2
- package/src/esm/Triangle.js.map +1 -1
- package/src/esm/VEllipse.d.ts +62 -3
- package/src/esm/VEllipse.js +178 -17
- package/src/esm/VEllipse.js.map +1 -1
- package/src/esm/VEllipseSector.d.ts +86 -2
- package/src/esm/VEllipseSector.js +146 -7
- package/src/esm/VEllipseSector.js.map +1 -1
- package/src/esm/Vector.d.ts +12 -2
- package/src/esm/Vector.js +15 -2
- package/src/esm/Vector.js.map +1 -1
- package/src/esm/VertTuple.d.ts +39 -10
- package/src/esm/VertTuple.js +49 -11
- package/src/esm/VertTuple.js.map +1 -1
- package/src/esm/Vertex.d.ts +18 -2
- package/src/esm/Vertex.js +22 -2
- package/src/esm/Vertex.js.map +1 -1
- package/src/esm/draw.d.ts +1 -0
- package/src/esm/draw.js +2 -1
- package/src/esm/draw.js.map +1 -1
- package/src/esm/drawutilssvg.js +24 -0
- package/src/esm/drawutilssvg.js.map +1 -1
- package/src/esm/geomutils.d.ts +32 -1
- package/src/esm/geomutils.js +47 -1
- package/src/esm/geomutils.js.map +1 -1
- package/src/esm/interfaces/core.d.ts +39 -0
- package/src/esm/interfaces/core.js +2 -0
- package/src/esm/interfaces/core.js.map +1 -1
- package/src/esm/utils/algorithms/PolygonInset.d.ts +184 -0
- package/src/esm/utils/algorithms/PolygonInset.js +424 -0
- package/src/esm/utils/algorithms/PolygonInset.js.map +1 -0
- package/src/esm/utils/algorithms/clearDuplicateVertices.d.ts +5 -4
- package/src/esm/utils/algorithms/clearDuplicateVertices.js +6 -3
- package/src/esm/utils/algorithms/clearDuplicateVertices.js.map +1 -1
- package/src/esm/utils/algorithms/convexPolygonIncircle.d.ts +2 -1
- package/src/esm/utils/algorithms/convexPolygonIncircle.js +15 -7
- package/src/esm/utils/algorithms/convexPolygonIncircle.js.map +1 -1
- package/src/esm/utils/algorithms/createRandomizedPolygon.d.ts +14 -0
- package/src/esm/utils/algorithms/createRandomizedPolygon.js +28 -0
- package/src/esm/utils/algorithms/createRandomizedPolygon.js.map +1 -0
- package/src/esm/utils/algorithms/findPolygonSelfIntersections.d.ts +2 -1
- package/src/esm/utils/algorithms/findPolygonSelfIntersections.js +3 -3
- package/src/esm/utils/algorithms/findPolygonSelfIntersections.js.map +1 -1
- package/src/esm/utils/algorithms/splitPolygonToNonIntersecting.d.ts +3 -2
- package/src/esm/utils/algorithms/splitPolygonToNonIntersecting.js +11 -9
- package/src/esm/utils/algorithms/splitPolygonToNonIntersecting.js.map +1 -1
- package/src/esm/utils/createRandomizedPolygon.d.ts +14 -0
- package/src/esm/utils/createRandomizedPolygon.js +28 -0
- package/src/esm/utils/createRandomizedPolygon.js.map +1 -0
- package/src/esm/utils/detectDarkMode.js.map +1 -1
- package/src/esm/utils/dom/guiSizeToggler.d.ts +2 -1
- package/src/esm/utils/dom/guiSizeToggler.js +4 -2
- package/src/esm/utils/dom/guiSizeToggler.js.map +1 -1
- package/src/esm/utils/helpers/BezierPathInteractionHelper.d.ts +9 -7
- package/src/esm/utils/helpers/BezierPathInteractionHelper.js +35 -22
- package/src/esm/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
- package/src/esm/utils/helpers/CircleSectorHelper.d.ts +10 -1
- package/src/esm/utils/helpers/CircleSectorHelper.js +19 -20
- package/src/esm/utils/helpers/CircleSectorHelper.js.map +1 -1
- package/src/esm/utils/helpers/VEllipseHelper.d.ts +30 -0
- package/src/esm/utils/helpers/VEllipseHelper.js +81 -0
- package/src/esm/utils/helpers/VEllipseHelper.js.map +1 -0
- package/src/esm/utils/helpers/VEllipseSectorHelper.d.ts +42 -3
- package/src/esm/utils/helpers/VEllipseSectorHelper.js +106 -24
- package/src/esm/utils/helpers/VEllipseSectorHelper.js.map +1 -1
- package/src/ts/BezierPath.ts +58 -5
- package/src/ts/Bounds.ts +110 -6
- package/src/ts/Circle.ts +87 -5
- package/src/ts/CircleSector.ts +115 -5
- package/src/ts/CubicBezierCurve.ts +332 -42
- package/src/ts/Line.ts +66 -3
- package/src/ts/PlotBoilerplate.ts +10 -12
- package/src/ts/Polygon.ts +329 -27
- package/src/ts/Triangle.ts +101 -5
- package/src/ts/VEllipse.ts +214 -19
- package/src/ts/VEllipseSector.ts +154 -8
- package/src/ts/Vector.ts +16 -2
- package/src/ts/VertTuple.ts +53 -13
- package/src/ts/Vertex.ts +24 -3
- package/src/ts/draw.ts +2 -1
- package/src/ts/drawutilssvg.ts +29 -0
- package/src/ts/geomutils.ts +49 -1
- package/src/ts/interfaces/core.ts +42 -0
- package/src/ts/utils/algorithms/PolygonInset.ts +529 -0
- package/src/ts/utils/algorithms/clearDuplicateVertices.ts +11 -8
- package/src/ts/utils/algorithms/convexPolygonIncircle.ts +82 -78
- package/src/ts/utils/algorithms/findPolygonSelfIntersections.ts +25 -26
- package/src/ts/utils/algorithms/splitPolygonToNonIntersecting.ts +92 -99
- package/src/ts/utils/createRandomizedPolygon.ts +31 -0
- package/src/ts/utils/detectDarkMode.ts +1 -3
- package/src/ts/utils/dom/guiSizeToggler.ts +4 -2
- package/src/ts/utils/helpers/BezierPathInteractionHelper.ts +45 -29
- package/src/ts/utils/helpers/CircleSectorHelper.ts +115 -125
- package/src/ts/utils/helpers/VEllipseHelper.ts +113 -0
- package/src/ts/utils/helpers/VEllipseSectorHelper.ts +142 -25
|
@@ -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
|
-
* @
|
|
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
|
|
22
|
+
const EPS: number = 0.000001;
|
|
23
23
|
|
|
24
24
|
export interface PolygonIncircle {
|
|
25
|
-
|
|
26
|
-
|
|
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 = (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
95
|
-
|
|
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 = (
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const circleIntersC : Vertex = lineC.getClosestPoint( intersection );
|
|
132
|
+
if (!intersection) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
133
135
|
|
|
134
|
-
|
|
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 = (
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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
|
-
|
|
159
|
+
}
|
|
160
|
+
return result;
|
|
155
161
|
};
|
|
156
|
-
|
|
157
|
-
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* @author Ikaros Kappler
|
|
6
6
|
* @date 2020-12-04
|
|
7
7
|
* @modified 2020-12-09 Ported from vanilla JS to Typescript.
|
|
8
|
+
* @modified 2024-11-22 Fixed a type error in line 41.
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
import { Line } from "../../Line";
|
|
@@ -18,34 +19,32 @@ import { XYCoords } from "../../interfaces";
|
|
|
18
19
|
*
|
|
19
20
|
* @name findPolygonSelfIntersections
|
|
20
21
|
* @param {Array<Vertex>} vertices - The vertices that form the polygon.
|
|
21
|
-
* @return Array<Vertex>
|
|
22
|
+
* @return {Array<Vertex>}
|
|
22
23
|
*/
|
|
23
|
-
export const findPolygonSelfIntersections = (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
lineB.b.set( vertices[(b+1)%n] );
|
|
24
|
+
export const findPolygonSelfIntersections = (vertices: Array<XYCoords>): Array<Vertex> => {
|
|
25
|
+
const pointList: Array<Vertex> = [];
|
|
26
|
+
const lineA: Line = new Line(new Vertex(), new Vertex());
|
|
27
|
+
const lineB: Line = new Line(new Vertex(), new Vertex());
|
|
28
|
+
const n: number = vertices.length;
|
|
29
|
+
for (var a = 0; a < n; a++) {
|
|
30
|
+
lineA.a.set(vertices[a]);
|
|
31
|
+
lineA.b.set(vertices[(a + 1) % n]);
|
|
32
|
+
for (var b = 0; b < n; b++) {
|
|
33
|
+
// Same edge or neighbour edges intersect by definition.
|
|
34
|
+
// Skip them.
|
|
35
|
+
if (a == b || a + 1 == b || a == b + 1 || (a == 0 && b + 1 == n) || (b == 0 && a + 1 == n)) continue;
|
|
36
|
+
lineB.a.set(vertices[b]);
|
|
37
|
+
lineB.b.set(vertices[(b + 1) % n]);
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
// Commpute the intersection point of the (infinite) lines.
|
|
40
|
+
// The point is undefined if and only if both line are parallel (co-linear).
|
|
41
|
+
const intersectionPoint: Vertex | null = lineA.intersection(lineB);
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
}
|
|
43
|
+
// Check if the intersection point is on both (finite) edges of the polygon.
|
|
44
|
+
if (intersectionPoint && lineA.hasPoint(intersectionPoint) && lineB.hasPoint(intersectionPoint)) {
|
|
45
|
+
pointList.push(intersectionPoint);
|
|
46
|
+
}
|
|
49
47
|
}
|
|
50
|
-
|
|
48
|
+
}
|
|
49
|
+
return pointList;
|
|
51
50
|
};
|
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @requires Line
|
|
3
3
|
* @requires Vertex
|
|
4
|
-
*
|
|
4
|
+
*
|
|
5
5
|
* @author Ikaros Kappler
|
|
6
6
|
* @date 2020-12-04
|
|
7
7
|
* @modified 2020-12-07 Ported from vanilla JS to typescript.
|
|
8
|
-
* @
|
|
8
|
+
* @modified 2024-11-22 Added the `insideBoundsOnly` param to the `splitPolygonToNonIntersecting` algorithm.
|
|
9
|
+
* @version 1.1.0
|
|
9
10
|
*/
|
|
10
11
|
|
|
11
12
|
import { Line } from "../../Line";
|
|
12
13
|
import { Vertex } from "../../Vertex";
|
|
13
14
|
|
|
14
|
-
|
|
15
15
|
/**
|
|
16
16
|
* Splitting a polygon at a self intersection results in two new polygons.
|
|
17
17
|
*/
|
|
18
|
-
type ISplit = [
|
|
19
|
-
|
|
18
|
+
type ISplit = [Array<Vertex>, Array<Vertex>];
|
|
20
19
|
|
|
21
20
|
/**
|
|
22
|
-
* This function cuts a given self-intersecting polygon into non-self-intersecting
|
|
21
|
+
* This function cuts a given self-intersecting polygon into non-self-intersecting
|
|
23
22
|
* sub polygons.
|
|
24
23
|
*
|
|
25
24
|
* The algorithm only works for non-self-overlapping polygons:
|
|
@@ -35,97 +34,91 @@ type ISplit = [ Array<Vertex>, Array<Vertex> ];
|
|
|
35
34
|
* @return {Array<Array<Vertex>>} A sequence of non-self-intersecting sub polygons.
|
|
36
35
|
*/
|
|
37
36
|
export const splitPolygonToNonIntersecting = (() => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return [ first, second ];
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
return splitPolygonToNonIntersecting;
|
|
37
|
+
/**
|
|
38
|
+
* @param {Array<Vertex>} vertices
|
|
39
|
+
* @param {number=10} maxDepth
|
|
40
|
+
*/
|
|
41
|
+
const splitPolygonToNonIntersecting = (
|
|
42
|
+
vertices: Array<Vertex>,
|
|
43
|
+
maxDepth?: number,
|
|
44
|
+
insideBoundsOnly?: boolean
|
|
45
|
+
): Array<Array<Vertex>> => {
|
|
46
|
+
if (typeof maxDepth === "undefined") maxDepth = 10;
|
|
47
|
+
return _splitPolygonToNonIntersecting(vertices, maxDepth, insideBoundsOnly);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const _splitPolygonToNonIntersecting = (
|
|
51
|
+
vertices: Array<Vertex>,
|
|
52
|
+
maxDepth: number,
|
|
53
|
+
insideBoundsOnly?: boolean
|
|
54
|
+
): Array<Array<Vertex>> => {
|
|
55
|
+
if (maxDepth <= 0) {
|
|
56
|
+
// aborting at max depth
|
|
57
|
+
return [vertices];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (vertices.length <= 3) {
|
|
61
|
+
// No intersections possible
|
|
62
|
+
return [vertices];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const n: number = vertices.length;
|
|
66
|
+
const lineA: Line = new Line(new Vertex(), new Vertex());
|
|
67
|
+
const lineB: Line = new Line(new Vertex(), new Vertex());
|
|
68
|
+
for (var a = 0; a < vertices.length; a++) {
|
|
69
|
+
lineA.a.set(vertices[a]);
|
|
70
|
+
lineA.b.set(vertices[(a + 1) % n]);
|
|
71
|
+
for (var b = 0; b < vertices.length; b++) {
|
|
72
|
+
// Equal edges or neighbour edges intersect by definition.
|
|
73
|
+
// We ignore them.
|
|
74
|
+
if (a == b || a + 1 == b || a == b + 1 || (a == 0 && b + 1 == vertices.length) || (b == 0 && a + 1 == vertices.length))
|
|
75
|
+
continue;
|
|
76
|
+
lineB.a.set(vertices[b]);
|
|
77
|
+
lineB.b.set(vertices[(b + 1) % n]);
|
|
78
|
+
|
|
79
|
+
const intersectionPoint: Vertex | null = lineA.intersection(lineB);
|
|
80
|
+
if (
|
|
81
|
+
intersectionPoint &&
|
|
82
|
+
lineA.hasPoint(intersectionPoint, insideBoundsOnly) &&
|
|
83
|
+
lineB.hasPoint(intersectionPoint, insideBoundsOnly)
|
|
84
|
+
) {
|
|
85
|
+
// Cut polygon into two here
|
|
86
|
+
const split: ISplit = splitPolygonAt(vertices, a, b, intersectionPoint);
|
|
87
|
+
|
|
88
|
+
// Split has 2 elements.
|
|
89
|
+
const leftCleaned: Array<Array<Vertex>> = _splitPolygonToNonIntersecting(split[0], maxDepth - 1, insideBoundsOnly);
|
|
90
|
+
const rightCleaned: Array<Array<Vertex>> = _splitPolygonToNonIntersecting(split[1], maxDepth - 1, insideBoundsOnly);
|
|
91
|
+
|
|
92
|
+
return leftCleaned.concat(rightCleaned);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// No intersection found:
|
|
98
|
+
// just return a list with the original
|
|
99
|
+
// polygon as its only element.
|
|
100
|
+
return [vertices];
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// Pre: edgeIndexA < edgeIndexB && vertices.length >= 4
|
|
104
|
+
const splitPolygonAt = (vertices: Array<Vertex>, edgeIndexA: number, edgeIndexB: number, intersectionPoint: Vertex): ISplit => {
|
|
105
|
+
const first: Array<Vertex> = [];
|
|
106
|
+
var second: Array<Vertex> = [];
|
|
107
|
+
for (var i = 0; i < vertices.length; i++) {
|
|
108
|
+
if (i <= edgeIndexA) first.push(vertices[i]);
|
|
109
|
+
|
|
110
|
+
if (i == edgeIndexA) {
|
|
111
|
+
first.push(intersectionPoint);
|
|
112
|
+
second.push(intersectionPoint); // clone???
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (i > edgeIndexA && i <= edgeIndexB) second.push(vertices[i]);
|
|
116
|
+
|
|
117
|
+
if (i > edgeIndexB) first.push(vertices[i]);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return [first, second];
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
return splitPolygonToNonIntersecting;
|
|
130
124
|
})();
|
|
131
|
-
|
|
@@ -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
|
+
};
|
|
@@ -8,9 +8,7 @@
|
|
|
8
8
|
* @returns {boolean}
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export const detectDarkMode = (GUP?: Record<string, string>) => {
|
|
11
|
+
export const detectDarkMode = (GUP?: Record<string, string>): boolean => {
|
|
14
12
|
// Respect overrides
|
|
15
13
|
if (typeof GUP !== "undefined" && GUP.hasOwnProperty("darkmode") && GUP["darkmode"]) {
|
|
16
14
|
// const overrideValue = PlotBoilerplate.utils.fetch.bool(GUP, "darkmode", null);
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* @date 2021-12-13
|
|
6
6
|
* @modified 2022-01-10
|
|
7
7
|
* @modified 2024-06-25 Ported to typescript and moved to utils/dom (was located inside demos before).
|
|
8
|
-
* @
|
|
8
|
+
* @modified 2024-10-02 Added a transition time.
|
|
9
|
+
* @version 1.1.1
|
|
9
10
|
*/
|
|
10
11
|
|
|
11
12
|
import { GUI } from "../../interfaces/externals";
|
|
@@ -36,7 +37,8 @@ const applyGuiSize = (gui: GUI, guiDoubleSize: boolean, cssProps: Record<string,
|
|
|
36
37
|
}
|
|
37
38
|
};
|
|
38
39
|
|
|
39
|
-
export const guiSizeToggler
|
|
40
|
+
export const guiSizeToggler = (gui: GUI, config: ITogglerConfig, cssProps: Record<string, string>) => {
|
|
41
|
+
gui.domElement.style["transition"] = "transform 0.5s";
|
|
40
42
|
return {
|
|
41
43
|
update: function () {
|
|
42
44
|
applyGuiSize(gui, Boolean(config.guiDoubleSize), cssProps);
|