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
package/src/ts/Polygon.ts
CHANGED
|
@@ -28,7 +28,15 @@
|
|
|
28
28
|
* @modified 2023-09-25 Added the `Polygon.lineIntersections(Line,boolean)` function.
|
|
29
29
|
* @modified 2023-09-29 Added the `Polygon.closestLineIntersection(Line,boolean)` function.
|
|
30
30
|
* @modified 2023-11-24 Added the `Polygon.containsPolygon(Polygon)' function.
|
|
31
|
-
* @
|
|
31
|
+
* @modified 2024-10-12 Added the `getEdgeAt` method.
|
|
32
|
+
* @modified 2024-10-30 Added the `getEdges` method.
|
|
33
|
+
* @modified 2024-12-02 Added the `elimitateColinearEdges` method.
|
|
34
|
+
* @modified 2025-02-12 Added the `containsVerts` method to test multiple vertices for containment.
|
|
35
|
+
* @modified 2025-03-28 Added the `Polygon.utils.locateLineIntersecion` static helper method.
|
|
36
|
+
* @modified 2025-03-28 Added the `Polygon.lineIntersectionTangents` method.
|
|
37
|
+
* @modified 2025-04-09 Added the `Polygon.getCentroid` method.
|
|
38
|
+
* @modified 2025-05-16 Class `Polygon` now implements `IBounded`.
|
|
39
|
+
* @version 1.15.0
|
|
32
40
|
*
|
|
33
41
|
* @file Polygon
|
|
34
42
|
* @public
|
|
@@ -37,10 +45,13 @@
|
|
|
37
45
|
import { BezierPath } from "./BezierPath";
|
|
38
46
|
import { Bounds } from "./Bounds";
|
|
39
47
|
import { Line } from "./Line";
|
|
48
|
+
import { Triangle } from "./Triangle";
|
|
40
49
|
import { UIDGenerator } from "./UIDGenerator";
|
|
50
|
+
import { Vector } from "./Vector";
|
|
41
51
|
import { VertTuple } from "./VertTuple";
|
|
42
52
|
import { Vertex } from "./Vertex";
|
|
43
|
-
import {
|
|
53
|
+
import { geomutils } from "./geomutils";
|
|
54
|
+
import { XYCoords, SVGSerializable, UID, Intersectable, IBounded } from "./interfaces";
|
|
44
55
|
|
|
45
56
|
/**
|
|
46
57
|
* @classdesc A polygon class. Any polygon consists of an array of vertices; polygons can be open or closed.
|
|
@@ -53,7 +64,7 @@ import { XYCoords, SVGSerializable, UID } from "./interfaces";
|
|
|
53
64
|
* @requires Vertex
|
|
54
65
|
* @requires XYCoords
|
|
55
66
|
*/
|
|
56
|
-
export class Polygon implements SVGSerializable {
|
|
67
|
+
export class Polygon implements IBounded, Intersectable, SVGSerializable {
|
|
57
68
|
/**
|
|
58
69
|
* Required to generate proper CSS classes and other class related IDs.
|
|
59
70
|
**/
|
|
@@ -103,7 +114,9 @@ export class Polygon implements SVGSerializable {
|
|
|
103
114
|
**/
|
|
104
115
|
constructor(vertices?: Array<Vertex>, isOpen?: boolean) {
|
|
105
116
|
this.uid = UIDGenerator.next();
|
|
106
|
-
if (typeof vertices == "undefined")
|
|
117
|
+
if (typeof vertices == "undefined") {
|
|
118
|
+
vertices = [];
|
|
119
|
+
}
|
|
107
120
|
this.vertices = vertices;
|
|
108
121
|
this.isOpen = isOpen || false;
|
|
109
122
|
}
|
|
@@ -111,7 +124,7 @@ export class Polygon implements SVGSerializable {
|
|
|
111
124
|
/**
|
|
112
125
|
* Add a vertex to the end of the `vertices` array.
|
|
113
126
|
*
|
|
114
|
-
* @method
|
|
127
|
+
* @method addVertex
|
|
115
128
|
* @param {Vertex} vert - The vertex to add.
|
|
116
129
|
* @instance
|
|
117
130
|
* @memberof Polygon
|
|
@@ -120,6 +133,117 @@ export class Polygon implements SVGSerializable {
|
|
|
120
133
|
this.vertices.push(vert);
|
|
121
134
|
}
|
|
122
135
|
|
|
136
|
+
/**
|
|
137
|
+
* Add a vertex at a particular position of the `vertices` array.
|
|
138
|
+
*
|
|
139
|
+
* @method addVertexAt
|
|
140
|
+
* @param {Vertex} vert - The vertex to add.
|
|
141
|
+
* @param {number} index - The position to add the vertex at. Will be handled modulo.
|
|
142
|
+
* @instance
|
|
143
|
+
* @memberof Polygon
|
|
144
|
+
**/
|
|
145
|
+
addVertexAt(vert: Vertex, index: number): void {
|
|
146
|
+
// var moduloIndex = index % (this.vertices.length + 1);
|
|
147
|
+
this.vertices.splice(index, 0, vert);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Get a new instance of the line at the given start index. The returned line will consist
|
|
152
|
+
* of the vertex at `vertIndex` and `vertIndex+1` (will be handled modulo).
|
|
153
|
+
*
|
|
154
|
+
* @method getEdgeAt
|
|
155
|
+
* @param {number} vertIndex - The vertex index of the line to start.
|
|
156
|
+
* @instance
|
|
157
|
+
* @memberof Polygon
|
|
158
|
+
* @return {Line}
|
|
159
|
+
**/
|
|
160
|
+
getEdgeAt(vertIndex: number): Line {
|
|
161
|
+
return new Line(this.getVertexAt(vertIndex), this.getVertexAt(vertIndex + 1));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Converts this polygon into a sequence of lines. Please note that each time
|
|
166
|
+
* this method is called new lines are created. The underlying line vertices are no clones
|
|
167
|
+
* (instances).
|
|
168
|
+
*
|
|
169
|
+
* @method getEdges
|
|
170
|
+
* @instance
|
|
171
|
+
* @memberof Polygon
|
|
172
|
+
* @return {Array<Line>}
|
|
173
|
+
*/
|
|
174
|
+
getEdges(): Array<Line> {
|
|
175
|
+
const lines: Array<Line> = [];
|
|
176
|
+
for (var i = 0; i + 1 < this.vertices.length; i++) {
|
|
177
|
+
// var line = this.getLineAt(i).clone();
|
|
178
|
+
lines.push(this.getEdgeAt(i));
|
|
179
|
+
}
|
|
180
|
+
if (!this.isOpen && this.vertices.length > 0) {
|
|
181
|
+
lines.push(this.getEdgeAt(this.vertices.length - 1));
|
|
182
|
+
}
|
|
183
|
+
return lines;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Checks if the angle at the given polygon vertex (index) is acute. Please not that this is
|
|
188
|
+
* only working for clockwise polygons. If this polygon is not clockwise please use the
|
|
189
|
+
* `isClockwise` method and reverse polygon vertices if needed.
|
|
190
|
+
*
|
|
191
|
+
* @method isAngleAcute
|
|
192
|
+
* @instance
|
|
193
|
+
* @memberof Polygon
|
|
194
|
+
* @param {number} vertIndex - The index of the polygon vertex to check.
|
|
195
|
+
* @returns {boolean} `true` is angle is acute, `false` is obtuse.
|
|
196
|
+
*/
|
|
197
|
+
getInnerAngleAt(vertIndex: number): number {
|
|
198
|
+
const p2: Vertex = this.vertices[vertIndex];
|
|
199
|
+
const p1: Vertex = this.vertices[(vertIndex + this.vertices.length - 1) % this.vertices.length].clone();
|
|
200
|
+
const p3: Vertex = this.vertices[(vertIndex + 1) % this.vertices.length].clone();
|
|
201
|
+
|
|
202
|
+
// See
|
|
203
|
+
// https://math.stackexchange.com/questions/149959/how-to-find-the-interior-angle-of-an-irregular-pentagon-or-polygon
|
|
204
|
+
// π−arccos((P2−P1)⋅(P3−P2)|P2−P1||P3−P2|)
|
|
205
|
+
|
|
206
|
+
// Check if triangle is acute (will be used later)
|
|
207
|
+
// Acute angles and obtuse angles need to be handled differently.
|
|
208
|
+
const isAcute: boolean = this.isAngleAcute(vertIndex);
|
|
209
|
+
|
|
210
|
+
// Differences
|
|
211
|
+
const zero: Vertex = new Vertex(0, 0);
|
|
212
|
+
const p2mp1: Vertex = new Vertex(p2.x - p1.x, p2.y - p1.y);
|
|
213
|
+
const p3mp2: Vertex = new Vertex(p3.x - p2.x, p3.y - p2.y);
|
|
214
|
+
const p2mp1_len: number = zero.distance(p2mp1);
|
|
215
|
+
const p3mp2_len: number = zero.distance(p3mp2);
|
|
216
|
+
|
|
217
|
+
// Dot products
|
|
218
|
+
const dotProduct: number = geomutils.dotProduct(p2mp1, p3mp2);
|
|
219
|
+
const lengthProduct: number = p2mp1_len * p3mp2_len;
|
|
220
|
+
if (isAcute) {
|
|
221
|
+
return Math.PI - Math.acos(dotProduct / lengthProduct);
|
|
222
|
+
} else {
|
|
223
|
+
return Math.PI + Math.acos(dotProduct / lengthProduct);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Checks if the angle at the given polygon vertex (index) is acute.
|
|
229
|
+
*
|
|
230
|
+
* @method isAngleAcute
|
|
231
|
+
* @instance
|
|
232
|
+
* @memberof Polygon
|
|
233
|
+
* @param {number} vertIndex - The index of the polygon vertex to check.
|
|
234
|
+
* @returns {boolean} `true` is angle is acute, `false` is obtuse.
|
|
235
|
+
*/
|
|
236
|
+
isAngleAcute(vertIndex: number): boolean {
|
|
237
|
+
const A: Vertex = this.vertices[(vertIndex + this.vertices.length - 1) % this.vertices.length].clone();
|
|
238
|
+
const B: Vertex = this.vertices[vertIndex];
|
|
239
|
+
const C: Vertex = this.vertices[(vertIndex + 1) % this.vertices.length].clone();
|
|
240
|
+
|
|
241
|
+
// Find local winding number for triangle A B C
|
|
242
|
+
const windingNumber: number = Triangle.utils.determinant(A, B, C);
|
|
243
|
+
// console.log("vertIndex", vertIndex, "windingNumber", windingNumber);
|
|
244
|
+
return windingNumber < 0;
|
|
245
|
+
}
|
|
246
|
+
|
|
123
247
|
/**
|
|
124
248
|
* Get the polygon vertex at the given position (index).
|
|
125
249
|
*
|
|
@@ -130,15 +254,18 @@ export class Polygon implements SVGSerializable {
|
|
|
130
254
|
* - getVertexAt( vertices.length + k ) == getVertexAt( k )
|
|
131
255
|
* - getVertexAt( -k ) == getVertexAt( vertices.length -k )
|
|
132
256
|
*
|
|
133
|
-
* @
|
|
257
|
+
* @method getVertexAt
|
|
134
258
|
* @param {number} index - The index of the desired vertex.
|
|
135
259
|
* @instance
|
|
136
260
|
* @memberof Polygon
|
|
137
261
|
* @return {Vertex} At the given index.
|
|
138
262
|
**/
|
|
139
263
|
getVertexAt(index: number): Vertex {
|
|
140
|
-
if (index < 0)
|
|
141
|
-
|
|
264
|
+
if (index < 0) {
|
|
265
|
+
return this.vertices[this.vertices.length - (Math.abs(index) % this.vertices.length)];
|
|
266
|
+
} else {
|
|
267
|
+
return this.vertices[index % this.vertices.length];
|
|
268
|
+
}
|
|
142
269
|
}
|
|
143
270
|
|
|
144
271
|
/**
|
|
@@ -164,7 +291,7 @@ export class Polygon implements SVGSerializable {
|
|
|
164
291
|
* https://stackoverflow.com/questions/22521982/check-if-point-inside-a-polygon
|
|
165
292
|
*
|
|
166
293
|
* @method containsVert
|
|
167
|
-
* @param {XYCoords} vert - The vertex to check.
|
|
294
|
+
* @param {XYCoords} vert - The vertex to check.
|
|
168
295
|
* @return {boolean} True if the passed vertex is inside this polygon. The polygon is considered closed.
|
|
169
296
|
* @instance
|
|
170
297
|
* @memberof Polygon
|
|
@@ -185,6 +312,21 @@ export class Polygon implements SVGSerializable {
|
|
|
185
312
|
return inside;
|
|
186
313
|
}
|
|
187
314
|
|
|
315
|
+
/**
|
|
316
|
+
* Check if all given vertices are inside this polygon.<br>
|
|
317
|
+
* <br>
|
|
318
|
+
* This method just uses the `Polygon.containsVert` method.
|
|
319
|
+
*
|
|
320
|
+
* @method containsVerts
|
|
321
|
+
* @param {XYCoords[]} verts - The vertices to check.
|
|
322
|
+
* @return {boolean} True if all passed vertices are inside this polygon. The polygon is considered closed.
|
|
323
|
+
* @instance
|
|
324
|
+
* @memberof Polygon
|
|
325
|
+
**/
|
|
326
|
+
containsVerts(verts: XYCoords[]): boolean {
|
|
327
|
+
return verts.every((vert: XYCoords) => this.containsVert(vert));
|
|
328
|
+
}
|
|
329
|
+
|
|
188
330
|
/**
|
|
189
331
|
* Check if the passed polygon is completly contained inside this polygon.
|
|
190
332
|
*
|
|
@@ -250,7 +392,8 @@ export class Polygon implements SVGSerializable {
|
|
|
250
392
|
* @return {boolean}
|
|
251
393
|
*/
|
|
252
394
|
isClockwise(): boolean {
|
|
253
|
-
return Polygon.utils.signedArea(this.vertices) < 0;
|
|
395
|
+
// return Polygon.utils.signedArea(this.vertices) < 0;
|
|
396
|
+
return Polygon.utils.isClockwise(this.vertices);
|
|
254
397
|
}
|
|
255
398
|
|
|
256
399
|
/**
|
|
@@ -311,9 +454,68 @@ export class Polygon implements SVGSerializable {
|
|
|
311
454
|
return this;
|
|
312
455
|
}
|
|
313
456
|
|
|
457
|
+
/**
|
|
458
|
+
* Get the mean `center` of this polygon by calculating the mean value of all vertices.
|
|
459
|
+
*
|
|
460
|
+
* Mean: (v[0] + v[1] + ... v[n-1]) / n
|
|
461
|
+
*
|
|
462
|
+
* @method getMeanCenter
|
|
463
|
+
* @instance
|
|
464
|
+
* @memberof Polygon
|
|
465
|
+
* @return {Vertex|null} `null` is no vertices are available.
|
|
466
|
+
*/
|
|
467
|
+
getMeanCenter(): Vertex | null {
|
|
468
|
+
if (this.vertices.length === 0) {
|
|
469
|
+
return null;
|
|
470
|
+
}
|
|
471
|
+
const center: Vertex = this.vertices[0].clone();
|
|
472
|
+
for (var i = 1; i < this.vertices.length; i++) {
|
|
473
|
+
center.add(this.vertices[i]);
|
|
474
|
+
}
|
|
475
|
+
center.x /= this.vertices.length;
|
|
476
|
+
center.y /= this.vertices.length;
|
|
477
|
+
return center;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Get centroid.
|
|
482
|
+
* Centroids define the barycenter of any non self-intersecting convex polygon.
|
|
483
|
+
*
|
|
484
|
+
* If the polygon is self intersecting or non konvex then the barycenter is not well defined.
|
|
485
|
+
*
|
|
486
|
+
* https://mathworld.wolfram.com/PolygonCentroid.html
|
|
487
|
+
*
|
|
488
|
+
* @method getCentroid
|
|
489
|
+
* @instance
|
|
490
|
+
* @memberof Polygon
|
|
491
|
+
* @returns {Vertex|null}
|
|
492
|
+
*/
|
|
493
|
+
getCentroid(): Vertex | null {
|
|
494
|
+
if (this.vertices.length === 0) {
|
|
495
|
+
return null;
|
|
496
|
+
}
|
|
497
|
+
const center: Vertex = new Vertex(0.0, 0.0);
|
|
498
|
+
const n = this.vertices.length;
|
|
499
|
+
for (var i = 0; i < n; i++) {
|
|
500
|
+
// center.add(this.vertices[i]);
|
|
501
|
+
const cur: Vertex = this.vertices[i];
|
|
502
|
+
const next: Vertex = this.vertices[(i + 1) % n];
|
|
503
|
+
var factor: number = cur.x * next.y - next.x * cur.y;
|
|
504
|
+
center.x += (cur.x + next.x) * factor;
|
|
505
|
+
center.y += (cur.y + next.y) * factor;
|
|
506
|
+
}
|
|
507
|
+
const area = this.area();
|
|
508
|
+
center.x *= 1 / (6 * area);
|
|
509
|
+
center.y *= 1 / (6 * area);
|
|
510
|
+
return center;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
//--- BEGIN --- Implement interface `Intersectable`
|
|
314
514
|
/**
|
|
315
515
|
* Get all line intersections with this polygon.
|
|
316
516
|
*
|
|
517
|
+
* This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.
|
|
518
|
+
*
|
|
317
519
|
* See demo `47-closest-vector-projection-on-polygon` for how it works.
|
|
318
520
|
*
|
|
319
521
|
* @param {VertTuple} line - The line to find intersections with.
|
|
@@ -322,23 +524,28 @@ export class Polygon implements SVGSerializable {
|
|
|
322
524
|
*/
|
|
323
525
|
lineIntersections(line: VertTuple<any>, inVectorBoundsOnly: boolean = false): Array<Vertex> {
|
|
324
526
|
// Find the intersections of all lines inside the edge bounds
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
527
|
+
return Polygon.utils
|
|
528
|
+
.locateLineIntersecion(line, this.vertices, this.isOpen, inVectorBoundsOnly)
|
|
529
|
+
.map(intersectionTuple => intersectionTuple.intersectionPoint);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Get all line intersections of this polygon and their tangents along the shape.
|
|
534
|
+
*
|
|
535
|
+
* This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.
|
|
536
|
+
*
|
|
537
|
+
* @param line
|
|
538
|
+
* @param inVectorBoundsOnly
|
|
539
|
+
* @returns
|
|
540
|
+
*/
|
|
541
|
+
lineIntersectionTangents(line: VertTuple<any>, inVectorBoundsOnly: boolean = false): Array<Vector> {
|
|
542
|
+
// Find the intersection tangents of all lines inside the edge bounds
|
|
543
|
+
return Polygon.utils.locateLineIntersecion(line, this.vertices, this.isOpen, inVectorBoundsOnly).map(intersectionTuple => {
|
|
544
|
+
const polyLine = this.getEdgeAt(intersectionTuple.edgeIndex);
|
|
545
|
+
return new Vector(polyLine.a.clone(), polyLine.b.clone()).moveTo(intersectionTuple.intersectionPoint) as Vector;
|
|
546
|
+
});
|
|
341
547
|
}
|
|
548
|
+
//--- END --- Implement interface `Intersectable`
|
|
342
549
|
|
|
343
550
|
/**
|
|
344
551
|
* Get the closest line-polygon-intersection point (closest the line point A).
|
|
@@ -445,6 +652,7 @@ export class Polygon implements SVGSerializable {
|
|
|
445
652
|
return result;
|
|
446
653
|
}
|
|
447
654
|
|
|
655
|
+
//--- BEGIN --- Implement interface `IBounded`
|
|
448
656
|
/**
|
|
449
657
|
* Get the bounding box (bounds) of this polygon.
|
|
450
658
|
*
|
|
@@ -456,10 +664,14 @@ export class Polygon implements SVGSerializable {
|
|
|
456
664
|
getBounds(): Bounds {
|
|
457
665
|
return Bounds.computeFromVertices(this.vertices);
|
|
458
666
|
}
|
|
667
|
+
//--- END --- Implement interface `IBounded`
|
|
459
668
|
|
|
460
669
|
/**
|
|
461
670
|
* Create a deep copy of this polygon.
|
|
462
671
|
*
|
|
672
|
+
* @method clone
|
|
673
|
+
* @instance
|
|
674
|
+
* @memberof Polygon
|
|
463
675
|
* @return {Polygon} The cloned polygon.
|
|
464
676
|
*/
|
|
465
677
|
clone(): Polygon {
|
|
@@ -469,6 +681,56 @@ export class Polygon implements SVGSerializable {
|
|
|
469
681
|
);
|
|
470
682
|
}
|
|
471
683
|
|
|
684
|
+
/**
|
|
685
|
+
* Create a new polygon without colinear adjacent edges. This method does not midify the current polygon
|
|
686
|
+
* but creates a new one.
|
|
687
|
+
*
|
|
688
|
+
* Please note that this method does NOT create deep clones of the vertices. Use Polygon.clone() if you need to.
|
|
689
|
+
*
|
|
690
|
+
* Please also note that the `tolerance` may become really large here, as the denominator of two closely
|
|
691
|
+
* parallel lines is usually pretty large. See the demo `57-eliminate-colinear-polygon-edges` to get
|
|
692
|
+
* an impression of how denominators work.
|
|
693
|
+
*
|
|
694
|
+
* @method elimitateColinearEdges
|
|
695
|
+
* @instance
|
|
696
|
+
* @memberof Polygon
|
|
697
|
+
* @param {number?} tolerance - (default is 1.0) The epsilon to detect co-linear edges.
|
|
698
|
+
* @return {Polygon} A new polygon without co-linear adjacent edges – respective the given epsilon.
|
|
699
|
+
*/
|
|
700
|
+
elimitateColinearEdges(tolerance?: number): Polygon {
|
|
701
|
+
const eps: number = typeof tolerance === "undefined" ? 1.0 : tolerance;
|
|
702
|
+
const verts: Array<Vertex> = this.vertices.slice(); // Creates a shallow copy
|
|
703
|
+
let i: number = 0;
|
|
704
|
+
var lineA: Line = new Line(new Vertex(), new Vertex());
|
|
705
|
+
var lineB: Line = new Line(new Vertex(), new Vertex());
|
|
706
|
+
while (i + 1 < verts.length && verts.length > 2) {
|
|
707
|
+
const vertA = verts[i];
|
|
708
|
+
const vertB = verts[(i + 1) % verts.length];
|
|
709
|
+
lineA.a = vertA;
|
|
710
|
+
lineA.b = vertB;
|
|
711
|
+
lineB.a = vertB;
|
|
712
|
+
let areColinear: boolean = false;
|
|
713
|
+
let j = i + 2;
|
|
714
|
+
do {
|
|
715
|
+
let vertC: Vertex = verts[j % verts.length];
|
|
716
|
+
lineB.b = vertC;
|
|
717
|
+
areColinear = lineA.colinear(lineB, eps);
|
|
718
|
+
// console.log("are colinear?", i, i + 1, j, areColinear);
|
|
719
|
+
if (areColinear) {
|
|
720
|
+
j++;
|
|
721
|
+
}
|
|
722
|
+
} while (areColinear);
|
|
723
|
+
// Now j points to the first vertex that's NOT colinear to the current lineA
|
|
724
|
+
// -> delete all vertices in between
|
|
725
|
+
if (j - i > 2) {
|
|
726
|
+
// Means: there have been 'colinear vertices' in between
|
|
727
|
+
verts.splice(i + 1, j - i - 2);
|
|
728
|
+
}
|
|
729
|
+
i++;
|
|
730
|
+
}
|
|
731
|
+
return new Polygon(verts, this.isOpen);
|
|
732
|
+
}
|
|
733
|
+
|
|
472
734
|
/**
|
|
473
735
|
* Convert this polygon to a sequence of quadratic Bézier curves.<br>
|
|
474
736
|
* <br>
|
|
@@ -572,7 +834,9 @@ export class Polygon implements SVGSerializable {
|
|
|
572
834
|
**/
|
|
573
835
|
toCubicBezierSVGString(threshold: number): string {
|
|
574
836
|
var qdata: Array<Vertex> = this.toCubicBezierData(threshold);
|
|
575
|
-
if (qdata.length == 0)
|
|
837
|
+
if (qdata.length == 0) {
|
|
838
|
+
return "";
|
|
839
|
+
}
|
|
576
840
|
var buffer = ["M " + qdata[0].x + " " + qdata[0].y];
|
|
577
841
|
for (var i = 1; i < qdata.length; i += 3) {
|
|
578
842
|
buffer.push(
|
|
@@ -650,6 +914,10 @@ export class Polygon implements SVGSerializable {
|
|
|
650
914
|
return Math.abs(total);
|
|
651
915
|
},
|
|
652
916
|
|
|
917
|
+
isClockwise(vertices: Array<XYCoords>): boolean {
|
|
918
|
+
return Polygon.utils.signedArea(vertices) < 0;
|
|
919
|
+
},
|
|
920
|
+
|
|
653
921
|
/**
|
|
654
922
|
* Calulate the signed polyon area by interpreting the polygon as a matrix
|
|
655
923
|
* and calculating its determinant.
|
|
@@ -665,6 +933,40 @@ export class Polygon implements SVGSerializable {
|
|
|
665
933
|
sum += (vertices[j].x - vertices[i].x) * (vertices[i].y + vertices[j].y);
|
|
666
934
|
}
|
|
667
935
|
return sum;
|
|
936
|
+
},
|
|
937
|
+
|
|
938
|
+
/**
|
|
939
|
+
* Find intersections of a line with a polygon (vertices).
|
|
940
|
+
*
|
|
941
|
+
* @param {VertTuple<any>} line - The line to find intersections with.
|
|
942
|
+
* @param {Array<Vertex>} vertices - The polygon's vertices.
|
|
943
|
+
* @param {boolean} isOpen - True if the polygon is open, false otherwise.
|
|
944
|
+
* @param {boolean} inVectorBoundsOnly - If only intersections in strict vector bounds should be returned.
|
|
945
|
+
* @returns
|
|
946
|
+
*/
|
|
947
|
+
locateLineIntersecion(
|
|
948
|
+
line: VertTuple<any>,
|
|
949
|
+
vertices: Array<Vertex>,
|
|
950
|
+
isOpen: boolean,
|
|
951
|
+
inVectorBoundsOnly: boolean
|
|
952
|
+
): Array<{ edgeIndex: number; intersectionPoint: Vertex }> {
|
|
953
|
+
// Find the intersections of all lines inside the edge bounds
|
|
954
|
+
const intersectionPoints: Array<{ edgeIndex: number; intersectionPoint: Vertex }> = [];
|
|
955
|
+
var n = isOpen ? vertices.length - 1 : vertices.length;
|
|
956
|
+
for (var i = 0; i < n; i++) {
|
|
957
|
+
const polyLine = new Line(vertices[i % n], vertices[(i + 1) % n]);
|
|
958
|
+
const intersection = polyLine.intersection(line);
|
|
959
|
+
// true => only inside bounds
|
|
960
|
+
// ignore last edge if open
|
|
961
|
+
if (
|
|
962
|
+
intersection !== null &&
|
|
963
|
+
polyLine.hasPoint(intersection, true) &&
|
|
964
|
+
(!inVectorBoundsOnly || line.hasPoint(intersection, inVectorBoundsOnly))
|
|
965
|
+
) {
|
|
966
|
+
intersectionPoints.push({ edgeIndex: i, intersectionPoint: intersection });
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
return intersectionPoints;
|
|
668
970
|
}
|
|
669
971
|
};
|
|
670
972
|
}
|
package/src/ts/Triangle.ts
CHANGED
|
@@ -21,7 +21,13 @@
|
|
|
21
21
|
* @modified 2021-01-22 Always updating circumcircle when retieving it.
|
|
22
22
|
* @modified 2022-02-02 Added the `destroy` method.
|
|
23
23
|
* @modified 2022-02-02 Cleared the `Triangle.toSVGString` function (deprecated). Use `drawutilssvg` instead.
|
|
24
|
-
* @
|
|
24
|
+
* @modified 2024-11-22 Added static utility function Triangle.utils.determinant; adapted method `determinant`.
|
|
25
|
+
* @modified 2024-11-22 Changing visibility of `Triangle.utils` from `private` to `public`.
|
|
26
|
+
* @modified 2025-14-16 Class `Triangle` now implements interface `Intersectable`.
|
|
27
|
+
* @modified 2025-14-16 Class `Triangle` now implements interface `IBounded`.
|
|
28
|
+
* @modified 2025-14-16 Class `Triangle` now implements interface `Intersectable`.
|
|
29
|
+
* @modified 2025-14-16 Added method `Triangle.move`.
|
|
30
|
+
* @version 2.10.0
|
|
25
31
|
*
|
|
26
32
|
* @file Triangle
|
|
27
33
|
* @fileoverview A simple triangle class: three vertices.
|
|
@@ -33,9 +39,11 @@ import { Circle } from "./Circle";
|
|
|
33
39
|
import { Line } from "./Line";
|
|
34
40
|
import { Polygon } from "./Polygon";
|
|
35
41
|
import { UIDGenerator } from "./UIDGenerator";
|
|
42
|
+
import { Vector } from "./Vector";
|
|
43
|
+
import { VertTuple } from "./VertTuple";
|
|
36
44
|
import { Vertex } from "./Vertex";
|
|
37
45
|
import { geomutils } from "./geomutils";
|
|
38
|
-
import { SVGSerializable, UID } from "./interfaces";
|
|
46
|
+
import { IBounded, Intersectable, SVGSerializable, UID, XYCoords } from "./interfaces";
|
|
39
47
|
|
|
40
48
|
/**
|
|
41
49
|
* @classdesc A triangle class for triangulations.
|
|
@@ -54,7 +62,7 @@ import { SVGSerializable, UID } from "./interfaces";
|
|
|
54
62
|
* @requires geomutils
|
|
55
63
|
*
|
|
56
64
|
*/
|
|
57
|
-
export class Triangle implements SVGSerializable {
|
|
65
|
+
export class Triangle implements IBounded, SVGSerializable, Intersectable {
|
|
58
66
|
/**
|
|
59
67
|
* Required to generate proper CSS classes and other class related IDs.
|
|
60
68
|
**/
|
|
@@ -213,6 +221,37 @@ export class Triangle implements SVGSerializable {
|
|
|
213
221
|
return this;
|
|
214
222
|
}
|
|
215
223
|
|
|
224
|
+
//--- BEGIN --- Implement interface `IBounded`
|
|
225
|
+
/**
|
|
226
|
+
* Get the bounding box (bounds) of this Triangle.
|
|
227
|
+
*
|
|
228
|
+
* @method getBounds
|
|
229
|
+
* @instance
|
|
230
|
+
* @memberof Triangle
|
|
231
|
+
* @return {Bounds} The rectangular bounds of this Triangle.
|
|
232
|
+
**/
|
|
233
|
+
getBounds(): Bounds {
|
|
234
|
+
// return Bounds.computeFromVertices([this.a, this.b, this.c]);
|
|
235
|
+
return this.bounds();
|
|
236
|
+
}
|
|
237
|
+
//--- END --- Implement interface `IBounded`
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Move the Triangle's vertices by the given amount.
|
|
241
|
+
*
|
|
242
|
+
* @method move
|
|
243
|
+
* @param {XYCoords} amount - The amount to move.
|
|
244
|
+
* @instance
|
|
245
|
+
* @memberof Triangle
|
|
246
|
+
* @return {Triangle} this for chaining
|
|
247
|
+
**/
|
|
248
|
+
move(amount: XYCoords): Triangle {
|
|
249
|
+
this.a.add(amount);
|
|
250
|
+
this.b.add(amount);
|
|
251
|
+
this.c.add(amount);
|
|
252
|
+
return this;
|
|
253
|
+
}
|
|
254
|
+
|
|
216
255
|
/**
|
|
217
256
|
* Get the circumcircle of this triangle.
|
|
218
257
|
*
|
|
@@ -350,6 +389,51 @@ export class Triangle implements SVGSerializable {
|
|
|
350
389
|
);
|
|
351
390
|
}
|
|
352
391
|
|
|
392
|
+
//--- BEGIN --- Implement interface `Intersectable`
|
|
393
|
+
/**
|
|
394
|
+
* Get all line intersections with this polygon.
|
|
395
|
+
*
|
|
396
|
+
* This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.
|
|
397
|
+
*
|
|
398
|
+
* See demo `47-closest-vector-projection-on-polygon` for how it works.
|
|
399
|
+
*
|
|
400
|
+
* @param {VertTuple} line - The line to find intersections with.
|
|
401
|
+
* @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).
|
|
402
|
+
* @returns {Array<Vertex>} - An array of all intersections within the polygon bounds.
|
|
403
|
+
*/
|
|
404
|
+
lineIntersections(line: VertTuple<any>, inVectorBoundsOnly: boolean = false): Array<Vertex> {
|
|
405
|
+
// Find the intersections of all lines inside the edge bounds
|
|
406
|
+
return Polygon.utils
|
|
407
|
+
.locateLineIntersecion(line, [this.a, this.b, this.c], false, inVectorBoundsOnly)
|
|
408
|
+
.map(intersectionTuple => intersectionTuple.intersectionPoint);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Get all line intersections of this polygon and their tangents along the shape.
|
|
413
|
+
*
|
|
414
|
+
* This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.
|
|
415
|
+
*
|
|
416
|
+
* @param line
|
|
417
|
+
* @param inVectorBoundsOnly
|
|
418
|
+
* @returns
|
|
419
|
+
*/
|
|
420
|
+
lineIntersectionTangents(line: VertTuple<any>, inVectorBoundsOnly: boolean = false): Array<Vector> {
|
|
421
|
+
// Find the intersection tangents of all lines inside the edge bounds
|
|
422
|
+
return Polygon.utils
|
|
423
|
+
.locateLineIntersecion(line, [this.a, this.b, this.c], false, inVectorBoundsOnly)
|
|
424
|
+
.map(intersectionTuple => {
|
|
425
|
+
// const polyLine = this.getEdgeAt(intersectionTuple.edgeIndex);
|
|
426
|
+
const polyLine = this.getEdgeAt(intersectionTuple.edgeIndex);
|
|
427
|
+
return new Vector(polyLine.a.clone(), polyLine.b.clone()).moveTo(intersectionTuple.intersectionPoint) as Vector;
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
//--- END --- Implement interface `Intersectable`
|
|
431
|
+
|
|
432
|
+
getEdgeAt(edgeIndex: number): Line {
|
|
433
|
+
var modIndex = edgeIndex % 3;
|
|
434
|
+
return modIndex === 0 ? new Line(this.a, this.b) : modIndex === 1 ? new Line(this.b, this.c) : new Line(this.c, this.a);
|
|
435
|
+
}
|
|
436
|
+
|
|
353
437
|
/**
|
|
354
438
|
* Convert this triangle to a polygon instance.
|
|
355
439
|
*
|
|
@@ -374,7 +458,8 @@ export class Triangle implements SVGSerializable {
|
|
|
374
458
|
*/
|
|
375
459
|
determinant(): number {
|
|
376
460
|
// (b.y - a.y)*(c.x - b.x) - (c.y - b.y)*(b.x - a.x);
|
|
377
|
-
return (this.b.y - this.a.y) * (this.c.x - this.b.x) - (this.c.y - this.b.y) * (this.b.x - this.a.x);
|
|
461
|
+
// return (this.b.y - this.a.y) * (this.c.x - this.b.x) - (this.c.y - this.b.y) * (this.b.x - this.a.x);
|
|
462
|
+
return Triangle.utils.determinant(this.a, this.b, this.c);
|
|
378
463
|
}
|
|
379
464
|
|
|
380
465
|
/**
|
|
@@ -464,7 +549,7 @@ export class Triangle implements SVGSerializable {
|
|
|
464
549
|
this.isDestroyed = true;
|
|
465
550
|
}
|
|
466
551
|
|
|
467
|
-
|
|
552
|
+
public static utils = {
|
|
468
553
|
// Used in the bounds() function.
|
|
469
554
|
max3(a: number, b: number, c: number): number {
|
|
470
555
|
return a >= b && a >= c ? a : b >= a && b >= c ? b : c;
|
|
@@ -500,6 +585,17 @@ export class Triangle implements SVGSerializable {
|
|
|
500
585
|
var t: number = (1 / (2 * area)) * (p0x * p1y - p0y * p1x + (p0y - p1y) * px + (p1x - p0x) * py);
|
|
501
586
|
|
|
502
587
|
return s > 0 && t > 0 && 1 - s - t > 0;
|
|
588
|
+
},
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* Calculate the determinant of the three vertices a, b and c (in this order).
|
|
592
|
+
* @param {XYCords} a - The first vertex.
|
|
593
|
+
* @param {XYCords} b - The first vertex.
|
|
594
|
+
* @param {XYCords} c - The first vertex.
|
|
595
|
+
* @returns {nmber}
|
|
596
|
+
*/
|
|
597
|
+
determinant(a: XYCoords, b: XYCoords, c: XYCoords): number {
|
|
598
|
+
return (b.y - a.y) * (c.x - b.x) - (c.y - b.y) * (b.x - a.x);
|
|
503
599
|
}
|
|
504
600
|
};
|
|
505
601
|
}
|