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.
Files changed (232) hide show
  1. package/README.md +2 -0
  2. package/changelog.md +57 -0
  3. package/dist/index.esm.js +856 -694
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.esm.min.js +1 -1
  6. package/dist/index.esm.min.js.map +1 -1
  7. package/dist/plotboilerplate.browser.min.js +1 -1
  8. package/dist/plotboilerplate.browser.min.js.map +1 -1
  9. package/dist/plotboilerplate.js +858 -598
  10. package/dist/plotboilerplate.min.js +1 -1
  11. package/package.json +1 -1
  12. package/src/cjs/BezierPath.d.ts +32 -14
  13. package/src/cjs/BezierPath.js +65 -24
  14. package/src/cjs/BezierPath.js.map +1 -1
  15. package/src/cjs/Bounds.d.ts +22 -1
  16. package/src/cjs/Bounds.js +24 -1
  17. package/src/cjs/Bounds.js.map +1 -1
  18. package/src/cjs/Circle.d.ts +15 -13
  19. package/src/cjs/Circle.js +16 -34
  20. package/src/cjs/Circle.js.map +1 -1
  21. package/src/cjs/CircleSector.d.ts +17 -16
  22. package/src/cjs/CircleSector.js +12 -24
  23. package/src/cjs/CircleSector.js.map +1 -1
  24. package/src/cjs/CubicBezierCurve.d.ts +16 -15
  25. package/src/cjs/CubicBezierCurve.js +57 -94
  26. package/src/cjs/CubicBezierCurve.js.map +1 -1
  27. package/src/cjs/KeyHandler.d.ts +10 -3
  28. package/src/cjs/KeyHandler.js +28 -23
  29. package/src/cjs/KeyHandler.js.map +1 -1
  30. package/src/cjs/Line.d.ts +2 -15
  31. package/src/cjs/Line.js +6 -31
  32. package/src/cjs/Line.js.map +1 -1
  33. package/src/cjs/MouseHandler.js +43 -53
  34. package/src/cjs/MouseHandler.js.map +1 -1
  35. package/src/cjs/PBImage.d.ts +15 -13
  36. package/src/cjs/PBImage.js +11 -15
  37. package/src/cjs/PBImage.js.map +1 -1
  38. package/src/cjs/PBText.d.ts +13 -12
  39. package/src/cjs/PBText.js +8 -12
  40. package/src/cjs/PBText.js.map +1 -1
  41. package/src/cjs/PlotBoilerplate.js +3 -2
  42. package/src/cjs/PlotBoilerplate.js.map +1 -1
  43. package/src/cjs/Polygon.d.ts +44 -14
  44. package/src/cjs/Polygon.js +116 -66
  45. package/src/cjs/Polygon.js.map +1 -1
  46. package/src/cjs/Triangle.d.ts +15 -13
  47. package/src/cjs/Triangle.js +23 -64
  48. package/src/cjs/Triangle.js.map +1 -1
  49. package/src/cjs/VEllipse.d.ts +14 -9
  50. package/src/cjs/VEllipse.js +10 -18
  51. package/src/cjs/VEllipse.js.map +1 -1
  52. package/src/cjs/VEllipseSector.d.ts +15 -1
  53. package/src/cjs/VEllipseSector.js +11 -1
  54. package/src/cjs/VEllipseSector.js.map +1 -1
  55. package/src/cjs/Vector.d.ts +3 -15
  56. package/src/cjs/Vector.js +9 -49
  57. package/src/cjs/Vector.js.map +1 -1
  58. package/src/cjs/VertTuple.d.ts +15 -1
  59. package/src/cjs/VertTuple.js +14 -19
  60. package/src/cjs/VertTuple.js.map +1 -1
  61. package/src/cjs/Vertex.d.ts +47 -13
  62. package/src/cjs/Vertex.js +62 -22
  63. package/src/cjs/Vertex.js.map +1 -1
  64. package/src/cjs/VertexListeners.d.ts +12 -8
  65. package/src/cjs/VertexListeners.js +18 -25
  66. package/src/cjs/VertexListeners.js.map +1 -1
  67. package/src/cjs/draw.d.ts +41 -2
  68. package/src/cjs/draw.js +140 -3
  69. package/src/cjs/draw.js.map +1 -1
  70. package/src/cjs/drawgl.d.ts +38 -2
  71. package/src/cjs/drawgl.js +41 -2
  72. package/src/cjs/drawgl.js.map +1 -1
  73. package/src/cjs/drawutilssvg.d.ts +66 -3
  74. package/src/cjs/drawutilssvg.js +140 -15
  75. package/src/cjs/drawutilssvg.js.map +1 -1
  76. package/src/cjs/index.d.ts +0 -1
  77. package/src/cjs/index.js +0 -1
  78. package/src/cjs/index.js.map +1 -1
  79. package/src/cjs/interfaces/DrawLib.d.ts +61 -26
  80. package/src/cjs/interfaces/DrawLib.js +2 -0
  81. package/src/cjs/interfaces/DrawLib.js.map +1 -1
  82. package/src/cjs/interfaces/core.d.ts +0 -12
  83. package/src/cjs/module.d.ts +1 -3
  84. package/src/cjs/module.js +2 -5
  85. package/src/cjs/module.js.map +1 -1
  86. package/src/cjs/utils/creategui.js +16 -2
  87. package/src/cjs/utils/datastructures/Girih.d.ts +5 -0
  88. package/src/cjs/utils/datastructures/Girih.js +18 -14
  89. package/src/cjs/utils/datastructures/Girih.js.map +1 -1
  90. package/src/cjs/utils/datastructures/GirihPenroseRhombus.js +42 -25
  91. package/src/cjs/utils/datastructures/GirihPenroseRhombus.js.map +1 -1
  92. package/src/cjs/utils/datastructures/GirihTile.js +2 -13
  93. package/src/cjs/utils/datastructures/GirihTile.js.map +1 -1
  94. package/src/cjs/utils/findInVertexArray.d.ts +19 -0
  95. package/src/cjs/utils/findInVertexArray.js +29 -0
  96. package/src/cjs/utils/findInVertexArray.js.map +1 -0
  97. package/src/cjs/utils/helpers/BezierPathInteractionHelper.d.ts +17 -1
  98. package/src/cjs/utils/helpers/BezierPathInteractionHelper.js +50 -32
  99. package/src/cjs/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
  100. package/src/cjs/utils/io/DndFileHandler.d.ts +63 -0
  101. package/src/cjs/utils/io/DndFileHandler.js +112 -0
  102. package/src/cjs/utils/io/DndFileHandler.js.map +1 -0
  103. package/src/cjs/utils/io/FileDrop.d.ts +98 -0
  104. package/src/cjs/utils/io/FileDrop.js +142 -0
  105. package/src/cjs/utils/io/FileDrop.js.map +1 -0
  106. package/src/esm/BezierPath.d.ts +32 -14
  107. package/src/esm/BezierPath.js +65 -24
  108. package/src/esm/BezierPath.js.map +1 -1
  109. package/src/esm/Bounds.d.ts +22 -1
  110. package/src/esm/Bounds.js +24 -1
  111. package/src/esm/Bounds.js.map +1 -1
  112. package/src/esm/Circle.d.ts +15 -13
  113. package/src/esm/Circle.js +16 -34
  114. package/src/esm/Circle.js.map +1 -1
  115. package/src/esm/CircleSector.d.ts +17 -16
  116. package/src/esm/CircleSector.js +12 -24
  117. package/src/esm/CircleSector.js.map +1 -1
  118. package/src/esm/CubicBezierCurve.d.ts +16 -15
  119. package/src/esm/CubicBezierCurve.js +57 -94
  120. package/src/esm/CubicBezierCurve.js.map +1 -1
  121. package/src/esm/KeyHandler.d.ts +10 -3
  122. package/src/esm/KeyHandler.js +28 -23
  123. package/src/esm/KeyHandler.js.map +1 -1
  124. package/src/esm/Line.d.ts +2 -15
  125. package/src/esm/Line.js +6 -31
  126. package/src/esm/Line.js.map +1 -1
  127. package/src/esm/MouseHandler.js +43 -53
  128. package/src/esm/MouseHandler.js.map +1 -1
  129. package/src/esm/PBImage.d.ts +15 -13
  130. package/src/esm/PBImage.js +11 -15
  131. package/src/esm/PBImage.js.map +1 -1
  132. package/src/esm/PBText.d.ts +13 -12
  133. package/src/esm/PBText.js +8 -12
  134. package/src/esm/PBText.js.map +1 -1
  135. package/src/esm/PlotBoilerplate.js +3 -2
  136. package/src/esm/PlotBoilerplate.js.map +1 -1
  137. package/src/esm/Polygon.d.ts +44 -14
  138. package/src/esm/Polygon.js +116 -66
  139. package/src/esm/Polygon.js.map +1 -1
  140. package/src/esm/Triangle.d.ts +15 -13
  141. package/src/esm/Triangle.js +23 -64
  142. package/src/esm/Triangle.js.map +1 -1
  143. package/src/esm/VEllipse.d.ts +14 -9
  144. package/src/esm/VEllipse.js +10 -18
  145. package/src/esm/VEllipse.js.map +1 -1
  146. package/src/esm/VEllipseSector.d.ts +15 -1
  147. package/src/esm/VEllipseSector.js +11 -1
  148. package/src/esm/VEllipseSector.js.map +1 -1
  149. package/src/esm/Vector.d.ts +3 -15
  150. package/src/esm/Vector.js +9 -49
  151. package/src/esm/Vector.js.map +1 -1
  152. package/src/esm/VertTuple.d.ts +15 -1
  153. package/src/esm/VertTuple.js +14 -19
  154. package/src/esm/VertTuple.js.map +1 -1
  155. package/src/esm/Vertex.d.ts +47 -13
  156. package/src/esm/Vertex.js +62 -22
  157. package/src/esm/Vertex.js.map +1 -1
  158. package/src/esm/VertexListeners.d.ts +12 -8
  159. package/src/esm/VertexListeners.js +18 -25
  160. package/src/esm/VertexListeners.js.map +1 -1
  161. package/src/esm/draw.d.ts +41 -2
  162. package/src/esm/draw.js +139 -3
  163. package/src/esm/draw.js.map +1 -1
  164. package/src/esm/drawgl.d.ts +38 -2
  165. package/src/esm/drawgl.js +41 -2
  166. package/src/esm/drawgl.js.map +1 -1
  167. package/src/esm/drawutilssvg.d.ts +66 -3
  168. package/src/esm/drawutilssvg.js +140 -15
  169. package/src/esm/drawutilssvg.js.map +1 -1
  170. package/src/esm/index.d.ts +0 -1
  171. package/src/esm/index.js +0 -1
  172. package/src/esm/index.js.map +1 -1
  173. package/src/esm/interfaces/DrawLib.d.ts +61 -26
  174. package/src/esm/interfaces/DrawLib.js +2 -0
  175. package/src/esm/interfaces/DrawLib.js.map +1 -1
  176. package/src/esm/interfaces/core.d.ts +0 -12
  177. package/src/esm/module.d.ts +1 -3
  178. package/src/esm/module.js +5 -4
  179. package/src/esm/module.js.map +1 -1
  180. package/src/esm/utils/datastructures/Girih.d.ts +5 -0
  181. package/src/esm/utils/datastructures/Girih.js +18 -14
  182. package/src/esm/utils/datastructures/Girih.js.map +1 -1
  183. package/src/esm/utils/datastructures/GirihPenroseRhombus.js +42 -25
  184. package/src/esm/utils/datastructures/GirihPenroseRhombus.js.map +1 -1
  185. package/src/esm/utils/datastructures/GirihTile.js +2 -13
  186. package/src/esm/utils/datastructures/GirihTile.js.map +1 -1
  187. package/src/esm/utils/findInVertexArray.d.ts +19 -0
  188. package/src/esm/utils/findInVertexArray.js +25 -0
  189. package/src/esm/utils/findInVertexArray.js.map +1 -0
  190. package/src/esm/utils/helpers/BezierPathInteractionHelper.d.ts +17 -1
  191. package/src/esm/utils/helpers/BezierPathInteractionHelper.js +49 -32
  192. package/src/esm/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
  193. package/src/esm/utils/io/DndFileHandler.d.ts +63 -0
  194. package/src/esm/utils/io/DndFileHandler.js +106 -0
  195. package/src/esm/utils/io/DndFileHandler.js.map +1 -0
  196. package/src/esm/utils/io/FileDrop.d.ts +98 -0
  197. package/src/esm/utils/io/FileDrop.js +136 -0
  198. package/src/esm/utils/io/FileDrop.js.map +1 -0
  199. package/src/ts/BezierPath.ts +78 -22
  200. package/src/ts/Bounds.ts +25 -1
  201. package/src/ts/Circle.ts +187 -200
  202. package/src/ts/CircleSector.ts +141 -141
  203. package/src/ts/CubicBezierCurve.ts +738 -810
  204. package/src/ts/KeyHandler.ts +221 -212
  205. package/src/ts/Line.ts +48 -80
  206. package/src/ts/MouseHandler.ts +356 -368
  207. package/src/ts/PBImage.ts +67 -69
  208. package/src/ts/PBText.ts +16 -14
  209. package/src/ts/PlotBoilerplate.ts +4 -2
  210. package/src/ts/Polygon.ts +493 -451
  211. package/src/ts/Triangle.ts +444 -489
  212. package/src/ts/VEllipse.ts +18 -17
  213. package/src/ts/VEllipseSector.ts +20 -1
  214. package/src/ts/Vector.ts +124 -160
  215. package/src/ts/VertTuple.ts +333 -338
  216. package/src/ts/Vertex.ts +75 -21
  217. package/src/ts/VertexListeners.ts +248 -266
  218. package/src/ts/draw.ts +192 -3
  219. package/src/ts/drawgl.ts +44 -2
  220. package/src/ts/drawutilssvg.ts +181 -15
  221. package/src/ts/index.ts +0 -1
  222. package/src/ts/interfaces/DrawLib.ts +69 -26
  223. package/src/ts/interfaces/core.ts +0 -11
  224. package/src/ts/module.ts +2 -4
  225. package/src/ts/utils/datastructures/Girih.ts +204 -209
  226. package/src/ts/utils/datastructures/GirihPenroseRhombus.ts +170 -152
  227. package/src/ts/utils/datastructures/GirihTile.ts +394 -419
  228. package/src/ts/utils/findInVertexArray.ts +28 -0
  229. package/src/ts/utils/helpers/BezierPathInteractionHelper.ts +56 -34
  230. package/src/ts/utils/io/FileDrop.ts +178 -0
  231. package/src/ts/SVGBuilder.ts +0 -109
  232. 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
- * @version 1.7.0
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
- * Required to generate proper CSS classes and other class related IDs.
51
- **/
52
- readonly className : string = "Polygon";
53
-
54
-
55
- /**
56
- * The UID of this drawable object.
57
- *
58
- * @member {UID}
59
- * @memberof Polygon
60
- * @instance
61
- * @readonly
62
- */
63
- readonly uid : UID;
64
-
65
-
66
- /**
67
- * @member {Array<Vertex>}
68
- * @memberof Polygon
69
- * @type {Array<Vertex>}
70
- * @instance
71
- */
72
- vertices:Array<Vertex>;
73
-
74
-
75
- /**
76
- * @member {boolean}
77
- * @memberof Polygon
78
- * @type {boolean}
79
- * @instance
80
- */
81
- isOpen:boolean;
82
-
83
-
84
- /**
85
- * The constructor.
86
- *
87
- * @constructor
88
- * @name Polygon
89
- * @param {Vertex[]} vertices - An array of 2d vertices that shape the polygon.
90
- * @param {boolean} isOpen - Indicates if the polygon should be rendered as an open or closed shape.
91
- **/
92
- constructor( vertices?:Array<Vertex>, isOpen?:boolean ) {
93
- this.uid = UIDGenerator.next();
94
- if( typeof vertices == 'undefined' )
95
- vertices = [];
96
- this.vertices = vertices;
97
- this.isOpen = isOpen;
98
- };
99
-
100
-
101
- /**
102
- * Add a vertex to the end of the `vertices` array.
103
- *
104
- * @method addVert
105
- * @param {Vertex} vert - The vertex to add.
106
- * @instance
107
- * @memberof Polygon
108
- **/
109
- addVertex( vert:Vertex ) : void {
110
- this.vertices.push( vert );
111
- };
112
-
113
-
114
- /**
115
- * Get the polygon vertex at the given position (index).
116
- *
117
- * The index may exceed the total vertex count, and will be wrapped around then (modulo).
118
- *
119
- * For k >= 0:
120
- * - getVertexAt( vertices.length ) == getVertexAt( 0 )
121
- * - getVertexAt( vertices.length + k ) == getVertexAt( k )
122
- * - getVertexAt( -k ) == getVertexAt( vertices.length -k )
123
- *
124
- * @metho getVertexAt
125
- * @param {number} index - The index of the desired vertex.
126
- * @instance
127
- * @memberof Polygon
128
- * @return {Vertex} At the given index.
129
- **/
130
- getVertexAt( index:number ) : Vertex {
131
- if( index < 0 )
132
- return this.vertices[ this.vertices.length - (Math.abs(index)%this.vertices.length) ];
133
- else
134
- return this.vertices[ index % this.vertices.length ];
135
- };
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( vert:XYCoords ) : Polygon {
148
- for( var i in this.vertices ) {
149
- this.vertices[i].add( vert );
150
- }
151
- return this;
152
- };
153
-
154
-
155
- /**
156
- * Check if the given vertex is inside this polygon.<br>
157
- * <br>
158
- * Ray-casting algorithm found at<br>
159
- * https://stackoverflow.com/questions/22521982/check-if-point-inside-a-polygon
160
- *
161
- * @method containsVert
162
- * @param {XYCoords} vert - The vertex to check. The new x-component.
163
- * @return {boolean} True if the passed vertex is inside this polygon. The polygon is considered closed.
164
- * @instance
165
- * @memberof Polygon
166
- **/
167
- containsVert( vert:XYCoords ) : boolean {
168
- // ray-casting algorithm based on
169
- // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
170
- var inside : boolean = false;
171
- for (var i = 0, j = this.vertices.length - 1; i < this.vertices.length; j = i++) {
172
- let xi : number = this.vertices[i].x, yi : number = this.vertices[i].y;
173
- let xj : number = this.vertices[j].x, yj : number = this.vertices[j].y;
174
-
175
- var intersect : boolean = ((yi > vert.y) != (yj > vert.y))
176
- && (vert.x < (xj - xi) * (vert.y - yi) / (yj - yi) + xi);
177
- if (intersect) inside = !inside;
178
- }
179
- return inside;
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
- * @method area
189
- * @instance
190
- * @memberof Polygon
513
+ * @name area
191
514
  * @return {number}
192
515
  */
193
- area() : number {
194
- return Polygon.utils.area(this.vertices);
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
- * @method signedArea
203
- * @instance
204
- * @memberof Polygon
537
+ * @name signedArea
205
538
  * @return {number}
206
539
  */
207
- signedArea() : number {
208
- return Polygon.utils.signedArea(this.vertices)
209
- };
210
-
211
-
212
- /**
213
- * Get the winding order of this polgon: clockwise or counterclockwise.
214
- *
215
- * @method isClockwise
216
- * @instance
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
  }