plotboilerplate 1.14.0 → 1.17.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 +2 -0
- package/changelog.md +57 -0
- package/dist/index.esm.js +856 -694
- 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 +858 -598
- package/dist/plotboilerplate.min.js +1 -1
- package/package.json +1 -1
- package/src/cjs/BezierPath.d.ts +32 -14
- package/src/cjs/BezierPath.js +65 -24
- package/src/cjs/BezierPath.js.map +1 -1
- package/src/cjs/Bounds.d.ts +22 -1
- package/src/cjs/Bounds.js +24 -1
- package/src/cjs/Bounds.js.map +1 -1
- package/src/cjs/Circle.d.ts +15 -13
- package/src/cjs/Circle.js +16 -34
- package/src/cjs/Circle.js.map +1 -1
- package/src/cjs/CircleSector.d.ts +17 -16
- package/src/cjs/CircleSector.js +12 -24
- package/src/cjs/CircleSector.js.map +1 -1
- package/src/cjs/CubicBezierCurve.d.ts +16 -15
- package/src/cjs/CubicBezierCurve.js +57 -94
- package/src/cjs/CubicBezierCurve.js.map +1 -1
- package/src/cjs/KeyHandler.d.ts +10 -3
- package/src/cjs/KeyHandler.js +28 -23
- package/src/cjs/KeyHandler.js.map +1 -1
- package/src/cjs/Line.d.ts +2 -15
- package/src/cjs/Line.js +6 -31
- package/src/cjs/Line.js.map +1 -1
- package/src/cjs/MouseHandler.js +43 -53
- package/src/cjs/MouseHandler.js.map +1 -1
- package/src/cjs/PBImage.d.ts +15 -13
- package/src/cjs/PBImage.js +11 -15
- package/src/cjs/PBImage.js.map +1 -1
- package/src/cjs/PBText.d.ts +13 -12
- package/src/cjs/PBText.js +8 -12
- package/src/cjs/PBText.js.map +1 -1
- package/src/cjs/PlotBoilerplate.js +3 -2
- package/src/cjs/PlotBoilerplate.js.map +1 -1
- package/src/cjs/Polygon.d.ts +44 -14
- package/src/cjs/Polygon.js +116 -66
- package/src/cjs/Polygon.js.map +1 -1
- package/src/cjs/Triangle.d.ts +15 -13
- package/src/cjs/Triangle.js +23 -64
- package/src/cjs/Triangle.js.map +1 -1
- package/src/cjs/VEllipse.d.ts +14 -9
- package/src/cjs/VEllipse.js +10 -18
- package/src/cjs/VEllipse.js.map +1 -1
- package/src/cjs/VEllipseSector.d.ts +15 -1
- package/src/cjs/VEllipseSector.js +11 -1
- package/src/cjs/VEllipseSector.js.map +1 -1
- package/src/cjs/Vector.d.ts +3 -15
- package/src/cjs/Vector.js +9 -49
- package/src/cjs/Vector.js.map +1 -1
- package/src/cjs/VertTuple.d.ts +15 -1
- package/src/cjs/VertTuple.js +14 -19
- package/src/cjs/VertTuple.js.map +1 -1
- package/src/cjs/Vertex.d.ts +47 -13
- package/src/cjs/Vertex.js +62 -22
- package/src/cjs/Vertex.js.map +1 -1
- package/src/cjs/VertexListeners.d.ts +12 -8
- package/src/cjs/VertexListeners.js +18 -25
- package/src/cjs/VertexListeners.js.map +1 -1
- package/src/cjs/draw.d.ts +41 -2
- package/src/cjs/draw.js +140 -3
- package/src/cjs/draw.js.map +1 -1
- package/src/cjs/drawgl.d.ts +38 -2
- package/src/cjs/drawgl.js +41 -2
- package/src/cjs/drawgl.js.map +1 -1
- package/src/cjs/drawutilssvg.d.ts +66 -3
- package/src/cjs/drawutilssvg.js +140 -15
- package/src/cjs/drawutilssvg.js.map +1 -1
- package/src/cjs/index.d.ts +0 -1
- package/src/cjs/index.js +0 -1
- package/src/cjs/index.js.map +1 -1
- package/src/cjs/interfaces/DrawLib.d.ts +61 -26
- package/src/cjs/interfaces/DrawLib.js +2 -0
- package/src/cjs/interfaces/DrawLib.js.map +1 -1
- package/src/cjs/interfaces/core.d.ts +0 -12
- package/src/cjs/module.d.ts +1 -3
- package/src/cjs/module.js +2 -5
- package/src/cjs/module.js.map +1 -1
- package/src/cjs/utils/creategui.js +16 -2
- package/src/cjs/utils/datastructures/Girih.d.ts +5 -0
- package/src/cjs/utils/datastructures/Girih.js +18 -14
- package/src/cjs/utils/datastructures/Girih.js.map +1 -1
- package/src/cjs/utils/datastructures/GirihPenroseRhombus.js +42 -25
- package/src/cjs/utils/datastructures/GirihPenroseRhombus.js.map +1 -1
- package/src/cjs/utils/datastructures/GirihTile.js +2 -13
- package/src/cjs/utils/datastructures/GirihTile.js.map +1 -1
- package/src/cjs/utils/findInVertexArray.d.ts +19 -0
- package/src/cjs/utils/findInVertexArray.js +29 -0
- package/src/cjs/utils/findInVertexArray.js.map +1 -0
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.d.ts +17 -1
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.js +50 -32
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
- package/src/cjs/utils/io/DndFileHandler.d.ts +63 -0
- package/src/cjs/utils/io/DndFileHandler.js +112 -0
- package/src/cjs/utils/io/DndFileHandler.js.map +1 -0
- package/src/cjs/utils/io/FileDrop.d.ts +98 -0
- package/src/cjs/utils/io/FileDrop.js +142 -0
- package/src/cjs/utils/io/FileDrop.js.map +1 -0
- package/src/esm/BezierPath.d.ts +32 -14
- package/src/esm/BezierPath.js +65 -24
- package/src/esm/BezierPath.js.map +1 -1
- package/src/esm/Bounds.d.ts +22 -1
- package/src/esm/Bounds.js +24 -1
- package/src/esm/Bounds.js.map +1 -1
- package/src/esm/Circle.d.ts +15 -13
- package/src/esm/Circle.js +16 -34
- package/src/esm/Circle.js.map +1 -1
- package/src/esm/CircleSector.d.ts +17 -16
- package/src/esm/CircleSector.js +12 -24
- package/src/esm/CircleSector.js.map +1 -1
- package/src/esm/CubicBezierCurve.d.ts +16 -15
- package/src/esm/CubicBezierCurve.js +57 -94
- package/src/esm/CubicBezierCurve.js.map +1 -1
- package/src/esm/KeyHandler.d.ts +10 -3
- package/src/esm/KeyHandler.js +28 -23
- package/src/esm/KeyHandler.js.map +1 -1
- package/src/esm/Line.d.ts +2 -15
- package/src/esm/Line.js +6 -31
- package/src/esm/Line.js.map +1 -1
- package/src/esm/MouseHandler.js +43 -53
- package/src/esm/MouseHandler.js.map +1 -1
- package/src/esm/PBImage.d.ts +15 -13
- package/src/esm/PBImage.js +11 -15
- package/src/esm/PBImage.js.map +1 -1
- package/src/esm/PBText.d.ts +13 -12
- package/src/esm/PBText.js +8 -12
- package/src/esm/PBText.js.map +1 -1
- package/src/esm/PlotBoilerplate.js +3 -2
- package/src/esm/PlotBoilerplate.js.map +1 -1
- package/src/esm/Polygon.d.ts +44 -14
- package/src/esm/Polygon.js +116 -66
- package/src/esm/Polygon.js.map +1 -1
- package/src/esm/Triangle.d.ts +15 -13
- package/src/esm/Triangle.js +23 -64
- package/src/esm/Triangle.js.map +1 -1
- package/src/esm/VEllipse.d.ts +14 -9
- package/src/esm/VEllipse.js +10 -18
- package/src/esm/VEllipse.js.map +1 -1
- package/src/esm/VEllipseSector.d.ts +15 -1
- package/src/esm/VEllipseSector.js +11 -1
- package/src/esm/VEllipseSector.js.map +1 -1
- package/src/esm/Vector.d.ts +3 -15
- package/src/esm/Vector.js +9 -49
- package/src/esm/Vector.js.map +1 -1
- package/src/esm/VertTuple.d.ts +15 -1
- package/src/esm/VertTuple.js +14 -19
- package/src/esm/VertTuple.js.map +1 -1
- package/src/esm/Vertex.d.ts +47 -13
- package/src/esm/Vertex.js +62 -22
- package/src/esm/Vertex.js.map +1 -1
- package/src/esm/VertexListeners.d.ts +12 -8
- package/src/esm/VertexListeners.js +18 -25
- package/src/esm/VertexListeners.js.map +1 -1
- package/src/esm/draw.d.ts +41 -2
- package/src/esm/draw.js +139 -3
- package/src/esm/draw.js.map +1 -1
- package/src/esm/drawgl.d.ts +38 -2
- package/src/esm/drawgl.js +41 -2
- package/src/esm/drawgl.js.map +1 -1
- package/src/esm/drawutilssvg.d.ts +66 -3
- package/src/esm/drawutilssvg.js +140 -15
- package/src/esm/drawutilssvg.js.map +1 -1
- package/src/esm/index.d.ts +0 -1
- package/src/esm/index.js +0 -1
- package/src/esm/index.js.map +1 -1
- package/src/esm/interfaces/DrawLib.d.ts +61 -26
- package/src/esm/interfaces/DrawLib.js +2 -0
- package/src/esm/interfaces/DrawLib.js.map +1 -1
- package/src/esm/interfaces/core.d.ts +0 -12
- package/src/esm/module.d.ts +1 -3
- package/src/esm/module.js +5 -4
- package/src/esm/module.js.map +1 -1
- package/src/esm/utils/datastructures/Girih.d.ts +5 -0
- package/src/esm/utils/datastructures/Girih.js +18 -14
- package/src/esm/utils/datastructures/Girih.js.map +1 -1
- package/src/esm/utils/datastructures/GirihPenroseRhombus.js +42 -25
- package/src/esm/utils/datastructures/GirihPenroseRhombus.js.map +1 -1
- package/src/esm/utils/datastructures/GirihTile.js +2 -13
- package/src/esm/utils/datastructures/GirihTile.js.map +1 -1
- package/src/esm/utils/findInVertexArray.d.ts +19 -0
- package/src/esm/utils/findInVertexArray.js +25 -0
- package/src/esm/utils/findInVertexArray.js.map +1 -0
- package/src/esm/utils/helpers/BezierPathInteractionHelper.d.ts +17 -1
- package/src/esm/utils/helpers/BezierPathInteractionHelper.js +49 -32
- package/src/esm/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
- package/src/esm/utils/io/DndFileHandler.d.ts +63 -0
- package/src/esm/utils/io/DndFileHandler.js +106 -0
- package/src/esm/utils/io/DndFileHandler.js.map +1 -0
- package/src/esm/utils/io/FileDrop.d.ts +98 -0
- package/src/esm/utils/io/FileDrop.js +136 -0
- package/src/esm/utils/io/FileDrop.js.map +1 -0
- package/src/ts/BezierPath.ts +78 -22
- package/src/ts/Bounds.ts +25 -1
- package/src/ts/Circle.ts +187 -200
- package/src/ts/CircleSector.ts +141 -141
- package/src/ts/CubicBezierCurve.ts +738 -810
- package/src/ts/KeyHandler.ts +221 -212
- package/src/ts/Line.ts +48 -80
- package/src/ts/MouseHandler.ts +356 -368
- package/src/ts/PBImage.ts +67 -69
- package/src/ts/PBText.ts +16 -14
- package/src/ts/PlotBoilerplate.ts +4 -2
- package/src/ts/Polygon.ts +493 -451
- package/src/ts/Triangle.ts +444 -489
- package/src/ts/VEllipse.ts +18 -17
- package/src/ts/VEllipseSector.ts +20 -1
- package/src/ts/Vector.ts +124 -160
- package/src/ts/VertTuple.ts +333 -338
- package/src/ts/Vertex.ts +75 -21
- package/src/ts/VertexListeners.ts +248 -266
- package/src/ts/draw.ts +192 -3
- package/src/ts/drawgl.ts +44 -2
- package/src/ts/drawutilssvg.ts +181 -15
- package/src/ts/index.ts +0 -1
- package/src/ts/interfaces/DrawLib.ts +69 -26
- package/src/ts/interfaces/core.ts +0 -11
- package/src/ts/module.ts +2 -4
- package/src/ts/utils/datastructures/Girih.ts +204 -209
- package/src/ts/utils/datastructures/GirihPenroseRhombus.ts +170 -152
- package/src/ts/utils/datastructures/GirihTile.ts +394 -419
- package/src/ts/utils/findInVertexArray.ts +28 -0
- package/src/ts/utils/helpers/BezierPathInteractionHelper.ts +56 -34
- package/src/ts/utils/io/FileDrop.ts +178 -0
- package/src/ts/SVGBuilder.ts +0 -109
- package/src/ts/utils/algorithms/sh-tmp.ts~ +0 -59
package/src/ts/Polygon.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* @modified 2020-03-24 Ported this class from vanilla-JS to Typescript.
|
|
12
12
|
* @modified 2020-10-30 Added the `addVertex` function.
|
|
13
13
|
* @modified 2020-10-31 Added the `getVertexAt` function.
|
|
14
|
-
* @modified 2020-11-06 Added the `move` function.
|
|
14
|
+
* @modified 2020-11-06 Added the `move` function.
|
|
15
15
|
* @modified 2020-11-10 Added the `getBounds` function.
|
|
16
16
|
* @modified 2020-11-11 Generalized `move(Vertex)` to `move(XYCoords)`.
|
|
17
17
|
* @modified 2021-01-20 Added UID.
|
|
@@ -19,7 +19,12 @@
|
|
|
19
19
|
* @modified 2021-01-29 Added the `isClockwise` function.
|
|
20
20
|
* @modified 2021-01-29 Added the `area` function.
|
|
21
21
|
* @modified 2021-01-29 Changed the param type for `containsVert` from Vertex to XYCoords.
|
|
22
|
-
* @
|
|
22
|
+
* @modified 2021-12-14 Added the `perimeter()` function.
|
|
23
|
+
* @modified 2021-12-16 Added the `getEvenDistributionPolygon()` function.
|
|
24
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
25
|
+
* @modified 2022-02-02 Cleared the `Polygon.toSVGString` function (deprecated). Use `drawutilssvg` instead.
|
|
26
|
+
* @modified 2022-03-08 Added the `Polygon.clone()` function.
|
|
27
|
+
* @version 1.10.0
|
|
23
28
|
*
|
|
24
29
|
* @file Polygon
|
|
25
30
|
* @public
|
|
@@ -31,7 +36,6 @@ import { UIDGenerator } from "./UIDGenerator";
|
|
|
31
36
|
import { Vertex } from "./Vertex";
|
|
32
37
|
import { XYCoords, SVGSerializable, UID } from "./interfaces";
|
|
33
38
|
|
|
34
|
-
|
|
35
39
|
/**
|
|
36
40
|
* @classdesc A polygon class. Any polygon consists of an array of vertices; polygons can be open or closed.
|
|
37
41
|
*
|
|
@@ -44,465 +48,503 @@ import { XYCoords, SVGSerializable, UID } from "./interfaces";
|
|
|
44
48
|
* @requires XYCoords
|
|
45
49
|
*/
|
|
46
50
|
export class Polygon implements SVGSerializable {
|
|
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
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Required to generate proper CSS classes and other class related IDs.
|
|
53
|
+
**/
|
|
54
|
+
readonly className: string = "Polygon";
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The UID of this drawable object.
|
|
58
|
+
*
|
|
59
|
+
* @member {UID}
|
|
60
|
+
* @memberof Polygon
|
|
61
|
+
* @instance
|
|
62
|
+
* @readonly
|
|
63
|
+
*/
|
|
64
|
+
readonly uid: UID;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @member {Array<Vertex>}
|
|
68
|
+
* @memberof Polygon
|
|
69
|
+
* @type {Array<Vertex>}
|
|
70
|
+
* @instance
|
|
71
|
+
*/
|
|
72
|
+
vertices: Array<Vertex>;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @member {boolean}
|
|
76
|
+
* @memberof Polygon
|
|
77
|
+
* @type {boolean}
|
|
78
|
+
* @instance
|
|
79
|
+
*/
|
|
80
|
+
isOpen: boolean;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @member isDestroyed
|
|
84
|
+
* @memberof Polygon
|
|
85
|
+
* @type {boolean}
|
|
86
|
+
* @instance
|
|
87
|
+
*/
|
|
88
|
+
isDestroyed: boolean;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The constructor.
|
|
92
|
+
*
|
|
93
|
+
* @constructor
|
|
94
|
+
* @name Polygon
|
|
95
|
+
* @param {Vertex[]} vertices - An array of 2d vertices that shape the polygon.
|
|
96
|
+
* @param {boolean} isOpen - Indicates if the polygon should be rendered as an open or closed shape.
|
|
97
|
+
**/
|
|
98
|
+
constructor(vertices?: Array<Vertex>, isOpen?: boolean) {
|
|
99
|
+
this.uid = UIDGenerator.next();
|
|
100
|
+
if (typeof vertices == "undefined") vertices = [];
|
|
101
|
+
this.vertices = vertices;
|
|
102
|
+
this.isOpen = isOpen;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Add a vertex to the end of the `vertices` array.
|
|
107
|
+
*
|
|
108
|
+
* @method addVert
|
|
109
|
+
* @param {Vertex} vert - The vertex to add.
|
|
110
|
+
* @instance
|
|
111
|
+
* @memberof Polygon
|
|
112
|
+
**/
|
|
113
|
+
addVertex(vert: Vertex): void {
|
|
114
|
+
this.vertices.push(vert);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Get the polygon vertex at the given position (index).
|
|
119
|
+
*
|
|
120
|
+
* The index may exceed the total vertex count, and will be wrapped around then (modulo).
|
|
121
|
+
*
|
|
122
|
+
* For k >= 0:
|
|
123
|
+
* - getVertexAt( vertices.length ) == getVertexAt( 0 )
|
|
124
|
+
* - getVertexAt( vertices.length + k ) == getVertexAt( k )
|
|
125
|
+
* - getVertexAt( -k ) == getVertexAt( vertices.length -k )
|
|
126
|
+
*
|
|
127
|
+
* @metho getVertexAt
|
|
128
|
+
* @param {number} index - The index of the desired vertex.
|
|
129
|
+
* @instance
|
|
130
|
+
* @memberof Polygon
|
|
131
|
+
* @return {Vertex} At the given index.
|
|
132
|
+
**/
|
|
133
|
+
getVertexAt(index: number): Vertex {
|
|
134
|
+
if (index < 0) return this.vertices[this.vertices.length - (Math.abs(index) % this.vertices.length)];
|
|
135
|
+
else return this.vertices[index % this.vertices.length];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Move the polygon's vertices by the given amount.
|
|
140
|
+
*
|
|
141
|
+
* @method move
|
|
142
|
+
* @param {XYCoords} amount - The amount to move.
|
|
143
|
+
* @instance
|
|
144
|
+
* @memberof Polygon
|
|
145
|
+
* @return {Polygon} this for chaining
|
|
146
|
+
**/
|
|
147
|
+
move(amount: XYCoords): Polygon {
|
|
148
|
+
for (var i in this.vertices) {
|
|
149
|
+
this.vertices[i].add(amount);
|
|
150
|
+
}
|
|
151
|
+
return this;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Check if the given vertex is inside this polygon.<br>
|
|
156
|
+
* <br>
|
|
157
|
+
* Ray-casting algorithm found at<br>
|
|
158
|
+
* https://stackoverflow.com/questions/22521982/check-if-point-inside-a-polygon
|
|
159
|
+
*
|
|
160
|
+
* @method containsVert
|
|
161
|
+
* @param {XYCoords} vert - The vertex to check. The new x-component.
|
|
162
|
+
* @return {boolean} True if the passed vertex is inside this polygon. The polygon is considered closed.
|
|
163
|
+
* @instance
|
|
164
|
+
* @memberof Polygon
|
|
165
|
+
**/
|
|
166
|
+
containsVert(vert: XYCoords): boolean {
|
|
167
|
+
// ray-casting algorithm based on
|
|
168
|
+
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
|
|
169
|
+
var inside: boolean = false;
|
|
170
|
+
for (var i = 0, j = this.vertices.length - 1; i < this.vertices.length; j = i++) {
|
|
171
|
+
let xi: number = this.vertices[i].x,
|
|
172
|
+
yi: number = this.vertices[i].y;
|
|
173
|
+
let xj: number = this.vertices[j].x,
|
|
174
|
+
yj: number = this.vertices[j].y;
|
|
175
|
+
|
|
176
|
+
var intersect: boolean = yi > vert.y != yj > vert.y && vert.x < ((xj - xi) * (vert.y - yi)) / (yj - yi) + xi;
|
|
177
|
+
if (intersect) inside = !inside;
|
|
178
|
+
}
|
|
179
|
+
return inside;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Calculate the area of the given polygon (unsigned).
|
|
184
|
+
*
|
|
185
|
+
* Note that this does not work for self-intersecting polygons.
|
|
186
|
+
*
|
|
187
|
+
* @method area
|
|
188
|
+
* @instance
|
|
189
|
+
* @memberof Polygon
|
|
190
|
+
* @return {number}
|
|
191
|
+
*/
|
|
192
|
+
area(): number {
|
|
193
|
+
return Polygon.utils.area(this.vertices);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Calulate the signed polyon area by interpreting the polygon as a matrix
|
|
198
|
+
* and calculating its determinant.
|
|
199
|
+
*
|
|
200
|
+
* @method signedArea
|
|
201
|
+
* @instance
|
|
202
|
+
* @memberof Polygon
|
|
203
|
+
* @return {number}
|
|
204
|
+
*/
|
|
205
|
+
signedArea(): number {
|
|
206
|
+
return Polygon.utils.signedArea(this.vertices);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Get the winding order of this polgon: clockwise or counterclockwise.
|
|
211
|
+
*
|
|
212
|
+
* @method isClockwise
|
|
213
|
+
* @instance
|
|
214
|
+
* @memberof Polygon
|
|
215
|
+
* @return {boolean}
|
|
216
|
+
*/
|
|
217
|
+
isClockwise(): boolean {
|
|
218
|
+
return Polygon.utils.signedArea(this.vertices) < 0;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Get the perimeter of this polygon.
|
|
223
|
+
* The perimeter is the absolute length of the outline.
|
|
224
|
+
*
|
|
225
|
+
* If this polygon is open then the last segment (connecting the first and the
|
|
226
|
+
* last vertex) will be skipped.
|
|
227
|
+
*
|
|
228
|
+
* @method perimeter
|
|
229
|
+
* @instance
|
|
230
|
+
* @memberof Polygon
|
|
231
|
+
* @return {number}
|
|
232
|
+
*/
|
|
233
|
+
perimeter(): number {
|
|
234
|
+
let length: number = 0;
|
|
235
|
+
for (var i = 1; i < this.vertices.length; i++) {
|
|
236
|
+
length += this.vertices[i - 1].distance(this.vertices[i]);
|
|
237
|
+
}
|
|
238
|
+
if (!this.isOpen && this.vertices.length > 1) {
|
|
239
|
+
length += this.vertices[0].distance(this.vertices[this.vertices.length - 1]);
|
|
240
|
+
}
|
|
241
|
+
return length;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Scale the polygon relative to the given center.
|
|
246
|
+
*
|
|
247
|
+
* @method scale
|
|
248
|
+
* @param {number} factor - The scale factor.
|
|
249
|
+
* @param {Vertex} center - The center of scaling.
|
|
250
|
+
* @return {Polygon} this, for chaining.
|
|
251
|
+
* @instance
|
|
252
|
+
* @memberof Polygon
|
|
253
|
+
**/
|
|
254
|
+
scale(factor: number, center: Vertex): Polygon {
|
|
255
|
+
for (var i in this.vertices) {
|
|
256
|
+
if (typeof this.vertices[i].scale == "function") this.vertices[i].scale(factor, center);
|
|
257
|
+
else console.log("There seems to be a null vertex!", this.vertices[i]);
|
|
258
|
+
}
|
|
259
|
+
return this;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Rotate the polygon around the given center.
|
|
264
|
+
*
|
|
265
|
+
* @method rotate
|
|
266
|
+
* @param {number} angle - The rotation angle.
|
|
267
|
+
* @param {Vertex} center - The center of rotation.
|
|
268
|
+
* @instance
|
|
269
|
+
* @memberof Polygon
|
|
270
|
+
* @return {Polygon} this, for chaining.
|
|
271
|
+
**/
|
|
272
|
+
rotate(angle: number, center: Vertex): Polygon {
|
|
273
|
+
for (var i in this.vertices) {
|
|
274
|
+
this.vertices[i].rotate(angle, center);
|
|
275
|
+
}
|
|
276
|
+
return this;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Convert this polygon into a new polygon with n evenly distributed vertices.
|
|
281
|
+
*
|
|
282
|
+
* @param {number} pointCount - Must not be negative.
|
|
283
|
+
*/
|
|
284
|
+
getEvenDistributionPolygon(pointCount: number): Polygon {
|
|
285
|
+
if (pointCount <= 0) {
|
|
286
|
+
throw new Error("pointCount must be larger than zero; is " + pointCount + ".");
|
|
287
|
+
}
|
|
288
|
+
const result: Polygon = new Polygon([], this.isOpen);
|
|
289
|
+
if (this.vertices.length === 0) {
|
|
290
|
+
return result;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Fetch and add the start point from the source polygon
|
|
294
|
+
let polygonPoint: Vertex = new Vertex(this.vertices[0]);
|
|
295
|
+
result.vertices.push(polygonPoint);
|
|
296
|
+
if (this.vertices.length === 1) {
|
|
297
|
+
return result;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const perimeter: number = this.perimeter();
|
|
301
|
+
const stepSize: number = perimeter / pointCount;
|
|
302
|
+
const n: number = this.vertices.length;
|
|
303
|
+
|
|
304
|
+
let polygonIndex: number = 1;
|
|
305
|
+
let nextPolygonPoint: Vertex = new Vertex(this.vertices[1]);
|
|
306
|
+
let segmentLength: number = polygonPoint.distance(nextPolygonPoint);
|
|
307
|
+
let loopMax: number = this.isOpen ? n : n + 1;
|
|
308
|
+
let curSegmentU: number = stepSize;
|
|
309
|
+
var i = 1;
|
|
310
|
+
while (i < pointCount && polygonIndex < loopMax) {
|
|
311
|
+
// Check if next eq point is inside this segment
|
|
312
|
+
if (curSegmentU < segmentLength) {
|
|
313
|
+
let newPoint: Vertex = polygonPoint.clone().lerpAbs(nextPolygonPoint, curSegmentU);
|
|
314
|
+
result.vertices.push(newPoint);
|
|
315
|
+
curSegmentU += stepSize;
|
|
316
|
+
i++;
|
|
317
|
+
} else {
|
|
318
|
+
polygonIndex++;
|
|
319
|
+
polygonPoint = nextPolygonPoint;
|
|
320
|
+
nextPolygonPoint = new Vertex(this.vertices[polygonIndex % n]);
|
|
321
|
+
curSegmentU = curSegmentU - segmentLength;
|
|
322
|
+
segmentLength = polygonPoint.distance(nextPolygonPoint);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return result;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Get the bounding box (bounds) of this polygon.
|
|
330
|
+
*
|
|
331
|
+
* @method getBounds
|
|
332
|
+
* @instance
|
|
333
|
+
* @memberof Polygon
|
|
334
|
+
* @return {Bounds} The rectangular bounds of this polygon.
|
|
335
|
+
**/
|
|
336
|
+
getBounds(): Bounds {
|
|
337
|
+
return Bounds.computeFromVertices(this.vertices);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Create a deep copy of this polygon.
|
|
342
|
+
*
|
|
343
|
+
* @return {Polygon} The cloned polygon.
|
|
344
|
+
*/
|
|
345
|
+
clone(): Polygon {
|
|
346
|
+
return new Polygon(
|
|
347
|
+
this.vertices.map(vert => vert.clone()),
|
|
348
|
+
this.isOpen
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Convert this polygon to a sequence of quadratic Bézier curves.<br>
|
|
354
|
+
* <br>
|
|
355
|
+
* The first vertex in the returned array is the start point.<br>
|
|
356
|
+
* The following sequence are pairs of control-point-and-end-point:
|
|
357
|
+
* <pre>startPoint, controlPoint0, pathPoint1, controlPoint1, pathPoint2, controlPoint2, ..., endPoint</pre>
|
|
358
|
+
*
|
|
359
|
+
* @method toQuadraticBezierData
|
|
360
|
+
* @return {Vertex[]} An array of 2d vertices that shape the quadratic Bézier curve.
|
|
361
|
+
* @instance
|
|
362
|
+
* @memberof Polygon
|
|
363
|
+
**/
|
|
364
|
+
toQuadraticBezierData(): Array<Vertex> {
|
|
365
|
+
if (this.vertices.length < 3) return [];
|
|
366
|
+
var qbezier: Array<Vertex> = [];
|
|
367
|
+
var cc0: Vertex = this.vertices[0];
|
|
368
|
+
var cc1: Vertex = this.vertices[1];
|
|
369
|
+
var edgeCenter: Vertex = new Vertex(cc0.x + (cc1.x - cc0.x) / 2, cc0.y + (cc1.y - cc0.y) / 2);
|
|
370
|
+
qbezier.push(edgeCenter);
|
|
371
|
+
var limit = this.isOpen ? this.vertices.length : this.vertices.length + 1;
|
|
372
|
+
for (var t = 1; t < limit; t++) {
|
|
373
|
+
cc0 = this.vertices[t % this.vertices.length];
|
|
374
|
+
cc1 = this.vertices[(t + 1) % this.vertices.length];
|
|
375
|
+
var edgeCenter: Vertex = new Vertex(cc0.x + (cc1.x - cc0.x) / 2, cc0.y + (cc1.y - cc0.y) / 2);
|
|
376
|
+
qbezier.push(cc0);
|
|
377
|
+
qbezier.push(edgeCenter);
|
|
378
|
+
cc0 = cc1;
|
|
379
|
+
}
|
|
380
|
+
return qbezier;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Convert this polygon to a quadratic bezier curve, represented as an SVG data string.
|
|
385
|
+
*
|
|
386
|
+
* @method toQuadraticBezierSVGString
|
|
387
|
+
* @return {string} The 'd' part for an SVG 'path' element.
|
|
388
|
+
* @instance
|
|
389
|
+
* @memberof Polygon
|
|
390
|
+
**/
|
|
391
|
+
toQuadraticBezierSVGString(): string {
|
|
392
|
+
var qdata: Array<Vertex> = this.toQuadraticBezierData();
|
|
393
|
+
if (qdata.length == 0) return "";
|
|
394
|
+
var buffer = ["M " + qdata[0].x + " " + qdata[0].y];
|
|
395
|
+
for (var i = 1; i < qdata.length; i += 2) {
|
|
396
|
+
buffer.push("Q " + qdata[i].x + " " + qdata[i].y + ", " + qdata[i + 1].x + " " + qdata[i + 1].y);
|
|
397
|
+
}
|
|
398
|
+
return buffer.join(" ");
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Convert this polygon to a sequence of cubic Bézier curves.<br>
|
|
403
|
+
* <br>
|
|
404
|
+
* The first vertex in the returned array is the start point.<br>
|
|
405
|
+
* The following sequence are triplets of (first-control-point, secnond-control-point, end-point):<br>
|
|
406
|
+
* <pre>startPoint, controlPoint0_0, controlPoint1_1, pathPoint1, controlPoint1_0, controlPoint1_1, ..., endPoint</pre>
|
|
407
|
+
*
|
|
408
|
+
* @method toCubicBezierData
|
|
409
|
+
* @param {number=} threshold - An optional threshold (default=1.0) how strong the curve segments
|
|
410
|
+
* should over-/under-drive. Should be between 0.0 and 1.0 for best
|
|
411
|
+
* results but other values are allowed.
|
|
412
|
+
* @return {Vertex[]} An array of 2d vertices that shape the cubic Bézier curve.
|
|
413
|
+
* @instance
|
|
414
|
+
* @memberof Polygon
|
|
415
|
+
**/
|
|
416
|
+
toCubicBezierData(threshold: number | undefined): Array<Vertex> {
|
|
417
|
+
if (typeof threshold == "undefined") threshold = 1.0;
|
|
418
|
+
|
|
419
|
+
if (this.vertices.length < 3) return [];
|
|
420
|
+
var cbezier: Array<Vertex> = [];
|
|
421
|
+
var a: Vertex = this.vertices[0];
|
|
422
|
+
var b: Vertex = this.vertices[1];
|
|
423
|
+
var edgeCenter = new Vertex(a.x + (b.x - a.x) / 2, a.y + (b.y - a.y) / 2);
|
|
424
|
+
cbezier.push(edgeCenter);
|
|
425
|
+
|
|
426
|
+
var limit: number = this.isOpen ? this.vertices.length - 1 : this.vertices.length;
|
|
427
|
+
for (var t = 0; t < limit; t++) {
|
|
428
|
+
var a = this.vertices[t % this.vertices.length];
|
|
429
|
+
var b = this.vertices[(t + 1) % this.vertices.length];
|
|
430
|
+
var c = this.vertices[(t + 2) % this.vertices.length];
|
|
431
|
+
|
|
432
|
+
var aCenter: Vertex = new Vertex(a.x + (b.x - a.x) / 2, a.y + (b.y - a.y) / 2);
|
|
433
|
+
var bCenter: Vertex = new Vertex(b.x + (c.x - b.x) / 2, b.y + (c.y - b.y) / 2);
|
|
434
|
+
|
|
435
|
+
var a2: Vertex = new Vertex(aCenter.x + (b.x - aCenter.x) * threshold, aCenter.y + (b.y - aCenter.y) * threshold);
|
|
436
|
+
var b0: Vertex = new Vertex(bCenter.x + (b.x - bCenter.x) * threshold, bCenter.y + (b.y - bCenter.y) * threshold);
|
|
437
|
+
|
|
438
|
+
cbezier.push(a2);
|
|
439
|
+
cbezier.push(b0);
|
|
440
|
+
cbezier.push(bCenter);
|
|
441
|
+
}
|
|
442
|
+
return cbezier;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Convert this polygon to a cubic bezier curve, represented as an SVG data string.
|
|
447
|
+
*
|
|
448
|
+
* @method toCubicBezierSVGString
|
|
449
|
+
* @return {string} The 'd' part for an SVG 'path' element.
|
|
450
|
+
* @instance
|
|
451
|
+
* @memberof Polygon
|
|
452
|
+
**/
|
|
453
|
+
toCubicBezierSVGString(threshold: number): string {
|
|
454
|
+
var qdata: Array<Vertex> = this.toCubicBezierData(threshold);
|
|
455
|
+
if (qdata.length == 0) return "";
|
|
456
|
+
var buffer = ["M " + qdata[0].x + " " + qdata[0].y];
|
|
457
|
+
for (var i = 1; i < qdata.length; i += 3) {
|
|
458
|
+
buffer.push(
|
|
459
|
+
"C " +
|
|
460
|
+
qdata[i].x +
|
|
461
|
+
" " +
|
|
462
|
+
qdata[i].y +
|
|
463
|
+
", " +
|
|
464
|
+
qdata[i + 1].x +
|
|
465
|
+
" " +
|
|
466
|
+
qdata[i + 1].y +
|
|
467
|
+
", " +
|
|
468
|
+
qdata[i + 2].x +
|
|
469
|
+
" " +
|
|
470
|
+
qdata[i + 2].y
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
return buffer.join(" ");
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Convert this polygon to a cubic bezier path instance.
|
|
478
|
+
*
|
|
479
|
+
* @method toCubicBezierPath
|
|
480
|
+
* @param {number} threshold - The threshold, usually from 0.0 to 1.0.
|
|
481
|
+
* @return {BezierPath} - A bezier path instance.
|
|
482
|
+
* @instance
|
|
483
|
+
* @memberof Polygon
|
|
484
|
+
**/
|
|
485
|
+
toCubicBezierPath(threshold: number): BezierPath {
|
|
486
|
+
var qdata: Array<Vertex> = this.toCubicBezierData(threshold);
|
|
487
|
+
// Conver the linear path vertices to a two-dimensional path array
|
|
488
|
+
var pathdata: Array<Array<Vertex>> = [];
|
|
489
|
+
for (var i = 0; i + 3 < qdata.length; i += 3) {
|
|
490
|
+
pathdata.push([qdata[i], qdata[i + 3], qdata[i + 1], qdata[i + 2]]);
|
|
491
|
+
}
|
|
492
|
+
return BezierPath.fromArray(pathdata);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* This function should invalidate any installed listeners and invalidate this object.
|
|
497
|
+
* After calling this function the object might not hold valid data any more and
|
|
498
|
+
* should not be used.
|
|
499
|
+
*/
|
|
500
|
+
destroy() {
|
|
501
|
+
for (var i = 0; i < this.vertices.length; i++) {
|
|
502
|
+
this.vertices[i].destroy();
|
|
503
|
+
}
|
|
504
|
+
this.isDestroyed = true;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
static utils = {
|
|
183
508
|
/**
|
|
184
|
-
* Calculate the area of the given polygon (unsigned).
|
|
509
|
+
* Calculate the area of the given polygon (unsigned).
|
|
185
510
|
*
|
|
186
511
|
* Note that this does not work for self-intersecting polygons.
|
|
187
512
|
*
|
|
188
|
-
* @
|
|
189
|
-
* @instance
|
|
190
|
-
* @memberof Polygon
|
|
513
|
+
* @name area
|
|
191
514
|
* @return {number}
|
|
192
515
|
*/
|
|
193
|
-
area()
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
516
|
+
area(vertices: Array<XYCoords>): number {
|
|
517
|
+
// Found at:
|
|
518
|
+
// https://stackoverflow.com/questions/16285134/calculating-polygon-area
|
|
519
|
+
let total: number = 0.0;
|
|
520
|
+
|
|
521
|
+
for (var i = 0, l = vertices.length; i < l; i++) {
|
|
522
|
+
const addX = vertices[i].x;
|
|
523
|
+
const addY = vertices[(i + 1) % l].y;
|
|
524
|
+
const subX = vertices[(i + 1) % l].x;
|
|
525
|
+
const subY = vertices[i].y;
|
|
526
|
+
|
|
527
|
+
total += addX * addY * 0.5;
|
|
528
|
+
total -= subX * subY * 0.5;
|
|
529
|
+
}
|
|
530
|
+
return Math.abs(total);
|
|
531
|
+
},
|
|
197
532
|
|
|
198
533
|
/**
|
|
199
534
|
* Calulate the signed polyon area by interpreting the polygon as a matrix
|
|
200
535
|
* and calculating its determinant.
|
|
201
536
|
*
|
|
202
|
-
* @
|
|
203
|
-
* @instance
|
|
204
|
-
* @memberof Polygon
|
|
537
|
+
* @name signedArea
|
|
205
538
|
* @return {number}
|
|
206
539
|
*/
|
|
207
|
-
signedArea()
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
* @memberof Polygon
|
|
218
|
-
* @return {boolean}
|
|
219
|
-
*/
|
|
220
|
-
isClockwise() : boolean {
|
|
221
|
-
return Polygon.utils.signedArea(this.vertices) < 0;
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Scale the polygon relative to the given center.
|
|
228
|
-
*
|
|
229
|
-
* @method scale
|
|
230
|
-
* @param {number} factor - The scale factor.
|
|
231
|
-
* @param {Vertex} center - The center of scaling.
|
|
232
|
-
* @return {Polygon} this, for chaining.
|
|
233
|
-
* @instance
|
|
234
|
-
* @memberof Polygon
|
|
235
|
-
**/
|
|
236
|
-
scale( factor:number, center:Vertex ) : Polygon {
|
|
237
|
-
for( var i in this.vertices ) {
|
|
238
|
-
if( typeof this.vertices[i].scale == 'function' )
|
|
239
|
-
this.vertices[i].scale( factor, center );
|
|
240
|
-
else
|
|
241
|
-
console.log( 'There seems to be a null vertex!', this.vertices[i] );
|
|
242
|
-
}
|
|
243
|
-
return this;
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Rotate the polygon around the given center.
|
|
249
|
-
*
|
|
250
|
-
* @method rotate
|
|
251
|
-
* @param {number} angle - The rotation angle.
|
|
252
|
-
* @param {Vertex} center - The center of rotation.
|
|
253
|
-
* @instance
|
|
254
|
-
* @memberof Polygon
|
|
255
|
-
* @return {Polygon} this, for chaining.
|
|
256
|
-
**/
|
|
257
|
-
rotate( angle:number, center:Vertex ) : Polygon {
|
|
258
|
-
for( var i in this.vertices ) {
|
|
259
|
-
this.vertices[i].rotate( angle, center );
|
|
260
|
-
}
|
|
261
|
-
return this;
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Get the bounding box (bounds) of this polygon.
|
|
267
|
-
*
|
|
268
|
-
* @method getBounds
|
|
269
|
-
* @instance
|
|
270
|
-
* @memberof Polygon
|
|
271
|
-
* @return {Bounds} The rectangular bounds of this polygon.
|
|
272
|
-
**/
|
|
273
|
-
getBounds() : Bounds {
|
|
274
|
-
return Bounds.computeFromVertices( this.vertices );
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* Convert this polygon to a sequence of quadratic Bézier curves.<br>
|
|
280
|
-
* <br>
|
|
281
|
-
* The first vertex in the returned array is the start point.<br>
|
|
282
|
-
* The following sequence are pairs of control-point-and-end-point:
|
|
283
|
-
* <pre>startPoint, controlPoint0, pathPoint1, controlPoint1, pathPoint2, controlPoint2, ..., endPoint</pre>
|
|
284
|
-
*
|
|
285
|
-
* @method toQuadraticBezierData
|
|
286
|
-
* @return {Vertex[]} An array of 2d vertices that shape the quadratic Bézier curve.
|
|
287
|
-
* @instance
|
|
288
|
-
* @memberof Polygon
|
|
289
|
-
**/
|
|
290
|
-
toQuadraticBezierData() : Array<Vertex> {
|
|
291
|
-
if( this.vertices.length < 3 )
|
|
292
|
-
return [];
|
|
293
|
-
var qbezier : Array<Vertex> = [];
|
|
294
|
-
var cc0 : Vertex = this.vertices[0];
|
|
295
|
-
var cc1 : Vertex = this.vertices[1];
|
|
296
|
-
var edgeCenter : Vertex = new Vertex( cc0.x + (cc1.x-cc0.x)/2,
|
|
297
|
-
cc0.y + (cc1.y-cc0.y)/2 );
|
|
298
|
-
qbezier.push( edgeCenter );
|
|
299
|
-
var limit = this.isOpen ? this.vertices.length : this.vertices.length+1;
|
|
300
|
-
for( var t = 1; t < limit; t++ ) {
|
|
301
|
-
cc0 = this.vertices[ t%this.vertices.length ];
|
|
302
|
-
cc1 = this.vertices[ (t+1)%this.vertices.length ];
|
|
303
|
-
var edgeCenter : Vertex = new Vertex( cc0.x + (cc1.x-cc0.x)/2,
|
|
304
|
-
cc0.y + (cc1.y-cc0.y)/2 );
|
|
305
|
-
qbezier.push( cc0 );
|
|
306
|
-
qbezier.push( edgeCenter );
|
|
307
|
-
cc0 = cc1;
|
|
308
|
-
}
|
|
309
|
-
return qbezier;
|
|
310
|
-
};
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Convert this polygon to a quadratic bezier curve, represented as an SVG data string.
|
|
315
|
-
*
|
|
316
|
-
* @method toQuadraticBezierSVGString
|
|
317
|
-
* @return {string} The 'd' part for an SVG 'path' element.
|
|
318
|
-
* @instance
|
|
319
|
-
* @memberof Polygon
|
|
320
|
-
**/
|
|
321
|
-
toQuadraticBezierSVGString() : string {
|
|
322
|
-
var qdata : Array<Vertex> = this.toQuadraticBezierData();
|
|
323
|
-
if( qdata.length == 0 )
|
|
324
|
-
return "";
|
|
325
|
-
var buffer = [ 'M ' + qdata[0].x+' '+qdata[0].y ];
|
|
326
|
-
for( var i = 1; i < qdata.length; i+=2 ) {
|
|
327
|
-
buffer.push( 'Q ' + qdata[i].x+' '+qdata[i].y + ', ' + qdata[i+1].x+' '+qdata[i+1].y );
|
|
328
|
-
}
|
|
329
|
-
return buffer.join(' ');
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Convert this polygon to a sequence of cubic Bézier curves.<br>
|
|
336
|
-
* <br>
|
|
337
|
-
* The first vertex in the returned array is the start point.<br>
|
|
338
|
-
* The following sequence are triplets of (first-control-point, secnond-control-point, end-point):<br>
|
|
339
|
-
* <pre>startPoint, controlPoint0_0, controlPoint1_1, pathPoint1, controlPoint1_0, controlPoint1_1, ..., endPoint</pre>
|
|
340
|
-
*
|
|
341
|
-
* @method toCubicBezierData
|
|
342
|
-
* @param {number=} threshold - An optional threshold (default=1.0) how strong the curve segments
|
|
343
|
-
* should over-/under-drive. Should be between 0.0 and 1.0 for best
|
|
344
|
-
* results but other values are allowed.
|
|
345
|
-
* @return {Vertex[]} An array of 2d vertices that shape the cubic Bézier curve.
|
|
346
|
-
* @instance
|
|
347
|
-
* @memberof Polygon
|
|
348
|
-
**/
|
|
349
|
-
toCubicBezierData( threshold:number|undefined ) : Array<Vertex> {
|
|
350
|
-
if( typeof threshold == 'undefined' )
|
|
351
|
-
threshold = 1.0;
|
|
352
|
-
|
|
353
|
-
if( this.vertices.length < 3 )
|
|
354
|
-
return [];
|
|
355
|
-
var cbezier : Array<Vertex> = [];
|
|
356
|
-
var a : Vertex = this.vertices[0];
|
|
357
|
-
var b : Vertex = this.vertices[1];
|
|
358
|
-
var edgeCenter = new Vertex( a.x + (b.x-a.x)/2, a.y + (b.y-a.y)/2 );
|
|
359
|
-
cbezier.push( edgeCenter );
|
|
360
|
-
|
|
361
|
-
var limit : number = this.isOpen ? this.vertices.length-1 : this.vertices.length;
|
|
362
|
-
for( var t = 0; t < limit; t++ ) {
|
|
363
|
-
var a = this.vertices[ t%this.vertices.length ];
|
|
364
|
-
var b = this.vertices[ (t+1)%this.vertices.length ];
|
|
365
|
-
var c = this.vertices[ (t+2)%this.vertices.length ];
|
|
366
|
-
|
|
367
|
-
var aCenter : Vertex = new Vertex( a.x + (b.x-a.x)/2, a.y + (b.y-a.y)/2 );
|
|
368
|
-
var bCenter : Vertex = new Vertex( b.x + (c.x-b.x)/2, b.y + (c.y-b.y)/2 );
|
|
369
|
-
|
|
370
|
-
var a2 : Vertex = new Vertex( aCenter.x + (b.x-aCenter.x)*threshold, aCenter.y + (b.y-aCenter.y)*threshold );
|
|
371
|
-
var b0 : Vertex = new Vertex( bCenter.x + (b.x-bCenter.x)*threshold, bCenter.y + (b.y-bCenter.y)*threshold );
|
|
372
|
-
|
|
373
|
-
cbezier.push( a2 );
|
|
374
|
-
cbezier.push( b0 );
|
|
375
|
-
cbezier.push( bCenter );
|
|
376
|
-
|
|
377
|
-
}
|
|
378
|
-
return cbezier;
|
|
379
|
-
|
|
380
|
-
};
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
/**
|
|
385
|
-
* Convert this polygon to a cubic bezier curve, represented as an SVG data string.
|
|
386
|
-
*
|
|
387
|
-
* @method toCubicBezierSVGString
|
|
388
|
-
* @return {string} The 'd' part for an SVG 'path' element.
|
|
389
|
-
* @instance
|
|
390
|
-
* @memberof Polygon
|
|
391
|
-
**/
|
|
392
|
-
toCubicBezierSVGString( threshold:number ) : string {
|
|
393
|
-
var qdata : Array<Vertex> = this.toCubicBezierData( threshold );
|
|
394
|
-
if( qdata.length == 0 )
|
|
395
|
-
return "";
|
|
396
|
-
var buffer = [ 'M ' + qdata[0].x+' '+qdata[0].y ];
|
|
397
|
-
for( var i = 1; i < qdata.length; i+=3 ) {
|
|
398
|
-
buffer.push( 'C ' + qdata[i].x+' '+qdata[i].y + ', ' + qdata[i+1].x+' '+qdata[i+1].y + ', ' + qdata[i+2].x + ' ' + qdata[i+2].y );
|
|
399
|
-
}
|
|
400
|
-
return buffer.join(' ');
|
|
401
|
-
};
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* Convert this polygon to a cubic bezier path instance.
|
|
407
|
-
*
|
|
408
|
-
* @method toCubicBezierPath
|
|
409
|
-
* @param {number} threshold - The threshold, usually from 0.0 to 1.0.
|
|
410
|
-
* @return {BezierPath} - A bezier path instance.
|
|
411
|
-
* @instance
|
|
412
|
-
* @memberof Polygon
|
|
413
|
-
**/
|
|
414
|
-
toCubicBezierPath( threshold:number ) : BezierPath {
|
|
415
|
-
var qdata : Array<Vertex> = this.toCubicBezierData( threshold );
|
|
416
|
-
// Conver the linear path vertices to a two-dimensional path array
|
|
417
|
-
var pathdata : Array<Array<Vertex>> = [];
|
|
418
|
-
for( var i = 0; i+3 < qdata.length; i+=3 ) {
|
|
419
|
-
pathdata.push( [ qdata[i], qdata[i+3], qdata[i+1], qdata[i+2] ] );
|
|
420
|
-
}
|
|
421
|
-
return BezierPath.fromArray( pathdata );
|
|
422
|
-
};
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
/**
|
|
426
|
-
* Create an SVG representation of this polygon.
|
|
427
|
-
*
|
|
428
|
-
* @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
|
|
429
|
-
* @method toSVGString
|
|
430
|
-
* @param {object=} options - An optional set of options, like 'className'.
|
|
431
|
-
* @return {string} The SVG string.
|
|
432
|
-
* @instance
|
|
433
|
-
* @memberof Polygon
|
|
434
|
-
**/
|
|
435
|
-
toSVGString( options:{ className? : string }|undefined ) : string {
|
|
436
|
-
options = options || {};
|
|
437
|
-
var buffer : Array<string> = [];
|
|
438
|
-
buffer.push( '<path' );
|
|
439
|
-
if( options.className )
|
|
440
|
-
buffer.push( ' class="' + options.className + '"' );
|
|
441
|
-
buffer.push( ' d="' );
|
|
442
|
-
if( this.vertices.length > 0 ) {
|
|
443
|
-
buffer.push( 'M ' );
|
|
444
|
-
buffer.push( this.vertices[0].x.toString() )
|
|
445
|
-
buffer.push( ' ' );
|
|
446
|
-
buffer.push( this.vertices[0].y.toString() );
|
|
447
|
-
for( var i = 1; i < this.vertices.length; i++ ) {
|
|
448
|
-
buffer.push( ' L ' );
|
|
449
|
-
buffer.push( this.vertices[i].x.toString() )
|
|
450
|
-
buffer.push( ' ' );
|
|
451
|
-
buffer.push( this.vertices[i].y.toString() );
|
|
452
|
-
}
|
|
453
|
-
if( !this.isOpen ) {
|
|
454
|
-
buffer.push( ' Z' );
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
buffer.push( '" />' );
|
|
458
|
-
return buffer.join('');
|
|
459
|
-
};
|
|
460
|
-
|
|
461
|
-
static utils = {
|
|
462
|
-
|
|
463
|
-
/**
|
|
464
|
-
* Calculate the area of the given polygon (unsigned).
|
|
465
|
-
*
|
|
466
|
-
* Note that this does not work for self-intersecting polygons.
|
|
467
|
-
*
|
|
468
|
-
* @name area
|
|
469
|
-
* @return {number}
|
|
470
|
-
*/
|
|
471
|
-
area( vertices : Array<XYCoords> ) : number {
|
|
472
|
-
// Found at:
|
|
473
|
-
// https://stackoverflow.com/questions/16285134/calculating-polygon-area
|
|
474
|
-
let total : number = 0.0;
|
|
475
|
-
|
|
476
|
-
for (var i = 0, l = vertices.length; i < l; i++) {
|
|
477
|
-
const addX = vertices[i].x;
|
|
478
|
-
const addY = vertices[(i + 1)%l].y;
|
|
479
|
-
const subX = vertices[(i + 1)%l].x;
|
|
480
|
-
const subY = vertices[i].y;
|
|
481
|
-
|
|
482
|
-
total += (addX * addY * 0.5);
|
|
483
|
-
total -= (subX * subY * 0.5);
|
|
484
|
-
}
|
|
485
|
-
return Math.abs(total);
|
|
486
|
-
},
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
/**
|
|
490
|
-
* Calulate the signed polyon area by interpreting the polygon as a matrix
|
|
491
|
-
* and calculating its determinant.
|
|
492
|
-
*
|
|
493
|
-
* @name signedArea
|
|
494
|
-
* @return {number}
|
|
495
|
-
*/
|
|
496
|
-
signedArea( vertices : Array<XYCoords> ) : number {
|
|
497
|
-
let sum : number = 0;
|
|
498
|
-
const n = vertices.length;
|
|
499
|
-
for (var i = 0; i < n; i++ ) {
|
|
500
|
-
const j = (i+1) % n;
|
|
501
|
-
sum += (vertices[j].x - vertices[i].x) * (vertices[i].y + vertices[j].y);
|
|
502
|
-
}
|
|
503
|
-
return sum;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
};
|
|
507
|
-
|
|
540
|
+
signedArea(vertices: Array<XYCoords>): number {
|
|
541
|
+
let sum: number = 0;
|
|
542
|
+
const n = vertices.length;
|
|
543
|
+
for (var i = 0; i < n; i++) {
|
|
544
|
+
const j = (i + 1) % n;
|
|
545
|
+
sum += (vertices[j].x - vertices[i].x) * (vertices[i].y + vertices[j].y);
|
|
546
|
+
}
|
|
547
|
+
return sum;
|
|
548
|
+
}
|
|
549
|
+
};
|
|
508
550
|
}
|