toosoon-utils 4.1.9 → 4.2.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.
Files changed (65) hide show
  1. package/README.md +97 -885
  2. package/lib/constants.d.ts +0 -1
  3. package/lib/constants.js +3 -1
  4. package/lib/extras/color-scale/ColorScale.d.ts +2 -2
  5. package/lib/extras/color-scale/ColorScale.js +2 -2
  6. package/lib/extras/curves/ArcCurve.d.ts +3 -3
  7. package/lib/extras/curves/ArcCurve.js +5 -4
  8. package/lib/extras/curves/CatmullRomCurve.d.ts +20 -5
  9. package/lib/extras/curves/CatmullRomCurve.js +23 -5
  10. package/lib/extras/curves/CatmullRomCurve3.d.ts +101 -0
  11. package/lib/extras/curves/CatmullRomCurve3.js +122 -0
  12. package/lib/extras/curves/CubicBezierCurve.d.ts +20 -5
  13. package/lib/extras/curves/CubicBezierCurve.js +23 -5
  14. package/lib/extras/curves/CubicBezierCurve3.d.ts +101 -0
  15. package/lib/extras/curves/CubicBezierCurve3.js +122 -0
  16. package/lib/extras/curves/Curve.d.ts +23 -24
  17. package/lib/extras/curves/Curve.js +19 -26
  18. package/lib/extras/curves/EllipseCurve.d.ts +25 -9
  19. package/lib/extras/curves/EllipseCurve.js +64 -15
  20. package/lib/extras/curves/LineCurve.d.ts +34 -10
  21. package/lib/extras/curves/LineCurve.js +35 -13
  22. package/lib/extras/curves/LineCurve3.d.ts +87 -0
  23. package/lib/extras/curves/LineCurve3.js +108 -0
  24. package/lib/extras/curves/PolylineCurve.d.ts +9 -8
  25. package/lib/extras/curves/PolylineCurve.js +6 -6
  26. package/lib/extras/curves/PolylineCurve3.d.ts +28 -0
  27. package/lib/extras/curves/PolylineCurve3.js +39 -0
  28. package/lib/extras/curves/QuadraticBezierCurve.d.ts +19 -5
  29. package/lib/extras/curves/QuadraticBezierCurve.js +22 -5
  30. package/lib/extras/curves/QuadraticBezierCurve3.d.ts +84 -0
  31. package/lib/extras/curves/QuadraticBezierCurve3.js +102 -0
  32. package/lib/extras/curves/SplineCurve.d.ts +12 -8
  33. package/lib/extras/curves/SplineCurve.js +9 -6
  34. package/lib/extras/curves/SplineCurve3.d.ts +28 -0
  35. package/lib/extras/curves/SplineCurve3.js +41 -0
  36. package/lib/extras/curves/index.d.ts +6 -0
  37. package/lib/extras/curves/index.js +6 -0
  38. package/lib/extras/geometry/Matrix2.d.ts +1 -0
  39. package/lib/extras/geometry/Matrix2.js +230 -0
  40. package/lib/extras/geometry/Matrix4.d.ts +1 -0
  41. package/lib/extras/geometry/Matrix4.js +632 -0
  42. package/lib/extras/geometry/Vector.d.ts +42 -0
  43. package/lib/extras/geometry/Vector.js +1 -0
  44. package/lib/extras/geometry/Vector2.d.ts +480 -0
  45. package/lib/extras/geometry/Vector2.js +709 -0
  46. package/lib/extras/geometry/Vector3.d.ts +486 -0
  47. package/lib/extras/geometry/Vector3.js +765 -0
  48. package/lib/extras/geometry/index.d.ts +3 -0
  49. package/lib/extras/geometry/index.js +2 -0
  50. package/lib/extras/paths/Path.d.ts +24 -18
  51. package/lib/extras/paths/Path.js +48 -35
  52. package/lib/extras/paths/PathContext.d.ts +97 -67
  53. package/lib/extras/paths/PathContext.js +326 -183
  54. package/lib/extras/paths/PathSVG.d.ts +43 -31
  55. package/lib/extras/paths/PathSVG.js +69 -56
  56. package/lib/extras/paths/index.d.ts +1 -1
  57. package/lib/geometry.d.ts +0 -135
  58. package/lib/geometry.js +1 -219
  59. package/lib/maths.d.ts +54 -22
  60. package/lib/maths.js +77 -27
  61. package/lib/random.d.ts +12 -16
  62. package/lib/random.js +19 -27
  63. package/lib/tsconfig.tsbuildinfo +1 -1
  64. package/lib/types.d.ts +43 -1
  65. package/package.json +2 -1
@@ -0,0 +1,765 @@
1
+ import { EPSILON, PI } from '../../constants';
2
+ import { clamp, lerp } from '../../maths';
3
+ /**
4
+ * Utility class for manipulating a 3D vectors
5
+ *
6
+ * @exports
7
+ * @class Vector3
8
+ * @implements Vector
9
+ */
10
+ export default class Vector3 {
11
+ isVector3 = true;
12
+ type = 'Vector3';
13
+ /**
14
+ * X-axis value of this vector
15
+ */
16
+ x;
17
+ /**
18
+ * Y-axis value of this vector
19
+ */
20
+ y;
21
+ /**
22
+ * Z-axis value of this vector
23
+ */
24
+ z;
25
+ /**
26
+ * @param {number} [x=0] X-axis value
27
+ * @param {number} [y=0] Y-axis value
28
+ * @param {number} [z=0] Z-axis value
29
+ */
30
+ constructor(x = 0, y = 0, z = 0) {
31
+ this.x = x;
32
+ this.y = y;
33
+ this.z = z;
34
+ }
35
+ /**
36
+ * Set this vector values
37
+ *
38
+ * @param {number} x X-axis value
39
+ * @param {number} y Y-axis value
40
+ * @param {number} z Z-axis value
41
+ * @returns {this}
42
+ */
43
+ set(x, y, z) {
44
+ this.x = x;
45
+ this.y = y;
46
+ this.z = z;
47
+ return this;
48
+ }
49
+ /**
50
+ * Set a given scalar value to all values of this vector
51
+ *
52
+ * @param {number} scalar Value to set for all vector values
53
+ * @returns {this}
54
+ */
55
+ setScalar(scalar) {
56
+ this.x = scalar;
57
+ this.y = scalar;
58
+ this.z = scalar;
59
+ return this;
60
+ }
61
+ /**
62
+ * Set this vector X-axis value
63
+ *
64
+ * @param {number} x X-axis value to set
65
+ * @returns {this}
66
+ */
67
+ setX(x) {
68
+ this.x = x;
69
+ return this;
70
+ }
71
+ /**
72
+ * Set this vector Y-axis value
73
+ *
74
+ * @param {number} y Y-axis value to set
75
+ * @returns {this}
76
+ */
77
+ setY(y) {
78
+ this.y = y;
79
+ return this;
80
+ }
81
+ /**
82
+ * Set this vector Z-axis value
83
+ *
84
+ * @param {number} z Z-axis value to set
85
+ * @returns {this}
86
+ */
87
+ setZ(z) {
88
+ this.z = z;
89
+ return this;
90
+ }
91
+ /**
92
+ * Set a given value of this vector
93
+ *
94
+ * @param {string|number} index `0` equals to `x`, `1` equals to `y`, `2` equals to `z`
95
+ * @param {number} value Value to set
96
+ * @returns {this}
97
+ */
98
+ setValue(index, value) {
99
+ switch (index) {
100
+ case 'x':
101
+ case 0:
102
+ this.x = value;
103
+ break;
104
+ case 'y':
105
+ case 1:
106
+ this.y = value;
107
+ break;
108
+ case 'z':
109
+ case 2:
110
+ this.z = value;
111
+ break;
112
+ }
113
+ return this;
114
+ }
115
+ /**
116
+ * Return a value from the vector
117
+ *
118
+ * @param {string|number} index `0` equals to `x`, `1` equals to `y`, `2` equals to `z`
119
+ * @returns {number}
120
+ */
121
+ getValue(index) {
122
+ switch (index) {
123
+ case 'x':
124
+ case 0:
125
+ return this.x;
126
+ case 'y':
127
+ case 1:
128
+ return this.y;
129
+ case 'z':
130
+ case 2:
131
+ return this.z;
132
+ default:
133
+ return NaN;
134
+ }
135
+ }
136
+ /**
137
+ * Add a given vector to this vector
138
+ *
139
+ * @param {Vector3|Point3} vector Vector to add
140
+ * @returns {this}
141
+ */
142
+ add([x, y, z]) {
143
+ this.x += x;
144
+ this.y += y;
145
+ this.z += z;
146
+ return this;
147
+ }
148
+ /**
149
+ * Add a given scalar value to all values of this vector
150
+ *
151
+ * @param {number} scalar Scalar value to add
152
+ * @returns {this}
153
+ */
154
+ addScalar(scalar) {
155
+ this.x += scalar;
156
+ this.y += scalar;
157
+ this.z += scalar;
158
+ return this;
159
+ }
160
+ /**
161
+ * Subtract a given vector to this vector
162
+ *
163
+ * @param {Vector3|Point3} vector Vector to subtract
164
+ * @returns {this}
165
+ */
166
+ sub([x, y, z]) {
167
+ this.x -= x;
168
+ this.y -= y;
169
+ this.z -= z;
170
+ return this;
171
+ }
172
+ /**
173
+ * Subtract a given scalar value to all values of this vector
174
+ *
175
+ * @param {number} scalar Scalar value to subtract
176
+ * @returns {this}
177
+ */
178
+ subScalar(scalar) {
179
+ this.x -= scalar;
180
+ this.y -= scalar;
181
+ this.z -= scalar;
182
+ return this;
183
+ }
184
+ /**
185
+ * Multiply a given vector to this vector
186
+ *
187
+ * @param {Vector3|Point3} vector Vector to multiply
188
+ * @returns {this}
189
+ */
190
+ multiply([x, y, z]) {
191
+ this.x *= x;
192
+ this.y *= y;
193
+ this.z *= z;
194
+ return this;
195
+ }
196
+ /**
197
+ * Multiply a given scalar value to all values of this vector
198
+ *
199
+ * @param {number} scalar Scalar value to multiply
200
+ * @returns {this}
201
+ */
202
+ multiplyScalar(scalar) {
203
+ this.x *= scalar;
204
+ this.y *= scalar;
205
+ this.z *= scalar;
206
+ return this;
207
+ }
208
+ /**
209
+ * Divide a given vector to this vector
210
+ *
211
+ * @param {Vector3|Point3} vector Vector to divide
212
+ * @returns {this}
213
+ */
214
+ divide([x, y, z]) {
215
+ this.x /= x;
216
+ this.y /= y;
217
+ this.z /= z;
218
+ return this;
219
+ }
220
+ /**
221
+ * Divide a given scalar value to all values of this vector
222
+ *
223
+ * @param {number} scalar Scalar value to multiply
224
+ * @returns {this}
225
+ */
226
+ divideScalar(scalar) {
227
+ this.x /= scalar;
228
+ this.y /= scalar;
229
+ this.z /= scalar;
230
+ return this;
231
+ }
232
+ /**
233
+ * Set this vector values to the min values compared to a given vector
234
+ *
235
+ * @param {Vector3|Point3} vector Vector to compare values with
236
+ * @returns {this}
237
+ */
238
+ min([x, y, z]) {
239
+ this.x = Math.min(this.x, x);
240
+ this.y = Math.min(this.y, y);
241
+ this.z = Math.min(this.z, z);
242
+ return this;
243
+ }
244
+ /**
245
+ * Set this vector values to the max values compared to a given vector
246
+ *
247
+ * @param {Vector3|Point3} vector Vector to compare values with
248
+ * @returns {this}
249
+ */
250
+ max([x, y, z]) {
251
+ this.x = Math.max(this.x, x);
252
+ this.y = Math.max(this.y, y);
253
+ this.z = Math.max(this.z, z);
254
+ return this;
255
+ }
256
+ /**
257
+ * Clamp this vector values to given boundaries
258
+ *
259
+ * @param {Vector3|Point3} min Minimum boundaries
260
+ * @param {Vector3|Point3} max Maximum boundaries
261
+ * @returns {this}
262
+ */
263
+ clamp([minX, minY, minZ], [maxX, maxY, maxZ]) {
264
+ this.x = clamp(this.x, minX, maxX);
265
+ this.y = clamp(this.y, minY, maxY);
266
+ this.z = clamp(this.z, minZ, maxZ);
267
+ return this;
268
+ }
269
+ /**
270
+ * Clamp this vector values to given scalar values
271
+ *
272
+ * @param {Vector3|Point3} min Minimum scalar boundary
273
+ * @param {Vector3|Point3} max Maximum scalar boundary
274
+ * @returns {this}
275
+ */
276
+ clampScalar(min, max) {
277
+ this.x = clamp(this.x, min, max);
278
+ this.y = clamp(this.y, min, max);
279
+ this.z = clamp(this.z, min, max);
280
+ return this;
281
+ }
282
+ // public clampLength(min: number, max: number) {
283
+ // const length = this.length();
284
+ // return this.divideScalar(length || 1).multiplyScalar(clamp(length, min, max));
285
+ // }
286
+ /**
287
+ * Round down to the nearest integer value this vector values
288
+ *
289
+ * @returns {this}
290
+ */
291
+ floor() {
292
+ this.x = Math.floor(this.x);
293
+ this.y = Math.floor(this.y);
294
+ this.z = Math.floor(this.z);
295
+ return this;
296
+ }
297
+ /**
298
+ * Round up to the nearest integer value this vector values
299
+ *
300
+ * @returns {this}
301
+ */
302
+ ceil() {
303
+ this.x = Math.ceil(this.x);
304
+ this.y = Math.ceil(this.y);
305
+ this.z = Math.ceil(this.z);
306
+ return this;
307
+ }
308
+ /**
309
+ * Round to the nearest integer value this vector values
310
+ *
311
+ * @returns {this}
312
+ */
313
+ round() {
314
+ this.x = Math.round(this.x);
315
+ this.y = Math.round(this.y);
316
+ this.z = Math.round(this.z);
317
+ return this;
318
+ }
319
+ /**
320
+ * Remove any fractional digits of this vector values
321
+ *
322
+ * @returns {this}
323
+ */
324
+ trunc() {
325
+ this.x = Math.trunc(this.x);
326
+ this.y = Math.trunc(this.y);
327
+ this.z = Math.trunc(this.z);
328
+ return this;
329
+ }
330
+ /**
331
+ * Set this vector values to their negative values
332
+ *
333
+ * @returns {this}
334
+ */
335
+ negate() {
336
+ this.x = -this.x;
337
+ this.y = -this.y;
338
+ this.z = -this.z;
339
+ return this;
340
+ }
341
+ /**
342
+ * Interpolate this vector values between a given vector and this vector
343
+ *
344
+ * @param {Vector3|Point3} vector Vector to interpolate values towards
345
+ * @param {number} t Normalized time value to interpolate
346
+ * @returns {this}
347
+ */
348
+ lerp([x, y, z], t) {
349
+ this.x += (x - this.x) * t;
350
+ this.y += (y - this.y) * t;
351
+ this.z += (z - this.z) * t;
352
+ return this;
353
+ }
354
+ /**
355
+ * Convert this vector to a unit vector
356
+ *
357
+ * @returns {this}
358
+ */
359
+ normalize() {
360
+ return this.divideScalar(this.length() || 1);
361
+ }
362
+ /**
363
+ * Set this vector values to the same direction but with a given length
364
+ *
365
+ * @param {number} length Length value
366
+ * @returns {this}
367
+ */
368
+ setLength(length) {
369
+ return this.normalize().multiplyScalar(length);
370
+ }
371
+ /**
372
+ * Project this vector onto a given vector
373
+ *
374
+ * @param {Vector3|Point3} vector Vector to project to
375
+ * @returns {this}
376
+ */
377
+ projectOnVector(vector) {
378
+ const denominator = Vector3.squaredLength(vector);
379
+ if (denominator === 0)
380
+ return this.set(0, 0, 0);
381
+ const scalar = Vector3.dot(vector, this) / denominator;
382
+ return this.copy(vector).multiplyScalar(scalar);
383
+ }
384
+ /**
385
+ * Calculate the Euclidean length of this vector
386
+ *
387
+ * @returns {number} Computed Euclidean length
388
+ */
389
+ length() {
390
+ return Vector3.length(this);
391
+ }
392
+ /**
393
+ * Calculate the squared length of this vector
394
+ *
395
+ * @return {number} Computed squared length
396
+ */
397
+ squaredLength() {
398
+ return Vector3.squaredLength(this);
399
+ }
400
+ /**
401
+ * Calculate the Manhattan length of this vector
402
+ *
403
+ * @return {number} Computed Manhattan length
404
+ */
405
+ manhattanLength() {
406
+ return Vector3.manhattanLength(this);
407
+ }
408
+ /**
409
+ * Check if this vector is equal with a given vector
410
+ *
411
+ * @param {Vector3|Point3} vector Vector to check
412
+ * @returns {boolean} True if this vector is equal with the given vector, false otherwise
413
+ */
414
+ equals(vector) {
415
+ return Vector3.equals(this, vector);
416
+ }
417
+ /**
418
+ * Check if this vector is collinear with a given vectors
419
+ *
420
+ * @param {Vector3|Point3} vector1 First vector to check
421
+ * @param {Vector3|Point3} vector2 Second vector to check
422
+ * @returns {boolean} True if this vector is collinear with the given vectors, false otherwise
423
+ */
424
+ collinear(vector1, vector2) {
425
+ return Vector3.collinear(this, vector1, vector2);
426
+ }
427
+ /**
428
+ * Calculate the dot product of a given vector with this vector
429
+ *
430
+ * @param {Vector3|Point3} vector Vector to compute the dot product with
431
+ * @returns {number} Computed dot product
432
+ */
433
+ dot(vector) {
434
+ return Vector3.dot(this, vector);
435
+ }
436
+ /**
437
+ * Calculate the cross product of a given vector with this vector
438
+ *
439
+ * @param {Vector3|Point3} vector Vector to compute the cross product with
440
+ * @returns {Point3} Computed cross product
441
+ */
442
+ cross(vector) {
443
+ return Vector3.cross(this, vector);
444
+ }
445
+ /**
446
+ * Calculate the angle between a given vector and this vector
447
+ *
448
+ * @param {Vector3|Point3} vector Vector to compute the angle with
449
+ * @returns {number} Computed angle (in radians)
450
+ */
451
+ angleTo(vector) {
452
+ const denominator = Math.sqrt(this.squaredLength() * Vector3.squaredLength(vector));
453
+ if (denominator === 0)
454
+ return PI / 2;
455
+ const theta = this.dot(vector) / denominator;
456
+ return Math.acos(clamp(theta, -1, 1));
457
+ }
458
+ /**
459
+ * Calculate the Euclidean distance from a given vector to this vector
460
+ *
461
+ * @param {Vector3|Point3} vector Vector to compute the distance to
462
+ * @returns {number} Computed Euclidean distance
463
+ */
464
+ distanceTo(vector) {
465
+ return Vector3.distance(this, vector);
466
+ }
467
+ /**
468
+ * Calculate the squared distance from a given vector to this vector
469
+ *
470
+ * @param {Vector3|Point3} vector Vector to compute the squared distance to
471
+ * @returns {number} Computed squared distance
472
+ */
473
+ squaredDistanceTo(vector) {
474
+ return Vector3.squaredDistance(this, vector);
475
+ }
476
+ /**
477
+ * Calculate the Manhattan distance from a given vector to this vector
478
+ *
479
+ * @param {Vector3|Point3} vector Vector to compute the Manhattan distance to
480
+ * @returns {number} Computed Manhattan distance
481
+ */
482
+ manhattanDistanceTo(vector) {
483
+ return Vector3.manhattanDistance(this, vector);
484
+ }
485
+ /**
486
+ * Return this vector values into an array
487
+ *
488
+ * @returns {Point3}
489
+ */
490
+ toArray() {
491
+ return [this.x, this.y, this.z];
492
+ }
493
+ /**
494
+ * Set this vector values from a given array
495
+ *
496
+ * @param {number[]} values Values to set
497
+ * @returns
498
+ */
499
+ fromArray([x, y, z]) {
500
+ this.x = x;
501
+ this.y = y;
502
+ this.z = z;
503
+ return this;
504
+ }
505
+ /**
506
+ * Set this vector values from given spherical coordinates
507
+ *
508
+ * @param {number} radius Radius of the sphere
509
+ * @param {number} phi Polar angle from the y (up) axis : [0, PI]
510
+ * @param {number} theta Equator angle around the y (up) axis : [0, 2*PI]
511
+ * @returns {this}
512
+ */
513
+ fromSphericalCoords(radius, phi, theta) {
514
+ const [x, y, z] = Vector3.fromSphericalCoords(radius, phi, theta);
515
+ this.x = x;
516
+ this.y = y;
517
+ this.z = z;
518
+ return this;
519
+ }
520
+ /**
521
+ * Set this vector values from given cylindrical coordinates
522
+ *
523
+ * @param {number} radius Radius of the cylinder
524
+ * @param {number} theta Equator angle around the y (up) axis : [0, 2*PI]
525
+ * @param {number} y Y-axis value
526
+ * @returns {this}
527
+ */
528
+ fromCylindricalCoords(radius, theta, y) {
529
+ const [x, _, z] = Vector3.fromCylindricalCoords(radius, theta, y);
530
+ this.x = x;
531
+ this.y = y;
532
+ this.z = z;
533
+ return this;
534
+ }
535
+ /**
536
+ * Copy the values of a given vector to this vector
537
+ *
538
+ * @param {Vector3|Point3} vector Vector to copy values from
539
+ * @returns {this}
540
+ */
541
+ copy([x, y, z]) {
542
+ this.x = x;
543
+ this.y = y;
544
+ this.z = z;
545
+ return this;
546
+ }
547
+ /**
548
+ * Create a new 3D vector with copied values from this vector
549
+ *
550
+ * @returns {Vector3}
551
+ */
552
+ clone() {
553
+ return new Vector3(this.x, this.y, this.z);
554
+ }
555
+ /**
556
+ * Add two vectors
557
+ *
558
+ * @param {Vector3|Point3} vector1 First vector
559
+ * @param {Vector3|Point3} vector2 Second vector
560
+ * @returns {Point3}
561
+ */
562
+ static add([x1, y1, z1], [x2, y2, z2]) {
563
+ const x = x1 + x2;
564
+ const y = y1 + y2;
565
+ const z = z1 + z2;
566
+ return [x, y, z];
567
+ }
568
+ /**
569
+ * Subtract two vectors
570
+ *
571
+ * @param {Vector3|Point3} vector1 First vector
572
+ * @param {Vector3|Point3} vector2 Second vector
573
+ * @returns {Point3}
574
+ */
575
+ static sub([x1, y1, z1], [x2, y2, z2]) {
576
+ const x = x1 - x2;
577
+ const y = y1 - y2;
578
+ const z = z1 - z2;
579
+ return [x, y, z];
580
+ }
581
+ /**
582
+ * Multiply two vectors
583
+ *
584
+ * @param {Vector3|Point3} vector1 First vector
585
+ * @param {Vector3|Point3} vector2 Second vector
586
+ * @returns {Point3}
587
+ */
588
+ static multiply([x1, y1, z1], [x2, y2, z2]) {
589
+ const x = x1 * x2;
590
+ const y = y1 * y2;
591
+ const z = z1 * z2;
592
+ return [x, y, z];
593
+ }
594
+ /**
595
+ * Divide two vectors
596
+ *
597
+ * @param {Vector3|Point3} vector1 First vector
598
+ * @param {Vector3|Point3} vector2 Second vector
599
+ * @returns {Point3}
600
+ */
601
+ static divide([x1, y1, z1], [x2, y2, z2]) {
602
+ const x = x1 / x2;
603
+ const y = y1 / y2;
604
+ const z = z1 / z2;
605
+ return [x, y, z];
606
+ }
607
+ /**
608
+ * Interpolate a point between two vectors
609
+ *
610
+ * @param {number} t Normalized time value to interpolate
611
+ * @param {Vector3|Point3} min Minimum boundaries
612
+ * @param {Vector3|Point3} max Maximum boundaries
613
+ * @returns {Point3}
614
+ */
615
+ static lerp(t, [x1, y1, z1], [x2, y2, z2]) {
616
+ const x = lerp(t, x1, x2);
617
+ const y = lerp(t, y1, y2);
618
+ const z = lerp(t, z1, z2);
619
+ return [x, y, z];
620
+ }
621
+ /**
622
+ * Check if two vectors are equal to each other
623
+ *
624
+ * @param {Vector3|Point3} vector1 First vector
625
+ * @param {Vector3|Point3} vector2 Second vector
626
+ * @returns {boolean} True if the given vectors are equal, false otherwise
627
+ */
628
+ static equals([x1, y1, z1], [x2, y2, z2]) {
629
+ return x1 === x2 && y1 === y2 && z1 === z2;
630
+ }
631
+ /**
632
+ * Check if three vectors are collinear (aligned on the same line)
633
+ *
634
+ * @param {Vector3|Point3} vector1 First vector
635
+ * @param {Vector3|Point3} vector2 Second vector
636
+ * @param {Vector3|Point3} vector3 Third vector
637
+ * @returns {boolean} True if the given vectors are collinear, false otherwise
638
+ */
639
+ static collinear([x1, y1, z1], [x2, y2, z2], [x3, y3, z3]) {
640
+ const v1 = [x2 - x1, y2 - y1, z2 - z1];
641
+ const v2 = [x3 - x1, y3 - y1, z3 - z1];
642
+ // prettier-ignore
643
+ const cross = [
644
+ v1[1] * v2[2] - v1[2] * v2[1],
645
+ v1[2] * v2[0] - v1[0] * v2[2],
646
+ v1[0] * v2[1] - v1[1] * v2[0]
647
+ ];
648
+ return Math.hypot(...cross) <= EPSILON;
649
+ }
650
+ /**
651
+ * Calculate the dot product of two vectors
652
+ *
653
+ * @param {Vector3|Point3} vector1 First vector
654
+ * @param {Vector3|Point3} vector2 Second vector
655
+ * @returns {number} Computed dot product
656
+ */
657
+ static dot([x1, y1, z1], [x2, y2, z2]) {
658
+ return x1 * x2 + y1 * y2 + z1 * z2;
659
+ }
660
+ /**
661
+ * Calculate the cross product of two vectors
662
+ *
663
+ * @param {Vector3|Point3} vector1 First vector
664
+ * @param {Vector3|Point3} vector2 Second vector
665
+ * @returns {Point3} Computed cross product
666
+ */
667
+ static cross([x1, y1, z1], [x2, y2, z2]) {
668
+ const x = y1 * z2 - z1 * y2;
669
+ const y = z1 * x2 - x1 * z2;
670
+ const z = x1 * y2 - y1 * x2;
671
+ return [x, y, z];
672
+ }
673
+ /**
674
+ * Calculate the Euclidean distance between two vectors
675
+ *
676
+ * @param {Vector3|Point3} vector1 First vector
677
+ * @param {Vector3|Point3} vector2 Second vector
678
+ * @returns {number} Computed Euclidean distance
679
+ */
680
+ static distance(vector1, vector2) {
681
+ return Math.sqrt(Vector3.squaredDistance(vector1, vector2));
682
+ }
683
+ /**
684
+ * Calculate the squared distance between two vectors
685
+ *
686
+ * @param {Vector3|Point3} vector1 First vector
687
+ * @param {Vector3|Point3} vector2 Second vector
688
+ * @returns {number} Computed squared distance
689
+ */
690
+ static squaredDistance([x1, y1, z1], [x2, y2, z2]) {
691
+ const dx = x1 - x2;
692
+ const dy = y1 - y2;
693
+ const dz = z1 - z2;
694
+ return dx * dx + dy * dy + dz * dz;
695
+ }
696
+ /**
697
+ * Calculate the Manhattan distance between two vectors
698
+ *
699
+ * @param {Vector3|Point3} vector1 First vector
700
+ * @param {Vector3|Point3} vector2 Second vector
701
+ * @return {number} Computed Manhattan distance
702
+ */
703
+ static manhattanDistance([x1, y1, z1], [x2, y2, z2]) {
704
+ return Math.abs(x1 - x2) + Math.abs(y1 - y2) + Math.abs(z1 - z2);
705
+ }
706
+ /**
707
+ * Calculate the Euclidean length of a vector
708
+ *
709
+ * @param {Vector3|Point3} vector Vector to compute Euclidean length from
710
+ * @returns {number} Computed Euclidean length
711
+ */
712
+ static length(vector) {
713
+ return Math.sqrt(Vector3.squaredLength(vector));
714
+ }
715
+ /**
716
+ * Calculate the squared length of a vector
717
+ *
718
+ * @param {Vector3|Point3} vector Vector to compute squared length from
719
+ * @returns {number} Computed squared length
720
+ */
721
+ static squaredLength([x, y, z]) {
722
+ return x * x + y * y + z * z;
723
+ }
724
+ /**
725
+ * Calculate the Manhattan length of a vector
726
+ *
727
+ * @param {Vector3|Point3} vector Vector to compute Manhattan length from
728
+ * @return {number} Computed Manhattan length
729
+ */
730
+ static manhattanLength([x, y, z]) {
731
+ return Math.abs(x) + Math.abs(y) + Math.abs(z);
732
+ }
733
+ /**
734
+ * Convert spherical coordinates to a 3D point on the surface of a sphere
735
+ *
736
+ * @param {number} phi Polar angle from the y (up) axis : [0, PI]
737
+ * @param {number} theta Equator angle around the y (up) axis : [0, 2*PI]
738
+ * @param {number} [radius=1] Radius of the sphere
739
+ * @returns {Point3}
740
+ */
741
+ static fromSphericalCoords(phi, theta, radius = 1) {
742
+ const x = radius * Math.sin(phi) * Math.sin(theta);
743
+ const y = radius * Math.cos(phi);
744
+ const z = radius * Math.sin(phi) * Math.cos(theta);
745
+ return [x, y, z];
746
+ }
747
+ /**
748
+ * Convert cylindrical coordinates to a 3D point on the surface of a cylinder
749
+ *
750
+ * @param {number} theta Equator angle around the y (up) axis : [0, 2*PI]
751
+ * @param {number} y Y-axis value
752
+ * @param {number} [radius=1] Radius of the cylinder
753
+ * @returns {Point3}
754
+ */
755
+ static fromCylindricalCoords(theta, y, radius = 1) {
756
+ const x = radius * Math.sin(theta);
757
+ const z = radius * Math.cos(theta);
758
+ return [x, y, z];
759
+ }
760
+ *[Symbol.iterator]() {
761
+ yield this.x;
762
+ yield this.y;
763
+ yield this.z;
764
+ }
765
+ }