plotboilerplate 1.15.0 → 1.17.1
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 +1 -0
- package/changelog.md +65 -0
- package/dist/index.esm.js +760 -667
- 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 +765 -571
- 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 +33 -1
- package/src/cjs/Bounds.js +38 -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.d.ts +3 -1
- package/src/cjs/PlotBoilerplate.js +9 -2
- package/src/cjs/PlotBoilerplate.js.map +1 -1
- package/src/cjs/Polygon.d.ts +23 -14
- package/src/cjs/Polygon.js +22 -35
- 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 +23 -13
- package/src/cjs/Vertex.js +24 -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 +45 -3
- package/src/cjs/draw.js +149 -6
- package/src/cjs/draw.js.map +1 -1
- package/src/cjs/drawgl.d.ts +41 -3
- package/src/cjs/drawgl.js +45 -3
- package/src/cjs/drawgl.js.map +1 -1
- package/src/cjs/drawutilssvg.d.ts +69 -4
- package/src/cjs/drawutilssvg.js +147 -16
- 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 +64 -27
- package/src/cjs/interfaces/DrawLib.js +3 -0
- package/src/cjs/interfaces/DrawLib.js.map +1 -1
- package/src/cjs/interfaces/core.d.ts +2 -12
- package/src/cjs/interfaces/core.js +1 -0
- package/src/cjs/interfaces/core.js.map +1 -1
- 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/Color.d.ts +3 -1
- package/src/cjs/utils/datastructures/Color.js +17 -6
- package/src/cjs/utils/datastructures/Color.js.map +1 -1
- 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/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 +33 -1
- package/src/esm/Bounds.js +38 -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.d.ts +3 -1
- package/src/esm/PlotBoilerplate.js +9 -2
- package/src/esm/PlotBoilerplate.js.map +1 -1
- package/src/esm/Polygon.d.ts +23 -14
- package/src/esm/Polygon.js +22 -35
- 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 +23 -13
- package/src/esm/Vertex.js +24 -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 +45 -3
- package/src/esm/draw.js +147 -6
- package/src/esm/draw.js.map +1 -1
- package/src/esm/drawgl.d.ts +41 -3
- package/src/esm/drawgl.js +44 -3
- package/src/esm/drawgl.js.map +1 -1
- package/src/esm/drawutilssvg.d.ts +69 -4
- package/src/esm/drawutilssvg.js +146 -16
- 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 +64 -27
- package/src/esm/interfaces/DrawLib.js +3 -0
- package/src/esm/interfaces/DrawLib.js.map +1 -1
- package/src/esm/interfaces/core.d.ts +2 -12
- package/src/esm/interfaces/core.js +1 -0
- package/src/esm/interfaces/core.js.map +1 -1
- 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/Color.d.ts +3 -1
- package/src/esm/utils/datastructures/Color.js +17 -6
- package/src/esm/utils/datastructures/Color.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/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 +40 -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 +9 -2
- package/src/ts/Polygon.ts +34 -34
- 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 +35 -21
- package/src/ts/VertexListeners.ts +248 -266
- package/src/ts/draw.ts +201 -6
- package/src/ts/drawgl.ts +47 -3
- package/src/ts/drawutilssvg.ts +187 -16
- package/src/ts/index.ts +0 -1
- package/src/ts/interfaces/DrawLib.ts +72 -27
- package/src/ts/interfaces/core.ts +3 -13
- package/src/ts/module.ts +2 -4
- package/src/ts/utils/datastructures/Color.ts +17 -6
- 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/helpers/BezierPathInteractionHelper.ts +56 -34
- package/src/ts/utils/io/FileDrop.ts +178 -0
- package/src/ts/SVGBuilder.ts +0 -109
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
* @modified 2020-07-14 Changed the moveCurvePoint(...,Vertex) to moveCurvePoint(...,XYCoords), which is more generic.
|
|
19
19
|
* @modified 2020-07-24 Added the getClosestT function and the helper function locateIntervalByDistance(...).
|
|
20
20
|
* @modified 2021-01-20 Added UID.
|
|
21
|
-
* @
|
|
21
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
22
|
+
* @modified 2022-02-02 Cleared the `toSVGPathData` function (deprecated). Use `drawutilssvg` instead.
|
|
23
|
+
* @version 2.6.0
|
|
22
24
|
*
|
|
23
25
|
* @file CubicBezierCurve
|
|
24
26
|
* @public
|
|
@@ -30,7 +32,6 @@ import { Vertex } from "./Vertex";
|
|
|
30
32
|
import { Vector } from "./Vector";
|
|
31
33
|
import { XYCoords, UID } from "./interfaces";
|
|
32
34
|
|
|
33
|
-
|
|
34
35
|
/**
|
|
35
36
|
* @classdesc A refactored cubic bezier curve class.
|
|
36
37
|
*
|
|
@@ -42,682 +43,643 @@ import { XYCoords, UID } from "./interfaces";
|
|
|
42
43
|
* @requires UIDGenerator
|
|
43
44
|
*/
|
|
44
45
|
export class CubicBezierCurve {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
*
|
|
355
|
-
* @return {object} - An object with t, tPrev and tNext (numbers).
|
|
356
|
-
**/
|
|
357
|
-
private locateIntervalByDistance( p:Vertex,
|
|
358
|
-
tStart:number,
|
|
359
|
-
tEnd:number,
|
|
360
|
-
stepCount : number ) :
|
|
361
|
-
{ t:number; tPrev:number; tNext:number} {
|
|
362
|
-
var minIndex : number = -1;
|
|
363
|
-
var minDist : number = 0;
|
|
364
|
-
var t : number = 0.0;
|
|
365
|
-
const tDiff : number = tEnd - tStart;
|
|
366
|
-
for( var i = 0; i <= stepCount; i++ ) {
|
|
367
|
-
t = tStart + tDiff * (i / stepCount);
|
|
368
|
-
var vert : Vertex = this.getPointAt(t);
|
|
369
|
-
var dist : number = vert.distance(p);
|
|
370
|
-
if( minIndex == -1 || dist < minDist ) {
|
|
371
|
-
minIndex = i;
|
|
372
|
-
minDist = dist;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
return { t : tStart + tDiff * (minIndex/stepCount),
|
|
376
|
-
tPrev : tStart + tDiff * (Math.max(0,minIndex-1)/stepCount),
|
|
377
|
-
tNext : tStart + tDiff * (Math.min(stepCount,minIndex+1)/stepCount)
|
|
378
|
-
};
|
|
379
|
-
};
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* Get the bounds of this bezier curve.
|
|
384
|
-
*
|
|
385
|
-
* The bounds are approximated by the underlying segment buffer; the more segment there are,
|
|
386
|
-
* the more accurate will be the returned bounds.
|
|
387
|
-
*
|
|
388
|
-
* @return {Bounds} The bounds of this curve.
|
|
389
|
-
**/
|
|
390
|
-
getBounds() : Bounds {
|
|
391
|
-
var min : Vertex = new Vertex( Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY );
|
|
392
|
-
var max : Vertex = new Vertex( Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY );
|
|
393
|
-
let v : Vertex;
|
|
394
|
-
for( var i = 0; i < this.segmentCache.length; i++ ) {
|
|
395
|
-
v = this.segmentCache[i];
|
|
396
|
-
min.x = Math.min( min.x, v.x );
|
|
397
|
-
min.y = Math.min( min.y, v.y );
|
|
398
|
-
max.x = Math.max( max.x, v.x );
|
|
399
|
-
max.y = Math.max( max.y, v.y );
|
|
400
|
-
}
|
|
401
|
-
return new Bounds( min, max );
|
|
402
|
-
};
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* Get the start point of the curve.<br>
|
|
407
|
-
* <br>
|
|
408
|
-
* This function just returns this.startPoint.
|
|
409
|
-
*
|
|
410
|
-
* @method getStartPoint
|
|
411
|
-
* @instance
|
|
412
|
-
* @memberof CubicBezierCurve
|
|
413
|
-
* @return {Vertex} this.startPoint
|
|
414
|
-
**/
|
|
415
|
-
getStartPoint() : Vertex {
|
|
416
|
-
return this.startPoint;
|
|
417
|
-
};
|
|
418
|
-
|
|
419
|
-
/**
|
|
420
|
-
* Get the end point of the curve.<br>
|
|
421
|
-
* <br>
|
|
422
|
-
* This function just returns this.endPoint.
|
|
423
|
-
*
|
|
424
|
-
* @method getEndPoint
|
|
425
|
-
* @instance
|
|
426
|
-
* @memberof CubicBezierCurve
|
|
427
|
-
* @return {Vertex} this.endPoint
|
|
428
|
-
**/
|
|
429
|
-
getEndPoint() : Vertex {
|
|
430
|
-
return this.endPoint;
|
|
431
|
-
};
|
|
432
|
-
|
|
433
|
-
/**
|
|
434
|
-
* Get the start control point of the curve.<br>
|
|
435
|
-
* <br>
|
|
436
|
-
* This function just returns this.startControlPoint.
|
|
437
|
-
*
|
|
438
|
-
* @method getStartControlPoint
|
|
439
|
-
* @instance
|
|
440
|
-
* @memberof CubicBezierCurve
|
|
441
|
-
* @return {Vertex} this.startControlPoint
|
|
442
|
-
**/
|
|
443
|
-
getStartControlPoint() : Vertex {
|
|
444
|
-
return this.startControlPoint;
|
|
445
|
-
};
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* Get the end control point of the curve.<br>
|
|
449
|
-
* <br>
|
|
450
|
-
* This function just returns this.endControlPoint.
|
|
451
|
-
*
|
|
452
|
-
* @method getEndControlPoint
|
|
453
|
-
* @instance
|
|
454
|
-
* @memberof CubicBezierCurve
|
|
455
|
-
* @return {Vertex} this.endControlPoint
|
|
456
|
-
**/
|
|
457
|
-
getEndControlPoint() : Vertex {
|
|
458
|
-
return this.endControlPoint;
|
|
459
|
-
};
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
/**
|
|
463
|
-
* Get one of the four curve points specified by the passt point ID.
|
|
464
|
-
*
|
|
465
|
-
* @method getEndControlPoint
|
|
466
|
-
* @param {number} id - One of START_POINT, START_CONTROL_POINT, END_CONTROL_POINT or END_POINT.
|
|
467
|
-
* @instance
|
|
468
|
-
* @memberof CubicBezierCurve
|
|
469
|
-
* @return {Vertex}
|
|
470
|
-
**/
|
|
471
|
-
getPointByID( id:number ) : Vertex {
|
|
472
|
-
if( id == this.START_POINT ) return this.startPoint;
|
|
473
|
-
if( id == this.END_POINT ) return this.endPoint;
|
|
474
|
-
if( id == this.START_CONTROL_POINT ) return this.startControlPoint;
|
|
475
|
-
if( id == this.END_CONTROL_POINT ) return this.endControlPoint;
|
|
476
|
-
throw new Error(`Invalid point ID '${id}'.`);
|
|
477
|
-
};
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
/**
|
|
481
|
-
* Get the curve point at a given position t, where t is in [0,1].<br>
|
|
482
|
-
* <br>
|
|
483
|
-
* @see Line.pointAt
|
|
484
|
-
*
|
|
485
|
-
* @method getPointAt
|
|
486
|
-
* @param {number} t - The position on the curve in [0,1] (0 means at
|
|
487
|
-
* start point, 1 means at end point, other values address points in bertween).
|
|
488
|
-
* @instance
|
|
489
|
-
* @memberof CubicBezierCurve
|
|
490
|
-
* @return {Vertex}
|
|
491
|
-
**/
|
|
492
|
-
getPointAt( t:number ) : Vertex {
|
|
493
|
-
// Perform some powerful math magic
|
|
494
|
-
const x : number = this.startPoint.x * Math.pow(1.0-t,3) + this.startControlPoint.x*3*t*Math.pow(1.0-t,2)
|
|
495
|
-
+ this.endControlPoint.x*3*Math.pow(t,2)*(1.0-t)+this.endPoint.x*Math.pow(t,3);
|
|
496
|
-
const y : number = this.startPoint.y*Math.pow(1.0-t,3)+this.startControlPoint.y*3*t*Math.pow(1.0-t,2)
|
|
497
|
-
+ this.endControlPoint.y*3*Math.pow(t,2)*(1.0-t)+this.endPoint.y*Math.pow(t,3);
|
|
498
|
-
return new Vertex( x, y );
|
|
499
|
-
};
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
/**
|
|
503
|
-
* Get the curve point at a given position u, where u is in [0,arcLength].<br>
|
|
504
|
-
* <br>
|
|
505
|
-
* @see CubicBezierCurve.getPointAt
|
|
506
|
-
*
|
|
507
|
-
* @method getPoint
|
|
508
|
-
* @param {number} u - The position on the curve in [0,arcLength] (0 means at
|
|
509
|
-
* start point, arcLength means at end point, other values address points in bertween).
|
|
510
|
-
* @instance
|
|
511
|
-
* @memberof CubicBezierCurve
|
|
512
|
-
* @return {Vertex}
|
|
513
|
-
**/
|
|
514
|
-
getPoint( u:number ) : Vertex {
|
|
515
|
-
return this.getPointAt( u / this.arcLength );
|
|
516
|
-
};
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
/**
|
|
520
|
-
* Get the curve tangent vector at a given absolute curve position t in [0,1].<br>
|
|
521
|
-
* <br>
|
|
522
|
-
* Note that the returned tangent vector (end point) is not normalized and relative to (0,0).
|
|
523
|
-
*
|
|
524
|
-
* @method getTangent
|
|
525
|
-
* @param {number} t - The position on the curve in [0,1].
|
|
526
|
-
* @instance
|
|
527
|
-
* @memberof CubicBezierCurve
|
|
528
|
-
* @return {Vertex}
|
|
529
|
-
**/
|
|
530
|
-
getTangentAt( t:number ) : Vertex {
|
|
531
|
-
const a : Vertex = this.getStartPoint();
|
|
532
|
-
const b : Vertex = this.getStartControlPoint();
|
|
533
|
-
const c : Vertex = this.getEndControlPoint();
|
|
534
|
-
const d : Vertex = this.getEndPoint();
|
|
535
|
-
|
|
536
|
-
// This is the shortened one
|
|
537
|
-
const t2 : number = t * t;
|
|
538
|
-
// (1 - t)^2 = (1-t)*(1-t) = 1 - t - t + t^2 = 1 - 2*t + t^2
|
|
539
|
-
const nt2 : number = 1 - 2*t + t2;
|
|
540
|
-
|
|
541
|
-
const tX : number = -3 * a.x * nt2 +
|
|
542
|
-
b.x * (3 * nt2 - 6 *(t-t2) ) +
|
|
543
|
-
c.x * (6 *(t-t2) - 3*t2) +
|
|
544
|
-
3*d.x*t2;
|
|
545
|
-
const tY : number = -3 * a.y * nt2 +
|
|
546
|
-
b.y * (3 * nt2 - 6 *(t-t2) ) +
|
|
547
|
-
c.y * (6 *(t-t2) - 3*t2) +
|
|
548
|
-
3*d.y*t2;
|
|
549
|
-
|
|
550
|
-
// Note: my implementation does NOT normalize tangent vectors!
|
|
551
|
-
return new Vertex( tX, tY );
|
|
552
|
-
};
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
/**
|
|
556
|
-
* Get a sub curve at the given start end end offsets (values between 0.0 and 1.0).
|
|
557
|
-
*
|
|
558
|
-
* tStart >= tEnd is allowed, you will get a reversed sub curve then.
|
|
559
|
-
*
|
|
560
|
-
* @method getSubCurveAt
|
|
561
|
-
* @param {number} tStart – The start offset of the desired sub curve (must be in [0..1]).
|
|
562
|
-
* @param {number} tEnd – The end offset if the desired cub curve (must be in [0..1]).
|
|
563
|
-
* @instance
|
|
564
|
-
* @memberof CubicBezierCurve
|
|
565
|
-
* @return {CubicBezierCurve} The sub curve as a new curve.
|
|
566
|
-
**/
|
|
567
|
-
getSubCurveAt( tStart:number, tEnd:number ) : CubicBezierCurve {
|
|
568
|
-
const startVec : Vector = new Vector(
|
|
569
|
-
this.getPointAt(tStart),
|
|
570
|
-
this.getTangentAt(tStart)
|
|
571
|
-
);
|
|
572
|
-
const endVec : Vector = new Vector(
|
|
573
|
-
this.getPointAt(tEnd),
|
|
574
|
-
this.getTangentAt(tEnd).inv()
|
|
575
|
-
);
|
|
576
|
-
|
|
577
|
-
// Tangents are relative. Make absolute.
|
|
578
|
-
startVec.b.add( startVec.a )
|
|
579
|
-
endVec.b.add( endVec.a );
|
|
580
|
-
|
|
581
|
-
// This 'splits' the curve at the given point at t.
|
|
582
|
-
startVec.scale(0.33333333*(tEnd-tStart));
|
|
583
|
-
endVec.scale(0.33333333*(tEnd-tStart));
|
|
584
|
-
|
|
585
|
-
// Draw the bezier curve
|
|
586
|
-
// pb.draw.cubicBezier( startVec.a, endVec.a, startVec.b, endVec.b, '#8800ff', 2 );
|
|
587
|
-
return new CubicBezierCurve( startVec.a, endVec.a, startVec.b, endVec.b );
|
|
588
|
-
};
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
/**
|
|
592
|
-
* Convert a relative curve position u to the absolute curve position t.
|
|
593
|
-
*
|
|
594
|
-
* @method convertU2t
|
|
595
|
-
* @param {number} u - The relative position on the curve in [0,arcLength].
|
|
596
|
-
* @instance
|
|
597
|
-
* @memberof CubicBezierCurve
|
|
598
|
-
* @return {number}
|
|
599
|
-
**/
|
|
600
|
-
convertU2T( u:number ) : number {
|
|
601
|
-
return Math.max( 0.0,
|
|
602
|
-
Math.min( 1.0,
|
|
603
|
-
( u / this.arcLength )
|
|
604
|
-
)
|
|
605
|
-
);
|
|
606
|
-
};
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
/**
|
|
610
|
-
* Get the curve tangent vector at a given relative position u in [0,arcLength].<br>
|
|
611
|
-
* <br>
|
|
612
|
-
* Note that the returned tangent vector (end point) is not normalized.
|
|
613
|
-
*
|
|
614
|
-
* @method getTangent
|
|
615
|
-
* @param {number} u - The position on the curve in [0,arcLength].
|
|
616
|
-
* @instance
|
|
617
|
-
* @memberof CubicBezierCurve
|
|
618
|
-
* @return {Vertex}
|
|
619
|
-
**/
|
|
620
|
-
getTangent( u:number ) : Vertex {
|
|
621
|
-
return this.getTangentAt( this.convertU2T(u) );
|
|
622
|
-
};
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
/**
|
|
626
|
-
* Get the curve perpendicular at a given relative position u in [0,arcLength] as a vector.<br>
|
|
627
|
-
* <br>
|
|
628
|
-
* Note that the returned vector (end point) is not normalized.
|
|
629
|
-
*
|
|
630
|
-
* @method getPerpendicular
|
|
631
|
-
* @param {number} u - The relative position on the curve in [0,arcLength].
|
|
632
|
-
* @instance
|
|
633
|
-
* @memberof CubicBezierCurve
|
|
634
|
-
* @return {Vertex}
|
|
635
|
-
**/
|
|
636
|
-
getPerpendicular( u:number ) : Vertex {
|
|
637
|
-
return this.getPerpendicularAt( this.convertU2T(u) );
|
|
638
|
-
};
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
/**
|
|
642
|
-
* Get the curve perpendicular at a given absolute position t in [0,1] as a vector.<br>
|
|
643
|
-
* <br>
|
|
644
|
-
* Note that the returned vector (end point) is not normalized.
|
|
645
|
-
*
|
|
646
|
-
* @method getPerpendicularAt
|
|
647
|
-
* @param {number} u - The absolute position on the curve in [0,1].
|
|
648
|
-
* @instance
|
|
649
|
-
* @memberof CubicBezierCurve
|
|
650
|
-
* @return {Vertex}
|
|
651
|
-
**/
|
|
652
|
-
getPerpendicularAt( t:number ) : Vertex {
|
|
653
|
-
const tangentVector : Vertex = this.getTangentAt( t );
|
|
654
|
-
return new Vertex( tangentVector.y, - tangentVector.x );
|
|
655
|
-
};
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
/**
|
|
661
|
-
* Clone this Bézier curve (deep clone).
|
|
662
|
-
*
|
|
663
|
-
* @method clone
|
|
664
|
-
* @instance
|
|
665
|
-
* @memberof CubicBezierCurve
|
|
666
|
-
* @return {CubicBezierCurve}
|
|
667
|
-
**/
|
|
668
|
-
clone() : CubicBezierCurve {
|
|
669
|
-
return new CubicBezierCurve( this.getStartPoint().clone(),
|
|
670
|
-
this.getEndPoint().clone(),
|
|
671
|
-
this.getStartControlPoint().clone(),
|
|
672
|
-
this.getEndControlPoint().clone()
|
|
673
|
-
);
|
|
674
|
-
};
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
/**
|
|
678
|
-
* Check if this and the specified curve are equal.<br>
|
|
679
|
-
* <br>
|
|
680
|
-
* All four points need to be equal for this, the Vertex.equals function is used.<br>
|
|
681
|
-
* <br>
|
|
682
|
-
* Please note that this function is not type safe (comparison with any object will fail).
|
|
683
|
-
*
|
|
684
|
-
* @method clone
|
|
685
|
-
* @param {CubicBezierCurve} curve - The curve to compare with.
|
|
686
|
-
* @instance
|
|
687
|
-
* @memberof CubicBezierCurve
|
|
688
|
-
* @return {boolean}
|
|
689
|
-
**/
|
|
690
|
-
equals( curve:CubicBezierCurve|undefined ) : boolean {
|
|
691
|
-
// Note: in the earlier vanilla-JS version this was callable with plain objects.
|
|
692
|
-
// Let's see if this restricted version works out.
|
|
693
|
-
if( !curve )
|
|
694
|
-
return false;
|
|
695
|
-
if( !curve.startPoint ||
|
|
696
|
-
!curve.endPoint ||
|
|
697
|
-
!curve.startControlPoint ||
|
|
698
|
-
!curve.endControlPoint )
|
|
699
|
-
return false;
|
|
700
|
-
return this.startPoint.equals(curve.startPoint)
|
|
701
|
-
&& this.endPoint.equals(curve.endPoint)
|
|
702
|
-
&& this.startControlPoint.equals(curve.startControlPoint)
|
|
703
|
-
&& this.endControlPoint.equals(curve.endControlPoint);
|
|
46
|
+
/** @constant {number} */
|
|
47
|
+
static readonly START_POINT: number = 0;
|
|
48
|
+
/** @constant {number} */
|
|
49
|
+
static readonly START_CONTROL_POINT: number = 1;
|
|
50
|
+
/** @constant {number} */
|
|
51
|
+
static readonly END_CONTROL_POINT: number = 2;
|
|
52
|
+
/** @constant {number} */
|
|
53
|
+
static readonly END_POINT: number = 3;
|
|
54
|
+
|
|
55
|
+
/** @constant {number} */
|
|
56
|
+
readonly START_POINT: number = CubicBezierCurve.START_POINT;
|
|
57
|
+
/** @constant {number} */
|
|
58
|
+
readonly START_CONTROL_POINT: number = CubicBezierCurve.START_CONTROL_POINT;
|
|
59
|
+
/** @constant {number} */
|
|
60
|
+
readonly END_CONTROL_POINT: number = CubicBezierCurve.END_CONTROL_POINT;
|
|
61
|
+
/** @constant {number} */
|
|
62
|
+
readonly END_POINT: number = CubicBezierCurve.END_POINT;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The UID of this drawable object.
|
|
66
|
+
*
|
|
67
|
+
* @member {UID}
|
|
68
|
+
* @memberof CubicBezierCurve
|
|
69
|
+
* @instance
|
|
70
|
+
* @readonly
|
|
71
|
+
*/
|
|
72
|
+
readonly uid: UID;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @member {CubicBezierCurve}
|
|
76
|
+
* @memberof CubicBezierCurve
|
|
77
|
+
* @instance
|
|
78
|
+
*/
|
|
79
|
+
startPoint: Vertex;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @member {CubicBezierCurve}
|
|
83
|
+
* @memberof CubicBezierCurve
|
|
84
|
+
* @instance
|
|
85
|
+
*/
|
|
86
|
+
endPoint: Vertex;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @member {CubicBezierCurve}
|
|
90
|
+
* @memberof CubicBezierCurve
|
|
91
|
+
* @instance
|
|
92
|
+
*/
|
|
93
|
+
startControlPoint: Vertex;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @member {CubicBezierCurve}
|
|
97
|
+
* @memberof CubicBezierCurve
|
|
98
|
+
* @instance
|
|
99
|
+
*/
|
|
100
|
+
endControlPoint: Vertex;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @member {CubicBezierCurve}
|
|
104
|
+
* @memberof CubicBezierCurve
|
|
105
|
+
* @instance
|
|
106
|
+
*/
|
|
107
|
+
curveIntervals: number;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @member {CubicBezierCurve}
|
|
111
|
+
* @memberof CubicBezierCurve
|
|
112
|
+
* @instance
|
|
113
|
+
*/
|
|
114
|
+
segmentCache: Array<Vertex>;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @member {CubicBezierCurve}
|
|
118
|
+
* @memberof CubicBezierCurve
|
|
119
|
+
* @instance
|
|
120
|
+
*/
|
|
121
|
+
segmentLengths: Array<number>;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* @member {CubicBezierCurve}
|
|
125
|
+
* @memberof CubicBezierCurve
|
|
126
|
+
* @instance
|
|
127
|
+
*/
|
|
128
|
+
arcLength: number;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @member isDestroyed
|
|
132
|
+
* @memberof CubicBezierCurve
|
|
133
|
+
* @type {boolean}
|
|
134
|
+
* @instance
|
|
135
|
+
*/
|
|
136
|
+
isDestroyed: boolean;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* The constructor.
|
|
140
|
+
*
|
|
141
|
+
* @constructor
|
|
142
|
+
* @name CubicBezierCurve
|
|
143
|
+
* @param {Vertex} startPoint - The Bézier curve's start point.
|
|
144
|
+
* @param {Vertex} endPoint - The Bézier curve's end point.
|
|
145
|
+
* @param {Vertex} startControlPoint - The Bézier curve's start control point.
|
|
146
|
+
* @param {Vertex} endControlPoint - The Bézier curve's end control point.
|
|
147
|
+
**/
|
|
148
|
+
constructor(startPoint: Vertex, endPoint: Vertex, startControlPoint: Vertex, endControlPoint: Vertex) {
|
|
149
|
+
this.uid = UIDGenerator.next();
|
|
150
|
+
this.startPoint = startPoint;
|
|
151
|
+
this.startControlPoint = startControlPoint;
|
|
152
|
+
this.endPoint = endPoint;
|
|
153
|
+
this.endControlPoint = endControlPoint;
|
|
154
|
+
this.curveIntervals = 30;
|
|
155
|
+
// An array of vertices
|
|
156
|
+
this.segmentCache = [];
|
|
157
|
+
// An array of floats
|
|
158
|
+
this.segmentLengths = [];
|
|
159
|
+
// float
|
|
160
|
+
this.arcLength = null;
|
|
161
|
+
|
|
162
|
+
this.updateArcLengths();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Move the given curve point (the start point, end point or one of the two
|
|
167
|
+
* control points).
|
|
168
|
+
*
|
|
169
|
+
* @method moveCurvePoint
|
|
170
|
+
* @param {number} pointID - The numeric identicator of the point to move. Use one of the four eBezierPoint constants.
|
|
171
|
+
* @param {XYCoords} moveAmount - The amount to move the specified point by.
|
|
172
|
+
* @param {boolean} moveControlPoint - Move the control points along with their path point (if specified point is a path point).
|
|
173
|
+
* @param {boolean} updateArcLengths - Specifiy if the internal arc segment buffer should be updated.
|
|
174
|
+
* @instance
|
|
175
|
+
* @memberof CubicBezierCurve
|
|
176
|
+
* @return {void}
|
|
177
|
+
**/
|
|
178
|
+
moveCurvePoint(pointID: number, moveAmount: XYCoords, moveControlPoint: boolean, updateArcLengths: boolean): void {
|
|
179
|
+
if (pointID == this.START_POINT) {
|
|
180
|
+
this.getStartPoint().add(moveAmount);
|
|
181
|
+
if (moveControlPoint) this.getStartControlPoint().add(moveAmount);
|
|
182
|
+
} else if (pointID == this.START_CONTROL_POINT) {
|
|
183
|
+
this.getStartControlPoint().add(moveAmount);
|
|
184
|
+
} else if (pointID == this.END_CONTROL_POINT) {
|
|
185
|
+
this.getEndControlPoint().add(moveAmount);
|
|
186
|
+
} else if (pointID == this.END_POINT) {
|
|
187
|
+
this.getEndPoint().add(moveAmount);
|
|
188
|
+
if (moveControlPoint) this.getEndControlPoint().add(moveAmount);
|
|
189
|
+
} else {
|
|
190
|
+
console.log(`[CubicBezierCurve.moveCurvePoint] pointID '${pointID}' invalid.`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (updateArcLengths) this.updateArcLengths();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Translate the whole curve by the given {x,y} amount: moves all four points.
|
|
198
|
+
*
|
|
199
|
+
* @method translate
|
|
200
|
+
* @param {Vertex} amount - The amount to translate this curve by.
|
|
201
|
+
* @instance
|
|
202
|
+
* @memberof CubicBezierCurve
|
|
203
|
+
* @return {CubicBezierCurve} this (for chaining).
|
|
204
|
+
**/
|
|
205
|
+
translate(amount: Vertex): CubicBezierCurve {
|
|
206
|
+
this.startPoint.add(amount);
|
|
207
|
+
this.startControlPoint.add(amount);
|
|
208
|
+
this.endControlPoint.add(amount);
|
|
209
|
+
this.endPoint.add(amount);
|
|
210
|
+
return this;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Reverse this curve, means swapping start- and end-point and swapping
|
|
215
|
+
* start-control- and end-control-point.
|
|
216
|
+
*
|
|
217
|
+
* @method reverse
|
|
218
|
+
* @instance
|
|
219
|
+
* @memberof CubicBezierCurve
|
|
220
|
+
* @return {CubicBezierCurve} this (for chaining).
|
|
221
|
+
**/
|
|
222
|
+
reverse(): CubicBezierCurve {
|
|
223
|
+
let tmp: Vertex = this.startPoint;
|
|
224
|
+
this.startPoint = this.endPoint;
|
|
225
|
+
this.endPoint = tmp;
|
|
226
|
+
tmp = this.startControlPoint;
|
|
227
|
+
this.startControlPoint = this.endControlPoint;
|
|
228
|
+
this.endControlPoint = tmp;
|
|
229
|
+
return this;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Get the total curve length.<br>
|
|
234
|
+
* <br>
|
|
235
|
+
* As not all Bézier curved have a closed formula to calculate their lengths, this
|
|
236
|
+
* implementation uses a segment buffer (with a length of 30 segments). So the
|
|
237
|
+
* returned length is taken from the arc segment buffer.<br>
|
|
238
|
+
* <br>
|
|
239
|
+
* Note that if the curve points were changed and the segment buffer was not
|
|
240
|
+
* updated this function might return wrong (old) values.
|
|
241
|
+
*
|
|
242
|
+
* @method getLength
|
|
243
|
+
* @instance
|
|
244
|
+
* @memberof CubicBezierCurve
|
|
245
|
+
* @return {number} >= 0
|
|
246
|
+
**/
|
|
247
|
+
getLength(): number {
|
|
248
|
+
return this.arcLength;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Uptate the internal arc segment buffer and their lengths.<br>
|
|
253
|
+
* <br>
|
|
254
|
+
* All class functions update the buffer automatically; if any
|
|
255
|
+
* curve point is changed by other reasons you should call this
|
|
256
|
+
* function to keep actual values in the buffer.
|
|
257
|
+
*
|
|
258
|
+
* @method updateArcLengths
|
|
259
|
+
* @instance
|
|
260
|
+
* @memberof CubicBezierCurve
|
|
261
|
+
* @return {void}
|
|
262
|
+
**/
|
|
263
|
+
updateArcLengths(): void {
|
|
264
|
+
let pointA: Vertex = this.startPoint.clone();
|
|
265
|
+
let pointB: Vertex = new Vertex(0, 0);
|
|
266
|
+
let curveStep: number = 1.0 / this.curveIntervals;
|
|
267
|
+
|
|
268
|
+
// Clear segment cache
|
|
269
|
+
this.segmentCache = [];
|
|
270
|
+
// Push start point into buffer
|
|
271
|
+
this.segmentCache.push(this.startPoint);
|
|
272
|
+
this.segmentLengths = [];
|
|
273
|
+
let newLength: number = 0.0;
|
|
274
|
+
|
|
275
|
+
var t: number = 0.0;
|
|
276
|
+
let tmpLength: number;
|
|
277
|
+
while (t <= 1.0) {
|
|
278
|
+
pointB = this.getPointAt(t);
|
|
279
|
+
|
|
280
|
+
// Store point into cache
|
|
281
|
+
this.segmentCache.push(pointB);
|
|
282
|
+
|
|
283
|
+
// Calculate segment length
|
|
284
|
+
tmpLength = pointA.distance(pointB);
|
|
285
|
+
this.segmentLengths.push(tmpLength);
|
|
286
|
+
newLength += tmpLength;
|
|
287
|
+
|
|
288
|
+
pointA = pointB;
|
|
289
|
+
t += curveStep;
|
|
290
|
+
}
|
|
291
|
+
this.arcLength = newLength;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Get a 't' (relative position on curve) with the closest distance to point 'p'.
|
|
296
|
+
*
|
|
297
|
+
* The returned number is 0.0 <= t <= 1.0. Use the getPointAt(t) function to retrieve the actual curve point.
|
|
298
|
+
*
|
|
299
|
+
* This function uses a recursive approach by cutting the curve into several linear segments.
|
|
300
|
+
*
|
|
301
|
+
* @param {Vertex} p - The point to find the closest position ('t' on the curve).
|
|
302
|
+
* @return {number}
|
|
303
|
+
**/
|
|
304
|
+
getClosestT(p: Vertex): number {
|
|
305
|
+
// We would like to have an error that's not larger than 1.0.
|
|
306
|
+
var desiredEpsilon: number = 1.0;
|
|
307
|
+
|
|
308
|
+
var result: { t: number; tPrev: number; tNext: number } = { t: 0, tPrev: 0.0, tNext: 1.0 };
|
|
309
|
+
var iteration: number = 0;
|
|
310
|
+
do {
|
|
311
|
+
result = this.locateIntervalByDistance(p, result.tPrev, result.tNext, this.curveIntervals);
|
|
312
|
+
iteration++;
|
|
313
|
+
// Be sure: stop after 4 iterations
|
|
314
|
+
} while (iteration < 4 && this.getPointAt(result.tPrev).distance(this.getPointAt(result.tNext)) > desiredEpsilon);
|
|
315
|
+
return result.t;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* This helper function locates the 't' on a fixed step interval with the minimal distance
|
|
320
|
+
* between the curve (at 't') and the given point.
|
|
321
|
+
*
|
|
322
|
+
* Furthermore you must specify a sub curve (start 't' and end 't') you want to search on.
|
|
323
|
+
* Using tStart=0.0 and tEnd=1.0 will search on the full curve.
|
|
324
|
+
*
|
|
325
|
+
* @param {Vertex} p - The point to find the closest curve point for.
|
|
326
|
+
* @param {number} tStart - The start position (start 't' of the sub curve). Should be >= 0.0.
|
|
327
|
+
* @param {number} tEnd - The end position (end 't' of the sub curve). Should be <= 1.0.
|
|
328
|
+
* @param {number} stepCount - The number of steps to check within the interval.
|
|
329
|
+
*
|
|
330
|
+
* @return {object} - An object with t, tPrev and tNext (numbers).
|
|
331
|
+
**/
|
|
332
|
+
private locateIntervalByDistance(
|
|
333
|
+
p: Vertex,
|
|
334
|
+
tStart: number,
|
|
335
|
+
tEnd: number,
|
|
336
|
+
stepCount: number
|
|
337
|
+
): { t: number; tPrev: number; tNext: number } {
|
|
338
|
+
var minIndex: number = -1;
|
|
339
|
+
var minDist: number = 0;
|
|
340
|
+
var t: number = 0.0;
|
|
341
|
+
const tDiff: number = tEnd - tStart;
|
|
342
|
+
for (var i = 0; i <= stepCount; i++) {
|
|
343
|
+
t = tStart + tDiff * (i / stepCount);
|
|
344
|
+
var vert: Vertex = this.getPointAt(t);
|
|
345
|
+
var dist: number = vert.distance(p);
|
|
346
|
+
if (minIndex == -1 || dist < minDist) {
|
|
347
|
+
minIndex = i;
|
|
348
|
+
minDist = dist;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return {
|
|
352
|
+
t: tStart + tDiff * (minIndex / stepCount),
|
|
353
|
+
tPrev: tStart + tDiff * (Math.max(0, minIndex - 1) / stepCount),
|
|
354
|
+
tNext: tStart + tDiff * (Math.min(stepCount, minIndex + 1) / stepCount)
|
|
704
355
|
};
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Get the bounds of this bezier curve.
|
|
360
|
+
*
|
|
361
|
+
* The bounds are approximated by the underlying segment buffer; the more segment there are,
|
|
362
|
+
* the more accurate will be the returned bounds.
|
|
363
|
+
*
|
|
364
|
+
* @return {Bounds} The bounds of this curve.
|
|
365
|
+
**/
|
|
366
|
+
getBounds(): Bounds {
|
|
367
|
+
var min: Vertex = new Vertex(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY);
|
|
368
|
+
var max: Vertex = new Vertex(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY);
|
|
369
|
+
let v: Vertex;
|
|
370
|
+
for (var i = 0; i < this.segmentCache.length; i++) {
|
|
371
|
+
v = this.segmentCache[i];
|
|
372
|
+
min.x = Math.min(min.x, v.x);
|
|
373
|
+
min.y = Math.min(min.y, v.y);
|
|
374
|
+
max.x = Math.max(max.x, v.x);
|
|
375
|
+
max.y = Math.max(max.y, v.y);
|
|
376
|
+
}
|
|
377
|
+
return new Bounds(min, max);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Get the start point of the curve.<br>
|
|
382
|
+
* <br>
|
|
383
|
+
* This function just returns this.startPoint.
|
|
384
|
+
*
|
|
385
|
+
* @method getStartPoint
|
|
386
|
+
* @instance
|
|
387
|
+
* @memberof CubicBezierCurve
|
|
388
|
+
* @return {Vertex} this.startPoint
|
|
389
|
+
**/
|
|
390
|
+
getStartPoint(): Vertex {
|
|
391
|
+
return this.startPoint;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Get the end point of the curve.<br>
|
|
396
|
+
* <br>
|
|
397
|
+
* This function just returns this.endPoint.
|
|
398
|
+
*
|
|
399
|
+
* @method getEndPoint
|
|
400
|
+
* @instance
|
|
401
|
+
* @memberof CubicBezierCurve
|
|
402
|
+
* @return {Vertex} this.endPoint
|
|
403
|
+
**/
|
|
404
|
+
getEndPoint(): Vertex {
|
|
405
|
+
return this.endPoint;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Get the start control point of the curve.<br>
|
|
410
|
+
* <br>
|
|
411
|
+
* This function just returns this.startControlPoint.
|
|
412
|
+
*
|
|
413
|
+
* @method getStartControlPoint
|
|
414
|
+
* @instance
|
|
415
|
+
* @memberof CubicBezierCurve
|
|
416
|
+
* @return {Vertex} this.startControlPoint
|
|
417
|
+
**/
|
|
418
|
+
getStartControlPoint(): Vertex {
|
|
419
|
+
return this.startControlPoint;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Get the end control point of the curve.<br>
|
|
424
|
+
* <br>
|
|
425
|
+
* This function just returns this.endControlPoint.
|
|
426
|
+
*
|
|
427
|
+
* @method getEndControlPoint
|
|
428
|
+
* @instance
|
|
429
|
+
* @memberof CubicBezierCurve
|
|
430
|
+
* @return {Vertex} this.endControlPoint
|
|
431
|
+
**/
|
|
432
|
+
getEndControlPoint(): Vertex {
|
|
433
|
+
return this.endControlPoint;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Get one of the four curve points specified by the passt point ID.
|
|
438
|
+
*
|
|
439
|
+
* @method getEndControlPoint
|
|
440
|
+
* @param {number} id - One of START_POINT, START_CONTROL_POINT, END_CONTROL_POINT or END_POINT.
|
|
441
|
+
* @instance
|
|
442
|
+
* @memberof CubicBezierCurve
|
|
443
|
+
* @return {Vertex}
|
|
444
|
+
**/
|
|
445
|
+
getPointByID(id: number): Vertex {
|
|
446
|
+
if (id == this.START_POINT) return this.startPoint;
|
|
447
|
+
if (id == this.END_POINT) return this.endPoint;
|
|
448
|
+
if (id == this.START_CONTROL_POINT) return this.startControlPoint;
|
|
449
|
+
if (id == this.END_CONTROL_POINT) return this.endControlPoint;
|
|
450
|
+
throw new Error(`Invalid point ID '${id}'.`);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Get the curve point at a given position t, where t is in [0,1].<br>
|
|
455
|
+
* <br>
|
|
456
|
+
* @see Line.pointAt
|
|
457
|
+
*
|
|
458
|
+
* @method getPointAt
|
|
459
|
+
* @param {number} t - The position on the curve in [0,1] (0 means at
|
|
460
|
+
* start point, 1 means at end point, other values address points in bertween).
|
|
461
|
+
* @instance
|
|
462
|
+
* @memberof CubicBezierCurve
|
|
463
|
+
* @return {Vertex}
|
|
464
|
+
**/
|
|
465
|
+
getPointAt(t: number): Vertex {
|
|
466
|
+
// Perform some powerful math magic
|
|
467
|
+
const x: number =
|
|
468
|
+
this.startPoint.x * Math.pow(1.0 - t, 3) +
|
|
469
|
+
this.startControlPoint.x * 3 * t * Math.pow(1.0 - t, 2) +
|
|
470
|
+
this.endControlPoint.x * 3 * Math.pow(t, 2) * (1.0 - t) +
|
|
471
|
+
this.endPoint.x * Math.pow(t, 3);
|
|
472
|
+
const y: number =
|
|
473
|
+
this.startPoint.y * Math.pow(1.0 - t, 3) +
|
|
474
|
+
this.startControlPoint.y * 3 * t * Math.pow(1.0 - t, 2) +
|
|
475
|
+
this.endControlPoint.y * 3 * Math.pow(t, 2) * (1.0 - t) +
|
|
476
|
+
this.endPoint.y * Math.pow(t, 3);
|
|
477
|
+
return new Vertex(x, y);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Get the curve point at a given position u, where u is in [0,arcLength].<br>
|
|
482
|
+
* <br>
|
|
483
|
+
* @see CubicBezierCurve.getPointAt
|
|
484
|
+
*
|
|
485
|
+
* @method getPoint
|
|
486
|
+
* @param {number} u - The position on the curve in [0,arcLength] (0 means at
|
|
487
|
+
* start point, arcLength means at end point, other values address points in bertween).
|
|
488
|
+
* @instance
|
|
489
|
+
* @memberof CubicBezierCurve
|
|
490
|
+
* @return {Vertex}
|
|
491
|
+
**/
|
|
492
|
+
getPoint(u: number): Vertex {
|
|
493
|
+
return this.getPointAt(u / this.arcLength);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Get the curve tangent vector at a given absolute curve position t in [0,1].<br>
|
|
498
|
+
* <br>
|
|
499
|
+
* Note that the returned tangent vector (end point) is not normalized and relative to (0,0).
|
|
500
|
+
*
|
|
501
|
+
* @method getTangent
|
|
502
|
+
* @param {number} t - The position on the curve in [0,1].
|
|
503
|
+
* @instance
|
|
504
|
+
* @memberof CubicBezierCurve
|
|
505
|
+
* @return {Vertex}
|
|
506
|
+
**/
|
|
507
|
+
getTangentAt(t: number): Vertex {
|
|
508
|
+
const a: Vertex = this.getStartPoint();
|
|
509
|
+
const b: Vertex = this.getStartControlPoint();
|
|
510
|
+
const c: Vertex = this.getEndControlPoint();
|
|
511
|
+
const d: Vertex = this.getEndPoint();
|
|
512
|
+
|
|
513
|
+
// This is the shortened one
|
|
514
|
+
const t2: number = t * t;
|
|
515
|
+
// (1 - t)^2 = (1-t)*(1-t) = 1 - t - t + t^2 = 1 - 2*t + t^2
|
|
516
|
+
const nt2: number = 1 - 2 * t + t2;
|
|
517
|
+
|
|
518
|
+
const tX: number = -3 * a.x * nt2 + b.x * (3 * nt2 - 6 * (t - t2)) + c.x * (6 * (t - t2) - 3 * t2) + 3 * d.x * t2;
|
|
519
|
+
const tY: number = -3 * a.y * nt2 + b.y * (3 * nt2 - 6 * (t - t2)) + c.y * (6 * (t - t2) - 3 * t2) + 3 * d.y * t2;
|
|
520
|
+
|
|
521
|
+
// Note: my implementation does NOT normalize tangent vectors!
|
|
522
|
+
return new Vertex(tX, tY);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Get a sub curve at the given start end end offsets (values between 0.0 and 1.0).
|
|
527
|
+
*
|
|
528
|
+
* tStart >= tEnd is allowed, you will get a reversed sub curve then.
|
|
529
|
+
*
|
|
530
|
+
* @method getSubCurveAt
|
|
531
|
+
* @param {number} tStart – The start offset of the desired sub curve (must be in [0..1]).
|
|
532
|
+
* @param {number} tEnd – The end offset if the desired cub curve (must be in [0..1]).
|
|
533
|
+
* @instance
|
|
534
|
+
* @memberof CubicBezierCurve
|
|
535
|
+
* @return {CubicBezierCurve} The sub curve as a new curve.
|
|
536
|
+
**/
|
|
537
|
+
getSubCurveAt(tStart: number, tEnd: number): CubicBezierCurve {
|
|
538
|
+
const startVec: Vector = new Vector(this.getPointAt(tStart), this.getTangentAt(tStart));
|
|
539
|
+
const endVec: Vector = new Vector(this.getPointAt(tEnd), this.getTangentAt(tEnd).inv());
|
|
540
|
+
|
|
541
|
+
// Tangents are relative. Make absolute.
|
|
542
|
+
startVec.b.add(startVec.a);
|
|
543
|
+
endVec.b.add(endVec.a);
|
|
544
|
+
|
|
545
|
+
// This 'splits' the curve at the given point at t.
|
|
546
|
+
startVec.scale(0.33333333 * (tEnd - tStart));
|
|
547
|
+
endVec.scale(0.33333333 * (tEnd - tStart));
|
|
548
|
+
|
|
549
|
+
// Draw the bezier curve
|
|
550
|
+
// pb.draw.cubicBezier( startVec.a, endVec.a, startVec.b, endVec.b, '#8800ff', 2 );
|
|
551
|
+
return new CubicBezierCurve(startVec.a, endVec.a, startVec.b, endVec.b);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Convert a relative curve position u to the absolute curve position t.
|
|
556
|
+
*
|
|
557
|
+
* @method convertU2t
|
|
558
|
+
* @param {number} u - The relative position on the curve in [0,arcLength].
|
|
559
|
+
* @instance
|
|
560
|
+
* @memberof CubicBezierCurve
|
|
561
|
+
* @return {number}
|
|
562
|
+
**/
|
|
563
|
+
convertU2T(u: number): number {
|
|
564
|
+
return Math.max(0.0, Math.min(1.0, u / this.arcLength));
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Get the curve tangent vector at a given relative position u in [0,arcLength].<br>
|
|
569
|
+
* <br>
|
|
570
|
+
* Note that the returned tangent vector (end point) is not normalized.
|
|
571
|
+
*
|
|
572
|
+
* @method getTangent
|
|
573
|
+
* @param {number} u - The position on the curve in [0,arcLength].
|
|
574
|
+
* @instance
|
|
575
|
+
* @memberof CubicBezierCurve
|
|
576
|
+
* @return {Vertex}
|
|
577
|
+
**/
|
|
578
|
+
getTangent(u: number): Vertex {
|
|
579
|
+
return this.getTangentAt(this.convertU2T(u));
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* Get the curve perpendicular at a given relative position u in [0,arcLength] as a vector.<br>
|
|
584
|
+
* <br>
|
|
585
|
+
* Note that the returned vector (end point) is not normalized.
|
|
586
|
+
*
|
|
587
|
+
* @method getPerpendicular
|
|
588
|
+
* @param {number} u - The relative position on the curve in [0,arcLength].
|
|
589
|
+
* @instance
|
|
590
|
+
* @memberof CubicBezierCurve
|
|
591
|
+
* @return {Vertex}
|
|
592
|
+
**/
|
|
593
|
+
getPerpendicular(u: number): Vertex {
|
|
594
|
+
return this.getPerpendicularAt(this.convertU2T(u));
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Get the curve perpendicular at a given absolute position t in [0,1] as a vector.<br>
|
|
599
|
+
* <br>
|
|
600
|
+
* Note that the returned vector (end point) is not normalized.
|
|
601
|
+
*
|
|
602
|
+
* @method getPerpendicularAt
|
|
603
|
+
* @param {number} u - The absolute position on the curve in [0,1].
|
|
604
|
+
* @instance
|
|
605
|
+
* @memberof CubicBezierCurve
|
|
606
|
+
* @return {Vertex}
|
|
607
|
+
**/
|
|
608
|
+
getPerpendicularAt(t: number): Vertex {
|
|
609
|
+
const tangentVector: Vertex = this.getTangentAt(t);
|
|
610
|
+
return new Vertex(tangentVector.y, -tangentVector.x);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* Clone this Bézier curve (deep clone).
|
|
615
|
+
*
|
|
616
|
+
* @method clone
|
|
617
|
+
* @instance
|
|
618
|
+
* @memberof CubicBezierCurve
|
|
619
|
+
* @return {CubicBezierCurve}
|
|
620
|
+
**/
|
|
621
|
+
clone(): CubicBezierCurve {
|
|
622
|
+
return new CubicBezierCurve(
|
|
623
|
+
this.getStartPoint().clone(),
|
|
624
|
+
this.getEndPoint().clone(),
|
|
625
|
+
this.getStartControlPoint().clone(),
|
|
626
|
+
this.getEndControlPoint().clone()
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Check if this and the specified curve are equal.<br>
|
|
632
|
+
* <br>
|
|
633
|
+
* All four points need to be equal for this, the Vertex.equals function is used.<br>
|
|
634
|
+
* <br>
|
|
635
|
+
* Please note that this function is not type safe (comparison with any object will fail).
|
|
636
|
+
*
|
|
637
|
+
* @method clone
|
|
638
|
+
* @param {CubicBezierCurve} curve - The curve to compare with.
|
|
639
|
+
* @instance
|
|
640
|
+
* @memberof CubicBezierCurve
|
|
641
|
+
* @return {boolean}
|
|
642
|
+
**/
|
|
643
|
+
equals(curve: CubicBezierCurve | undefined): boolean {
|
|
644
|
+
// Note: in the earlier vanilla-JS version this was callable with plain objects.
|
|
645
|
+
// Let's see if this restricted version works out.
|
|
646
|
+
if (!curve) return false;
|
|
647
|
+
if (!curve.startPoint || !curve.endPoint || !curve.startControlPoint || !curve.endControlPoint) return false;
|
|
648
|
+
return (
|
|
649
|
+
this.startPoint.equals(curve.startPoint) &&
|
|
650
|
+
this.endPoint.equals(curve.endPoint) &&
|
|
651
|
+
this.startControlPoint.equals(curve.startControlPoint) &&
|
|
652
|
+
this.endControlPoint.equals(curve.endControlPoint)
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* This function should invalidate any installed listeners and invalidate this object.
|
|
658
|
+
* After calling this function the object might not hold valid data any more and
|
|
659
|
+
* should not be used.
|
|
660
|
+
*/
|
|
661
|
+
destroy() {
|
|
662
|
+
this.startPoint.destroy();
|
|
663
|
+
this.endPoint.destroy();
|
|
664
|
+
this.startControlPoint.destroy();
|
|
665
|
+
this.endControlPoint.destroy();
|
|
666
|
+
this.isDestroyed = true;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* Quick check for class instance.
|
|
671
|
+
* Is there a better way?
|
|
672
|
+
*
|
|
673
|
+
* @method isInstance
|
|
674
|
+
* @param {any} obj - Check if the passed object/value is an instance of CubicBezierCurve.
|
|
675
|
+
* @instance
|
|
676
|
+
* @memberof CubicBezierCurve
|
|
677
|
+
* @return {boolean}
|
|
678
|
+
**/
|
|
679
|
+
static isInstance(obj: any): boolean {
|
|
680
|
+
// Note: check this again
|
|
681
|
+
/* OLD VANILLA JS IMPLEMENTATION */
|
|
682
|
+
/* if( typeof obj != "object" )
|
|
721
683
|
return false;
|
|
722
684
|
function hasXY(v) {
|
|
723
685
|
return typeof v != "undefined" && typeof v.x == "number" && typeof v.y == "number";
|
|
@@ -727,137 +689,103 @@ export class CubicBezierCurve {
|
|
|
727
689
|
&& typeof obj.startControlPoint == "object" && hasXY(obj.startControlPoint)
|
|
728
690
|
&& typeof obj.endControlPoint == "object" && hasXY(obj.endControlPoint);
|
|
729
691
|
*/
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
if( !obj.startControlPoint )
|
|
830
|
-
throw "Object member \"startControlPoint\" missing.";
|
|
831
|
-
if( !obj.endControlPoint )
|
|
832
|
-
throw "Object member \"endControlPoint\" missing.";
|
|
833
|
-
|
|
834
|
-
return new CubicBezierCurve( new Vertex(obj.startPoint[0], obj.startPoint[1]),
|
|
835
|
-
new Vertex(obj.endPoint[0], obj.endPoint[1]),
|
|
836
|
-
new Vertex(obj.startControlPoint[0], obj.startControlPoint[1]),
|
|
837
|
-
new Vertex(obj.endControlPoint[0], obj.endControlPoint[1])
|
|
838
|
-
);
|
|
839
|
-
};
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
/**
|
|
844
|
-
* Convert a 4-element array of vertices to a cubic bézier curve.
|
|
845
|
-
*
|
|
846
|
-
* @method fromArray
|
|
847
|
-
* @param {Vertex[]} arr - [ startVertex, endVertex, startControlVertex, endControlVertex ]
|
|
848
|
-
* @memberof CubicBezierCurve
|
|
849
|
-
* @throws An exception if the passed array is malformed.
|
|
850
|
-
* @return {CubicBezierCurve}
|
|
851
|
-
**/
|
|
852
|
-
static fromArray( arr:Array<Vertex> ) {
|
|
853
|
-
if( !Array.isArray(arr) )
|
|
854
|
-
throw "Can only build from object.";
|
|
855
|
-
if( arr.length != 4 )
|
|
856
|
-
throw "Can only build from array with four elements.";
|
|
857
|
-
return new CubicBezierCurve( arr[0],
|
|
858
|
-
arr[1],
|
|
859
|
-
arr[2],
|
|
860
|
-
arr[3]
|
|
861
|
-
);
|
|
862
|
-
};
|
|
692
|
+
return obj instanceof CubicBezierCurve;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Convert this curve to a JSON string.
|
|
697
|
+
*
|
|
698
|
+
* @method toJSON
|
|
699
|
+
* @param {boolean=} [prettyFormat=false] - If set to true the function will add line breaks.
|
|
700
|
+
* @instance
|
|
701
|
+
* @memberof CubicBezierCurve
|
|
702
|
+
* @return {string} The JSON data.
|
|
703
|
+
**/
|
|
704
|
+
toJSON(prettyFormat: boolean): string {
|
|
705
|
+
var jsonString =
|
|
706
|
+
"{ " + // begin object
|
|
707
|
+
(prettyFormat ? "\n\t" : "") +
|
|
708
|
+
'"startPoint" : [' +
|
|
709
|
+
this.getStartPoint().x +
|
|
710
|
+
"," +
|
|
711
|
+
this.getStartPoint().y +
|
|
712
|
+
"], " +
|
|
713
|
+
(prettyFormat ? "\n\t" : "") +
|
|
714
|
+
'"endPoint" : [' +
|
|
715
|
+
this.getEndPoint().x +
|
|
716
|
+
"," +
|
|
717
|
+
this.getEndPoint().y +
|
|
718
|
+
"], " +
|
|
719
|
+
(prettyFormat ? "\n\t" : "") +
|
|
720
|
+
'"startControlPoint": [' +
|
|
721
|
+
this.getStartControlPoint().x +
|
|
722
|
+
"," +
|
|
723
|
+
this.getStartControlPoint().y +
|
|
724
|
+
"], " +
|
|
725
|
+
(prettyFormat ? "\n\t" : "") +
|
|
726
|
+
'"endControlPoint" : [' +
|
|
727
|
+
this.getEndControlPoint().x +
|
|
728
|
+
"," +
|
|
729
|
+
this.getEndControlPoint().y +
|
|
730
|
+
"]" +
|
|
731
|
+
(prettyFormat ? "\n\t" : "") +
|
|
732
|
+
" }"; // end object
|
|
733
|
+
return jsonString;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* Parse a Bézier curve from the given JSON string.
|
|
738
|
+
*
|
|
739
|
+
* @method fromJSON
|
|
740
|
+
* @param {string} jsonString - The JSON data to parse.
|
|
741
|
+
* @memberof CubicBezierCurve
|
|
742
|
+
* @static
|
|
743
|
+
* @throws An exception if the JSON string is malformed.
|
|
744
|
+
* @return {CubicBezierCurve}
|
|
745
|
+
**/
|
|
746
|
+
static fromJSON(jsonString: string): CubicBezierCurve {
|
|
747
|
+
var obj: object = JSON.parse(jsonString);
|
|
748
|
+
return CubicBezierCurve.fromObject(obj);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* Try to convert the passed object to a CubicBezierCurve.
|
|
753
|
+
*
|
|
754
|
+
* @method fromObject
|
|
755
|
+
* @param {object} obj - The object to convert.
|
|
756
|
+
* @memberof CubicBezierCurve
|
|
757
|
+
* @static
|
|
758
|
+
* @throws An exception if the passed object is malformed.
|
|
759
|
+
* @return {CubicBezierCurve}
|
|
760
|
+
**/
|
|
761
|
+
static fromObject(obj: any): CubicBezierCurve {
|
|
762
|
+
if (typeof obj !== "object") throw "Can only build from object.";
|
|
763
|
+
|
|
764
|
+
if (!obj.startPoint) throw 'Object member "startPoint" missing.';
|
|
765
|
+
if (!obj.endPoint) throw 'Object member "endPoint" missing.';
|
|
766
|
+
if (!obj.startControlPoint) throw 'Object member "startControlPoint" missing.';
|
|
767
|
+
if (!obj.endControlPoint) throw 'Object member "endControlPoint" missing.';
|
|
768
|
+
|
|
769
|
+
return new CubicBezierCurve(
|
|
770
|
+
new Vertex(obj.startPoint[0], obj.startPoint[1]),
|
|
771
|
+
new Vertex(obj.endPoint[0], obj.endPoint[1]),
|
|
772
|
+
new Vertex(obj.startControlPoint[0], obj.startControlPoint[1]),
|
|
773
|
+
new Vertex(obj.endControlPoint[0], obj.endControlPoint[1])
|
|
774
|
+
);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
/**
|
|
778
|
+
* Convert a 4-element array of vertices to a cubic bézier curve.
|
|
779
|
+
*
|
|
780
|
+
* @method fromArray
|
|
781
|
+
* @param {Vertex[]} arr - [ startVertex, endVertex, startControlVertex, endControlVertex ]
|
|
782
|
+
* @memberof CubicBezierCurve
|
|
783
|
+
* @throws An exception if the passed array is malformed.
|
|
784
|
+
* @return {CubicBezierCurve}
|
|
785
|
+
**/
|
|
786
|
+
static fromArray(arr: Array<Vertex>) {
|
|
787
|
+
if (!Array.isArray(arr)) throw "Can only build from object.";
|
|
788
|
+
if (arr.length != 4) throw "Can only build from array with four elements.";
|
|
789
|
+
return new CubicBezierCurve(arr[0], arr[1], arr[2], arr[3]);
|
|
790
|
+
}
|
|
863
791
|
}
|