plotboilerplate 1.23.2 → 1.23.3
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/dist/index.esm.js +7052 -6754
- 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 +329 -27
- package/dist/plotboilerplate.min.js +1 -1
- package/package.json +4 -2
- package/src/cjs/PlotBoilerplate.d.ts +4 -2
- package/src/cjs/PlotBoilerplate.js +7 -3
- package/src/cjs/PlotBoilerplate.js.map +1 -1
- package/src/cjs/Polygon.d.ts +107 -4
- package/src/cjs/Polygon.js +215 -9
- package/src/cjs/Polygon.js.map +1 -1
- package/src/cjs/Triangle.d.ts +23 -3
- package/src/cjs/Triangle.js +15 -2
- package/src/cjs/Triangle.js.map +1 -1
- package/src/cjs/VertTuple.d.ts +12 -7
- package/src/cjs/VertTuple.js +14 -9
- package/src/cjs/VertTuple.js.map +1 -1
- package/src/cjs/Vertex.d.ts +2 -1
- package/src/cjs/Vertex.js +5 -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/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/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/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/esm/PlotBoilerplate.d.ts +4 -2
- package/src/esm/PlotBoilerplate.js +7 -3
- package/src/esm/PlotBoilerplate.js.map +1 -1
- package/src/esm/Polygon.d.ts +107 -4
- package/src/esm/Polygon.js +214 -9
- package/src/esm/Polygon.js.map +1 -1
- package/src/esm/Triangle.d.ts +23 -3
- package/src/esm/Triangle.js +15 -2
- package/src/esm/Triangle.js.map +1 -1
- package/src/esm/VertTuple.d.ts +12 -7
- package/src/esm/VertTuple.js +14 -9
- package/src/esm/VertTuple.js.map +1 -1
- package/src/esm/Vertex.d.ts +2 -1
- package/src/esm/Vertex.js +5 -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/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/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/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/ts/PlotBoilerplate.ts +7 -3
- package/src/ts/Polygon.ts +230 -9
- package/src/ts/Triangle.ts +18 -4
- package/src/ts/VertTuple.ts +15 -10
- package/src/ts/Vertex.ts +5 -2
- package/src/ts/draw.ts +2 -1
- package/src/ts/drawutilssvg.ts +29 -0
- package/src/ts/geomutils.ts +49 -1
- package/src/ts/utils/algorithms/PolygonInset.ts +529 -0
- package/src/ts/utils/algorithms/clearDuplicateVertices.ts +11 -8
- package/src/ts/utils/algorithms/findPolygonSelfIntersections.ts +25 -26
- package/src/ts/utils/algorithms/splitPolygonToNonIntersecting.ts +92 -99
- package/src/ts/utils/detectDarkMode.ts +1 -3
- package/src/ts/utils/dom/guiSizeToggler.ts +4 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"splitPolygonToNonIntersecting.js","sourceRoot":"","sources":["../../../ts/utils/algorithms/splitPolygonToNonIntersecting.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"splitPolygonToNonIntersecting.js","sourceRoot":"","sources":["../../../ts/utils/algorithms/splitPolygonToNonIntersecting.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detectDarkMode.js","sourceRoot":"","sources":["../../ts/utils/detectDarkMode.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"detectDarkMode.js","sourceRoot":"","sources":["../../ts/utils/detectDarkMode.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAA4B,EAAW,EAAE;IACtE,oBAAoB;IACpB,IAAI,OAAO,GAAG,KAAK,WAAW,IAAI,GAAG,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QACpF,iFAAiF;QACjF,MAAM,aAAa,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;QACpD,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;YAC3B,OAAO,aAAa,CAAC;QACvB,CAAC;IACH,CAAC;IACD,IAAI,UAAU,CAAC,UAAU,IAAI,UAAU,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,OAAO,EAAE,CAAC;QAC3F,sBAAsB;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,6BAA6B;IAC7B,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;IACpC,MAAM,SAAS,GAAG,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;IAC1C,OAAO,CAAC,SAAS,CAAC;AACpB,CAAC,CAAC"}
|
|
@@ -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
|
import { GUI } from "../../interfaces/externals";
|
|
11
12
|
interface ITogglerConfig {
|
|
@@ -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
|
* @param {GUI} gui - The GUI (compatible with dat.gui and lil-gui).
|
|
@@ -28,7 +29,8 @@ const applyGuiSize = (gui, guiDoubleSize, cssProps) => {
|
|
|
28
29
|
gui.domElement.style["transform"] = transform + "scale(1.0)";
|
|
29
30
|
}
|
|
30
31
|
};
|
|
31
|
-
export const guiSizeToggler
|
|
32
|
+
export const guiSizeToggler = (gui, config, cssProps) => {
|
|
33
|
+
gui.domElement.style["transition"] = "transform 0.5s";
|
|
32
34
|
return {
|
|
33
35
|
update: function () {
|
|
34
36
|
applyGuiSize(gui, Boolean(config.guiDoubleSize), cssProps);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guiSizeToggler.js","sourceRoot":"","sources":["../../../ts/utils/dom/guiSizeToggler.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"guiSizeToggler.js","sourceRoot":"","sources":["../../../ts/utils/dom/guiSizeToggler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH;;;;GAIG;AACH,MAAM,YAAY,GAAG,CAAC,GAAQ,EAAE,aAAsB,EAAE,QAAgC,EAAE,EAAE;IAC1F,IAAI,QAAQ,IAAI,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,kBAAkB,CAAC,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IACzE,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,kBAAkB,CAAC,GAAG,SAAS,CAAC;IACvD,CAAC;IAED,MAAM,SAAS,GAAG,QAAQ,IAAI,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAEtG,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACpC,IAAI,aAAa,EAAE,CAAC;QAClB,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,SAAS,GAAG,YAAY,CAAC;IAC/D,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,SAAS,GAAG,YAAY,CAAC;IAC/D,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAQ,EAAE,MAAsB,EAAE,QAAgC,EAAE,EAAE;IACnG,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,gBAAgB,CAAC;IACtD,OAAO;QACL,MAAM,EAAE;YACN,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC7D,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -85,8 +85,9 @@
|
|
|
85
85
|
* @modified 2023-09-29 Adding proper dicionary key and value types to the params of `PlotBoilerplate.utils.safeMergeByKeys` (was `object` before).
|
|
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
|
+
* @modified 2024-12-02 Adding the `triggerRedraw` to the `removeAll` method.
|
|
88
89
|
*
|
|
89
|
-
* @version 1.
|
|
90
|
+
* @version 1.20.0
|
|
90
91
|
*
|
|
91
92
|
* @file PlotBoilerplate
|
|
92
93
|
* @fileoverview The main class.
|
|
@@ -1032,16 +1033,19 @@ export class PlotBoilerplate {
|
|
|
1032
1033
|
*
|
|
1033
1034
|
* @method removeAll
|
|
1034
1035
|
* @param {boolean=false} keepVertices
|
|
1036
|
+
* @param {boolean=true} triggerRedraw - By default this method triggers the redraw routine; passing `false` will suppress redrawing.
|
|
1035
1037
|
* @instance
|
|
1036
1038
|
* @memberof PlotBoilerplate
|
|
1037
1039
|
* @return {void}
|
|
1038
1040
|
*/
|
|
1039
|
-
removeAll(keepVertices?: boolean) {
|
|
1041
|
+
removeAll(keepVertices?: boolean, triggerRedraw?: boolean) {
|
|
1040
1042
|
this.drawables = [];
|
|
1041
1043
|
if (!Boolean(keepVertices)) {
|
|
1042
1044
|
this.vertices = [];
|
|
1043
1045
|
}
|
|
1044
|
-
|
|
1046
|
+
if (triggerRedraw || typeof triggerRedraw === "undefined") {
|
|
1047
|
+
this.redraw();
|
|
1048
|
+
}
|
|
1045
1049
|
}
|
|
1046
1050
|
|
|
1047
1051
|
/**
|
package/src/ts/Polygon.ts
CHANGED
|
@@ -28,7 +28,11 @@
|
|
|
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
|
+
* @version 1.14.0
|
|
32
36
|
*
|
|
33
37
|
* @file Polygon
|
|
34
38
|
* @public
|
|
@@ -37,9 +41,11 @@
|
|
|
37
41
|
import { BezierPath } from "./BezierPath";
|
|
38
42
|
import { Bounds } from "./Bounds";
|
|
39
43
|
import { Line } from "./Line";
|
|
44
|
+
import { Triangle } from "./Triangle";
|
|
40
45
|
import { UIDGenerator } from "./UIDGenerator";
|
|
41
46
|
import { VertTuple } from "./VertTuple";
|
|
42
47
|
import { Vertex } from "./Vertex";
|
|
48
|
+
import { geomutils } from "./geomutils";
|
|
43
49
|
import { XYCoords, SVGSerializable, UID } from "./interfaces";
|
|
44
50
|
|
|
45
51
|
/**
|
|
@@ -103,7 +109,9 @@ export class Polygon implements SVGSerializable {
|
|
|
103
109
|
**/
|
|
104
110
|
constructor(vertices?: Array<Vertex>, isOpen?: boolean) {
|
|
105
111
|
this.uid = UIDGenerator.next();
|
|
106
|
-
if (typeof vertices == "undefined")
|
|
112
|
+
if (typeof vertices == "undefined") {
|
|
113
|
+
vertices = [];
|
|
114
|
+
}
|
|
107
115
|
this.vertices = vertices;
|
|
108
116
|
this.isOpen = isOpen || false;
|
|
109
117
|
}
|
|
@@ -111,7 +119,7 @@ export class Polygon implements SVGSerializable {
|
|
|
111
119
|
/**
|
|
112
120
|
* Add a vertex to the end of the `vertices` array.
|
|
113
121
|
*
|
|
114
|
-
* @method
|
|
122
|
+
* @method addVertex
|
|
115
123
|
* @param {Vertex} vert - The vertex to add.
|
|
116
124
|
* @instance
|
|
117
125
|
* @memberof Polygon
|
|
@@ -120,6 +128,117 @@ export class Polygon implements SVGSerializable {
|
|
|
120
128
|
this.vertices.push(vert);
|
|
121
129
|
}
|
|
122
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Add a vertex at a particular position of the `vertices` array.
|
|
133
|
+
*
|
|
134
|
+
* @method addVertexAt
|
|
135
|
+
* @param {Vertex} vert - The vertex to add.
|
|
136
|
+
* @param {number} index - The position to add the vertex at. Will be handled modulo.
|
|
137
|
+
* @instance
|
|
138
|
+
* @memberof Polygon
|
|
139
|
+
**/
|
|
140
|
+
addVertexAt(vert: Vertex, index: number): void {
|
|
141
|
+
// var moduloIndex = index % (this.vertices.length + 1);
|
|
142
|
+
this.vertices.splice(index, 0, vert);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Get a new instance of the line at the given start index. The returned line will consist
|
|
147
|
+
* of the vertex at `vertIndex` and `vertIndex+1` (will be handled modulo).
|
|
148
|
+
*
|
|
149
|
+
* @method getEdgeAt
|
|
150
|
+
* @param {number} vertIndex - The vertex index of the line to start.
|
|
151
|
+
* @instance
|
|
152
|
+
* @memberof Polygon
|
|
153
|
+
* @return {Line}
|
|
154
|
+
**/
|
|
155
|
+
getEdgeAt(vertIndex: number): Line {
|
|
156
|
+
return new Line(this.getVertexAt(vertIndex), this.getVertexAt(vertIndex + 1));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Converts this polygon into a sequence of lines. Please note that each time
|
|
161
|
+
* this method is called new lines are created. The underlying line vertices are no clones
|
|
162
|
+
* (instances).
|
|
163
|
+
*
|
|
164
|
+
* @method getEdges
|
|
165
|
+
* @instance
|
|
166
|
+
* @memberof Polygon
|
|
167
|
+
* @return {Array<Line>}
|
|
168
|
+
*/
|
|
169
|
+
getEdges(): Array<Line> {
|
|
170
|
+
const lines: Array<Line> = [];
|
|
171
|
+
for (var i = 0; i + 1 < this.vertices.length; i++) {
|
|
172
|
+
// var line = this.getLineAt(i).clone();
|
|
173
|
+
lines.push(this.getEdgeAt(i));
|
|
174
|
+
}
|
|
175
|
+
if (!this.isOpen && this.vertices.length > 0) {
|
|
176
|
+
lines.push(this.getEdgeAt(this.vertices.length - 1));
|
|
177
|
+
}
|
|
178
|
+
return lines;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Checks if the angle at the given polygon vertex (index) is acute. Please not that this is
|
|
183
|
+
* only working for clockwise polygons. If this polygon is not clockwise please use the
|
|
184
|
+
* `isClockwise` method and reverse polygon vertices if needed.
|
|
185
|
+
*
|
|
186
|
+
* @method isAngleAcute
|
|
187
|
+
* @instance
|
|
188
|
+
* @memberof Polygon
|
|
189
|
+
* @param {number} vertIndex - The index of the polygon vertex to check.
|
|
190
|
+
* @returns {boolean} `true` is angle is acute, `false` is obtuse.
|
|
191
|
+
*/
|
|
192
|
+
getInnerAngleAt(vertIndex: number): number {
|
|
193
|
+
const p2: Vertex = this.vertices[vertIndex];
|
|
194
|
+
const p1: Vertex = this.vertices[(vertIndex + this.vertices.length - 1) % this.vertices.length].clone();
|
|
195
|
+
const p3: Vertex = this.vertices[(vertIndex + 1) % this.vertices.length].clone();
|
|
196
|
+
|
|
197
|
+
// See
|
|
198
|
+
// https://math.stackexchange.com/questions/149959/how-to-find-the-interior-angle-of-an-irregular-pentagon-or-polygon
|
|
199
|
+
// π−arccos((P2−P1)⋅(P3−P2)|P2−P1||P3−P2|)
|
|
200
|
+
|
|
201
|
+
// Check if triangle is acute (will be used later)
|
|
202
|
+
// Acute angles and obtuse angles need to be handled differently.
|
|
203
|
+
const isAcute: boolean = this.isAngleAcute(vertIndex);
|
|
204
|
+
|
|
205
|
+
// Differences
|
|
206
|
+
const zero: Vertex = new Vertex(0, 0);
|
|
207
|
+
const p2mp1: Vertex = new Vertex(p2.x - p1.x, p2.y - p1.y);
|
|
208
|
+
const p3mp2: Vertex = new Vertex(p3.x - p2.x, p3.y - p2.y);
|
|
209
|
+
const p2mp1_len: number = zero.distance(p2mp1);
|
|
210
|
+
const p3mp2_len: number = zero.distance(p3mp2);
|
|
211
|
+
|
|
212
|
+
// Dot products
|
|
213
|
+
const dotProduct: number = geomutils.dotProduct(p2mp1, p3mp2);
|
|
214
|
+
const lengthProduct: number = p2mp1_len * p3mp2_len;
|
|
215
|
+
if (isAcute) {
|
|
216
|
+
return Math.PI - Math.acos(dotProduct / lengthProduct);
|
|
217
|
+
} else {
|
|
218
|
+
return Math.PI + Math.acos(dotProduct / lengthProduct);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Checks if the angle at the given polygon vertex (index) is acute.
|
|
224
|
+
*
|
|
225
|
+
* @method isAngleAcute
|
|
226
|
+
* @instance
|
|
227
|
+
* @memberof Polygon
|
|
228
|
+
* @param {number} vertIndex - The index of the polygon vertex to check.
|
|
229
|
+
* @returns {boolean} `true` is angle is acute, `false` is obtuse.
|
|
230
|
+
*/
|
|
231
|
+
isAngleAcute(vertIndex: number): boolean {
|
|
232
|
+
const A: Vertex = this.vertices[(vertIndex + this.vertices.length - 1) % this.vertices.length].clone();
|
|
233
|
+
const B: Vertex = this.vertices[vertIndex];
|
|
234
|
+
const C: Vertex = this.vertices[(vertIndex + 1) % this.vertices.length].clone();
|
|
235
|
+
|
|
236
|
+
// Find local winding number for triangle A B C
|
|
237
|
+
const windingNumber: number = Triangle.utils.determinant(A, B, C);
|
|
238
|
+
// console.log("vertIndex", vertIndex, "windingNumber", windingNumber);
|
|
239
|
+
return windingNumber < 0;
|
|
240
|
+
}
|
|
241
|
+
|
|
123
242
|
/**
|
|
124
243
|
* Get the polygon vertex at the given position (index).
|
|
125
244
|
*
|
|
@@ -130,15 +249,18 @@ export class Polygon implements SVGSerializable {
|
|
|
130
249
|
* - getVertexAt( vertices.length + k ) == getVertexAt( k )
|
|
131
250
|
* - getVertexAt( -k ) == getVertexAt( vertices.length -k )
|
|
132
251
|
*
|
|
133
|
-
* @
|
|
252
|
+
* @method getVertexAt
|
|
134
253
|
* @param {number} index - The index of the desired vertex.
|
|
135
254
|
* @instance
|
|
136
255
|
* @memberof Polygon
|
|
137
256
|
* @return {Vertex} At the given index.
|
|
138
257
|
**/
|
|
139
258
|
getVertexAt(index: number): Vertex {
|
|
140
|
-
if (index < 0)
|
|
141
|
-
|
|
259
|
+
if (index < 0) {
|
|
260
|
+
return this.vertices[this.vertices.length - (Math.abs(index) % this.vertices.length)];
|
|
261
|
+
} else {
|
|
262
|
+
return this.vertices[index % this.vertices.length];
|
|
263
|
+
}
|
|
142
264
|
}
|
|
143
265
|
|
|
144
266
|
/**
|
|
@@ -164,7 +286,7 @@ export class Polygon implements SVGSerializable {
|
|
|
164
286
|
* https://stackoverflow.com/questions/22521982/check-if-point-inside-a-polygon
|
|
165
287
|
*
|
|
166
288
|
* @method containsVert
|
|
167
|
-
* @param {XYCoords} vert - The vertex to check.
|
|
289
|
+
* @param {XYCoords} vert - The vertex to check.
|
|
168
290
|
* @return {boolean} True if the passed vertex is inside this polygon. The polygon is considered closed.
|
|
169
291
|
* @instance
|
|
170
292
|
* @memberof Polygon
|
|
@@ -185,6 +307,21 @@ export class Polygon implements SVGSerializable {
|
|
|
185
307
|
return inside;
|
|
186
308
|
}
|
|
187
309
|
|
|
310
|
+
/**
|
|
311
|
+
* Check if all given vertices are inside this polygon.<br>
|
|
312
|
+
* <br>
|
|
313
|
+
* This method just uses the `Polygon.containsVert` method.
|
|
314
|
+
*
|
|
315
|
+
* @method containsVerts
|
|
316
|
+
* @param {XYCoords[]} verts - The vertices to check.
|
|
317
|
+
* @return {boolean} True if all passed vertices are inside this polygon. The polygon is considered closed.
|
|
318
|
+
* @instance
|
|
319
|
+
* @memberof Polygon
|
|
320
|
+
**/
|
|
321
|
+
containsVerts(verts: XYCoords[]): boolean {
|
|
322
|
+
return verts.every((vert: XYCoords) => this.containsVert(vert));
|
|
323
|
+
}
|
|
324
|
+
|
|
188
325
|
/**
|
|
189
326
|
* Check if the passed polygon is completly contained inside this polygon.
|
|
190
327
|
*
|
|
@@ -250,7 +387,8 @@ export class Polygon implements SVGSerializable {
|
|
|
250
387
|
* @return {boolean}
|
|
251
388
|
*/
|
|
252
389
|
isClockwise(): boolean {
|
|
253
|
-
return Polygon.utils.signedArea(this.vertices) < 0;
|
|
390
|
+
// return Polygon.utils.signedArea(this.vertices) < 0;
|
|
391
|
+
return Polygon.utils.isClockwise(this.vertices);
|
|
254
392
|
}
|
|
255
393
|
|
|
256
394
|
/**
|
|
@@ -311,6 +449,29 @@ export class Polygon implements SVGSerializable {
|
|
|
311
449
|
return this;
|
|
312
450
|
}
|
|
313
451
|
|
|
452
|
+
/**
|
|
453
|
+
* Get the mean `center` of this polygon by calculating the mean value of all vertices.
|
|
454
|
+
*
|
|
455
|
+
* Mean: (v[0] + v[1] + ... v[n-1]) / n
|
|
456
|
+
*
|
|
457
|
+
* @method getMeanCenter
|
|
458
|
+
* @instance
|
|
459
|
+
* @memberof Polygon
|
|
460
|
+
* @return {Vertex|null} `null` is no vertices are available.
|
|
461
|
+
*/
|
|
462
|
+
getMeanCenter() {
|
|
463
|
+
if (this.vertices.length === 0) {
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
466
|
+
const center = this.vertices[0].clone();
|
|
467
|
+
for (var i = 1; i < this.vertices.length; i++) {
|
|
468
|
+
center.add(this.vertices[i]);
|
|
469
|
+
}
|
|
470
|
+
center.x /= this.vertices.length;
|
|
471
|
+
center.y /= this.vertices.length;
|
|
472
|
+
return center;
|
|
473
|
+
}
|
|
474
|
+
|
|
314
475
|
/**
|
|
315
476
|
* Get all line intersections with this polygon.
|
|
316
477
|
*
|
|
@@ -460,6 +621,9 @@ export class Polygon implements SVGSerializable {
|
|
|
460
621
|
/**
|
|
461
622
|
* Create a deep copy of this polygon.
|
|
462
623
|
*
|
|
624
|
+
* @method clone
|
|
625
|
+
* @instance
|
|
626
|
+
* @memberof Polygon
|
|
463
627
|
* @return {Polygon} The cloned polygon.
|
|
464
628
|
*/
|
|
465
629
|
clone(): Polygon {
|
|
@@ -469,6 +633,57 @@ export class Polygon implements SVGSerializable {
|
|
|
469
633
|
);
|
|
470
634
|
}
|
|
471
635
|
|
|
636
|
+
/**
|
|
637
|
+
* Create a new polygon without colinear adjacent edges. This method does not midify the current polygon
|
|
638
|
+
* but creates a new one.
|
|
639
|
+
*
|
|
640
|
+
* Please note that this method does NOT create deep clones of the vertices. Use Polygon.clone() if you need to.
|
|
641
|
+
*
|
|
642
|
+
* Please also note that the `tolerance` may become really large here, as the denominator of two closely
|
|
643
|
+
* parallel lines is usually pretty large. See the demo `57-eliminate-colinear-polygon-edges` to get
|
|
644
|
+
* an impression of how denominators work.
|
|
645
|
+
*
|
|
646
|
+
* @method elimitateColinearEdges
|
|
647
|
+
* @instance
|
|
648
|
+
* @memberof Polygon
|
|
649
|
+
* @param {number?} tolerance - (default is 1.0) The epsilon to detect co-linear edges.
|
|
650
|
+
* @return {Polygon} A new polygon without co-linear adjacent edges – respective the given epsilon.
|
|
651
|
+
*/
|
|
652
|
+
elimitateColinearEdges(tolerance?: number): Polygon {
|
|
653
|
+
const eps: number = typeof tolerance === "undefined" ? 1.0 : tolerance;
|
|
654
|
+
const verts: Array<Vertex> = this.vertices.slice(); // Creates a shallow copy
|
|
655
|
+
let i: number = 0;
|
|
656
|
+
var lineA: Line = new Line(new Vertex(), new Vertex());
|
|
657
|
+
var lineB: Line = new Line(new Vertex(), new Vertex());
|
|
658
|
+
while (i + 1 < verts.length && verts.length > 2) {
|
|
659
|
+
const vertA = verts[i];
|
|
660
|
+
const vertB = verts[(i + 1) % verts.length];
|
|
661
|
+
lineA.a = vertA;
|
|
662
|
+
lineA.b = vertB;
|
|
663
|
+
lineB.a = vertB;
|
|
664
|
+
let areColinear: boolean = false;
|
|
665
|
+
let j = i + 2;
|
|
666
|
+
do {
|
|
667
|
+
let vertC: Vertex = verts[j % verts.length];
|
|
668
|
+
lineB.b = vertC;
|
|
669
|
+
areColinear = lineA.colinear(lineB, eps);
|
|
670
|
+
// console.log("are colinear?", i, i + 1, j, areColinear);
|
|
671
|
+
if (areColinear) {
|
|
672
|
+
j++;
|
|
673
|
+
}
|
|
674
|
+
} while (areColinear);
|
|
675
|
+
// Now j points to the first vertex that's NOT colinear to the current lineA
|
|
676
|
+
// -> delete all vertices in between
|
|
677
|
+
if (j - i > 2) {
|
|
678
|
+
// Means: there have been 'colinear vertices' in between
|
|
679
|
+
// console.log("Splice", "i", i, "j", j, i + 1, j - i - 1);
|
|
680
|
+
verts.splice(i + 1, j - i - 2);
|
|
681
|
+
}
|
|
682
|
+
i++;
|
|
683
|
+
}
|
|
684
|
+
return new Polygon(verts, this.isOpen);
|
|
685
|
+
}
|
|
686
|
+
|
|
472
687
|
/**
|
|
473
688
|
* Convert this polygon to a sequence of quadratic Bézier curves.<br>
|
|
474
689
|
* <br>
|
|
@@ -572,7 +787,9 @@ export class Polygon implements SVGSerializable {
|
|
|
572
787
|
**/
|
|
573
788
|
toCubicBezierSVGString(threshold: number): string {
|
|
574
789
|
var qdata: Array<Vertex> = this.toCubicBezierData(threshold);
|
|
575
|
-
if (qdata.length == 0)
|
|
790
|
+
if (qdata.length == 0) {
|
|
791
|
+
return "";
|
|
792
|
+
}
|
|
576
793
|
var buffer = ["M " + qdata[0].x + " " + qdata[0].y];
|
|
577
794
|
for (var i = 1; i < qdata.length; i += 3) {
|
|
578
795
|
buffer.push(
|
|
@@ -650,6 +867,10 @@ export class Polygon implements SVGSerializable {
|
|
|
650
867
|
return Math.abs(total);
|
|
651
868
|
},
|
|
652
869
|
|
|
870
|
+
isClockwise(vertices: Array<XYCoords>): boolean {
|
|
871
|
+
return Polygon.utils.signedArea(vertices) < 0;
|
|
872
|
+
},
|
|
873
|
+
|
|
653
874
|
/**
|
|
654
875
|
* Calulate the signed polyon area by interpreting the polygon as a matrix
|
|
655
876
|
* and calculating its determinant.
|
package/src/ts/Triangle.ts
CHANGED
|
@@ -21,7 +21,9 @@
|
|
|
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
|
+
* @version 2.8.0
|
|
25
27
|
*
|
|
26
28
|
* @file Triangle
|
|
27
29
|
* @fileoverview A simple triangle class: three vertices.
|
|
@@ -35,7 +37,7 @@ import { Polygon } from "./Polygon";
|
|
|
35
37
|
import { UIDGenerator } from "./UIDGenerator";
|
|
36
38
|
import { Vertex } from "./Vertex";
|
|
37
39
|
import { geomutils } from "./geomutils";
|
|
38
|
-
import { SVGSerializable, UID } from "./interfaces";
|
|
40
|
+
import { SVGSerializable, UID, XYCoords } from "./interfaces";
|
|
39
41
|
|
|
40
42
|
/**
|
|
41
43
|
* @classdesc A triangle class for triangulations.
|
|
@@ -374,7 +376,8 @@ export class Triangle implements SVGSerializable {
|
|
|
374
376
|
*/
|
|
375
377
|
determinant(): number {
|
|
376
378
|
// (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);
|
|
379
|
+
// 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);
|
|
380
|
+
return Triangle.utils.determinant(this.a, this.b, this.c);
|
|
378
381
|
}
|
|
379
382
|
|
|
380
383
|
/**
|
|
@@ -464,7 +467,7 @@ export class Triangle implements SVGSerializable {
|
|
|
464
467
|
this.isDestroyed = true;
|
|
465
468
|
}
|
|
466
469
|
|
|
467
|
-
|
|
470
|
+
public static utils = {
|
|
468
471
|
// Used in the bounds() function.
|
|
469
472
|
max3(a: number, b: number, c: number): number {
|
|
470
473
|
return a >= b && a >= c ? a : b >= a && b >= c ? b : c;
|
|
@@ -500,6 +503,17 @@ export class Triangle implements SVGSerializable {
|
|
|
500
503
|
var t: number = (1 / (2 * area)) * (p0x * p1y - p0y * p1x + (p0y - p1y) * px + (p1x - p0x) * py);
|
|
501
504
|
|
|
502
505
|
return s > 0 && t > 0 && 1 - s - t > 0;
|
|
506
|
+
},
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Calculate the determinant of the three vertices a, b and c (in this order).
|
|
510
|
+
* @param {XYCords} a - The first vertex.
|
|
511
|
+
* @param {XYCords} b - The first vertex.
|
|
512
|
+
* @param {XYCords} c - The first vertex.
|
|
513
|
+
* @returns {nmber}
|
|
514
|
+
*/
|
|
515
|
+
determinant(a: XYCoords, b: XYCoords, c: XYCoords): number {
|
|
516
|
+
return (b.y - a.y) * (c.x - b.x) - (c.y - b.y) * (b.x - a.x);
|
|
503
517
|
}
|
|
504
518
|
};
|
|
505
519
|
}
|
package/src/ts/VertTuple.ts
CHANGED
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
* @modified 2021-01-20 Added UID.
|
|
11
11
|
* @modified 2022-02-02 Added the `destroy` method.
|
|
12
12
|
* @modified 2023-09-29 Fixed a calculation error in the VertTuple.hasPoint() function; distance measure was broken!
|
|
13
|
-
* @
|
|
13
|
+
* @modified 2024-09-10 Chaging the first param of `pointDistance` from `Vertex` to less strict type `XYCoords`. This should not break anything.
|
|
14
|
+
* @modified 2024-09-10 Adding the optional `epsilon` param to the `hasPoint` method.
|
|
15
|
+
* @modified 2024-12-02 Added the `epsilon` param to the `colinear` method. Default is 1.0e-6.
|
|
16
|
+
* @version 1.3.0
|
|
14
17
|
*/
|
|
15
18
|
|
|
16
19
|
import { Vertex } from "./Vertex";
|
|
@@ -234,12 +237,13 @@ export class VertTuple<T extends VertTuple<T>> {
|
|
|
234
237
|
*
|
|
235
238
|
* @method colinear
|
|
236
239
|
* @param {VertTuple} line
|
|
240
|
+
* @param {epsilon?=1.0e-6} epsilon - The epsilon to use (default is 1.0e-6).
|
|
237
241
|
* @instance
|
|
238
242
|
* @memberof VertTuple
|
|
239
243
|
* @return true if both lines are co-linear.
|
|
240
244
|
*/
|
|
241
|
-
colinear(line: VertTuple<T
|
|
242
|
-
return Math.abs(this.denominator(line)) < Vertex.EPSILON;
|
|
245
|
+
colinear(line: VertTuple<T>, epsilon?: number): boolean {
|
|
246
|
+
return Math.abs(this.denominator(line)) < (typeof epsilon === "undefined" ? Vertex.EPSILON : epsilon);
|
|
243
247
|
}
|
|
244
248
|
|
|
245
249
|
/**
|
|
@@ -269,20 +273,21 @@ export class VertTuple<T extends VertTuple<T>> {
|
|
|
269
273
|
* that point is located between point `a` and `b`.
|
|
270
274
|
*
|
|
271
275
|
* @method hasPoint
|
|
272
|
-
* @param {Vertex} point The point to check.
|
|
273
|
-
* @param {boolean=} insideBoundsOnly If set to to true (default=false) the point must be between start and end point of the line.
|
|
276
|
+
* @param {Vertex} point - The point to check.
|
|
277
|
+
* @param {boolean=} insideBoundsOnly - [optional] If set to to true (default=false) the point must be between start and end point of the line.
|
|
278
|
+
* @param {number=Vertex.EPSILON} epsilon - [optional] A tolerance.
|
|
274
279
|
* @return {boolean} True if the given point is on this line.
|
|
275
280
|
* @instance
|
|
276
281
|
* @memberof VertTuple
|
|
277
282
|
*/
|
|
278
|
-
hasPoint(point: XYCoords, insideBoundsOnly?: boolean): boolean {
|
|
283
|
+
hasPoint(point: XYCoords, insideBoundsOnly?: boolean, epsilon?: number): boolean {
|
|
279
284
|
const t: number = this.getClosestT(point);
|
|
280
285
|
// Compare to pointDistance?
|
|
281
286
|
const distance: number = Math.sqrt(VertTuple.vtutils.dist2(point, this.vertAt(t)));
|
|
282
287
|
if (typeof insideBoundsOnly !== "undefined" && insideBoundsOnly) {
|
|
283
|
-
return distance < Vertex.EPSILON && t >= 0 && t <= 1;
|
|
288
|
+
return distance < (epsilon ?? Vertex.EPSILON) && t >= 0 && t <= 1;
|
|
284
289
|
} else {
|
|
285
|
-
return distance < Vertex.EPSILON; // t >= 0 && t <= 1;
|
|
290
|
+
return distance < (epsilon ?? Vertex.EPSILON); // t >= 0 && t <= 1;
|
|
286
291
|
}
|
|
287
292
|
}
|
|
288
293
|
|
|
@@ -304,12 +309,12 @@ export class VertTuple<T extends VertTuple<T>> {
|
|
|
304
309
|
* The the minimal distance between this line and the specified point.
|
|
305
310
|
*
|
|
306
311
|
* @method pointDistance
|
|
307
|
-
* @param {
|
|
312
|
+
* @param {XYCoords} p The point (vertex) to measre the distance to.
|
|
308
313
|
* @return {number} The absolute minimal distance.
|
|
309
314
|
* @instance
|
|
310
315
|
* @memberof VertTuple
|
|
311
316
|
**/
|
|
312
|
-
pointDistance(p:
|
|
317
|
+
pointDistance(p: XYCoords): number {
|
|
313
318
|
// Taken From:
|
|
314
319
|
// https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
|
|
315
320
|
return Math.sqrt(VertTuple.vtutils.dist2(p, this.vertAt(this.getClosestT(p))));
|
package/src/ts/Vertex.ts
CHANGED
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
* @modified 2023-09-29 Downgraded types for the `Vertex.utils.buildArrowHead` function (replacing Vertex params by more generic XYCoords type).
|
|
33
33
|
* @modified 2023-09-29 Added the `Vertex.abs()` method as it seems useful.
|
|
34
34
|
* @modified 2024-03-08 Added the optional `precision` param to the `toString` method.
|
|
35
|
-
* @
|
|
35
|
+
* @modified 2024-12-17 Outsourced the euclidean distance calculation of `Vertex.distance` to `geomutils.dist4`.
|
|
36
|
+
* @version 2.9.1
|
|
36
37
|
*
|
|
37
38
|
* @file Vertex
|
|
38
39
|
* @public
|
|
@@ -42,6 +43,7 @@ import { IVertexAttr, VertexAttr } from "./VertexAttr";
|
|
|
42
43
|
import { UIDGenerator } from "./UIDGenerator";
|
|
43
44
|
import { VertexListeners } from "./VertexListeners";
|
|
44
45
|
import { XYCoords, SVGSerializable, UID } from "./interfaces";
|
|
46
|
+
import { geomutils } from "./geomutils";
|
|
45
47
|
|
|
46
48
|
/**
|
|
47
49
|
* @classdesc A vertex is a pair of two numbers.<br>
|
|
@@ -430,7 +432,8 @@ export class Vertex implements XYCoords, SVGSerializable {
|
|
|
430
432
|
* @memberof Vertex
|
|
431
433
|
**/
|
|
432
434
|
distance(vert: XYCoords): number {
|
|
433
|
-
return Math.sqrt(Math.pow(vert.x - this.x, 2) + Math.pow(vert.y - this.y, 2));
|
|
435
|
+
// return Math.sqrt(Math.pow(vert.x - this.x, 2) + Math.pow(vert.y - this.y, 2));
|
|
436
|
+
return geomutils.dist4(this.x, this.y, vert.x, vert.y);
|
|
434
437
|
}
|
|
435
438
|
|
|
436
439
|
/**
|
package/src/ts/draw.ts
CHANGED
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
* @modified 2023-09-29 Added the `lineDashes` attribute.
|
|
57
57
|
* @modified 2023-09-30 Adding `strokeOptions` param to these draw function: line, arrow, cubicBezierArrow, cubicBezier, cubicBezierPath, circle, circleArc, ellipse, square, rect, polygon, polyline.
|
|
58
58
|
* @modified 2023-10-07 Adding the optional `arrowHeadBasePositionBuffer` param to the arrowHead(...) method.
|
|
59
|
+
* @modified 2024-09-13 Remoed the scaling of `lineWidth` in the `polygon` and `polyline` methods. This makes no sense here and doesn't match up with the behavior of other line functions.
|
|
59
60
|
* @version 1.13.0
|
|
60
61
|
**/
|
|
61
62
|
|
|
@@ -1209,7 +1210,7 @@ export class drawutils implements DrawLib<void> {
|
|
|
1209
1210
|
this.ctx.save();
|
|
1210
1211
|
this.applyStrokeOpts(strokeOptions);
|
|
1211
1212
|
this.ctx.beginPath();
|
|
1212
|
-
this.ctx.lineWidth =
|
|
1213
|
+
this.ctx.lineWidth = lineWidth || 1.0;
|
|
1213
1214
|
this.ctx.moveTo(this.offset.x + vertices[0].x * this.scale.x, this.offset.y + vertices[0].y * this.scale.y);
|
|
1214
1215
|
for (var i = 0; i < vertices.length; i++) {
|
|
1215
1216
|
this.ctx.lineTo(this.offset.x + vertices[i].x * this.scale.x, this.offset.y + vertices[i].y * this.scale.y);
|
package/src/ts/drawutilssvg.ts
CHANGED
|
@@ -1288,6 +1288,35 @@ export class drawutilssvg implements DrawLib<void | SVGElement> {
|
|
|
1288
1288
|
* @memberof drawutilssvg
|
|
1289
1289
|
*/
|
|
1290
1290
|
grid(center: XYCoords, width: number, height: number, sizeX: number, sizeY: number, color: string) {
|
|
1291
|
+
// console.log("grid");
|
|
1292
|
+
// const node: SVGElement = this.makeNode("pattern");
|
|
1293
|
+
// var patternId = "pattern_id_" + Math.floor(Math.random() * 65365);
|
|
1294
|
+
// node.setAttribute("id", patternId);
|
|
1295
|
+
// node.setAttribute("viewBox", `0,0,${sizeX},${sizeY}`);
|
|
1296
|
+
// node.setAttribute("width", `${sizeX}`);
|
|
1297
|
+
// node.setAttribute("height", `${sizeX}`);
|
|
1298
|
+
|
|
1299
|
+
// var pattern: SVGElement = this.makeNode("path");
|
|
1300
|
+
// const d: SVGPathParams = [];
|
|
1301
|
+
// d.push("M", sizeX / 2.0, 0);
|
|
1302
|
+
// d.push("L", sizeX / 2.0, sizeY);
|
|
1303
|
+
// d.push("M", 0, sizeY / 2.0);
|
|
1304
|
+
// d.push("L", sizeX, sizeY / 2.0);
|
|
1305
|
+
// node.setAttribute("d", d.join(" "));
|
|
1306
|
+
|
|
1307
|
+
// this.bufferedNodeDefs.append(pattern);
|
|
1308
|
+
|
|
1309
|
+
// const fillNode: SVGElement = this.makeNode("rect");
|
|
1310
|
+
// // For some strange reason SVG rotation transforms use degrees instead of radians
|
|
1311
|
+
// // Note that the background does not scale with the zoom level (always covers full element)
|
|
1312
|
+
// fillNode.setAttribute("x", "0");
|
|
1313
|
+
// fillNode.setAttribute("y", "0");
|
|
1314
|
+
// fillNode.setAttribute("width", `${this.canvasSize.width}`);
|
|
1315
|
+
// fillNode.setAttribute("height", `${this.canvasSize.height}`);
|
|
1316
|
+
// fillNode.setAttribute("fill", `url(#${patternId})`);
|
|
1317
|
+
|
|
1318
|
+
// return this._bindFillDraw(fillNode, "grid", "red", 1);
|
|
1319
|
+
|
|
1291
1320
|
const node: SVGElement = this.makeNode("path");
|
|
1292
1321
|
const d: SVGPathParams = [];
|
|
1293
1322
|
|