@inglorious/utils 3.7.3 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -3
- package/package.json +89 -9
- package/src/algorithms/decision-tree.js +3 -3
- package/src/algorithms/path-finding.js +6 -6
- package/src/data-structures/board.js +97 -15
- package/src/data-structures/index.js +2 -2
- package/src/data-structures/objects.js +352 -34
- package/src/data-structures/string.js +13 -0
- package/src/data-structures/tree.js +1 -1
- package/src/functions/functions.js +168 -0
- package/src/functions/index.js +1 -4
- package/src/math/circle.js +5 -7
- package/src/math/index.js +0 -4
- package/src/math/line.js +3 -3
- package/src/math/point.js +10 -9
- package/src/math/quaternions.js +20 -4
- package/src/math/rectangle.js +4 -4
- package/src/math/segment.js +11 -5
- package/src/math/vectors.js +471 -65
- package/src/physics/acceleration.js +2 -3
- package/src/physics/friction.js +2 -2
- package/src/physics/gravity.js +2 -2
- package/src/physics/jump.js +0 -4
- package/src/physics/velocity.js +2 -3
- package/src/v.js +1 -1
- package/types/algorithms/decision-tree.d.ts +27 -0
- package/types/algorithms/index.d.ts +2 -0
- package/types/algorithms/path-finding.d.ts +69 -0
- package/types/data-structures/array.d.ts +56 -0
- package/types/data-structures/board.d.ts +121 -0
- package/types/data-structures/boolean.d.ts +4 -0
- package/types/data-structures/heap.d.ts +69 -0
- package/types/data-structures/index.d.ts +8 -0
- package/types/data-structures/objects.d.ts +237 -0
- package/types/data-structures/set.d.ts +4 -0
- package/types/data-structures/string.d.ts +7 -0
- package/types/data-structures/tree.d.ts +21 -0
- package/types/functions/functions.d.ts +57 -0
- package/types/functions/index.d.ts +1 -0
- package/types/index.d.ts +6 -4
- package/types/math/circle.d.ts +22 -0
- package/types/math/hitmask.d.ts +20 -0
- package/types/math/index.d.ts +14 -0
- package/types/math/line.d.ts +11 -0
- package/types/math/linear-interpolation.d.ts +2 -0
- package/types/math/numbers.d.ts +26 -0
- package/types/math/point.d.ts +25 -0
- package/types/math/quaternions.d.ts +10 -0
- package/types/math/rectangle.d.ts +36 -0
- package/types/math/rng.d.ts +14 -0
- package/types/math/segment.d.ts +23 -0
- package/types/math/statistics.d.ts +11 -0
- package/types/math/triangle.d.ts +5 -0
- package/types/math/trigonometry.d.ts +26 -0
- package/types/math/vectors.d.ts +190 -0
- package/types/physics/acceleration.d.ts +24 -0
- package/types/physics/friction.d.ts +11 -0
- package/types/physics/gravity.d.ts +20 -0
- package/types/physics/index.d.ts +5 -0
- package/types/physics/jump.d.ts +10 -0
- package/types/physics/velocity.d.ts +20 -0
- package/types/v.d.ts +7 -3
- package/src/data-structures/object.js +0 -320
- package/src/functions/function.js +0 -9
- package/src/math/quaternion.js +0 -22
- package/src/math/vector.js +0 -426
- package/types/algorithms.d.ts +0 -26
- package/types/data-structures.d.ts +0 -53
- package/types/math.d.ts +0 -90
package/src/math/vectors.js
CHANGED
|
@@ -1,12 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef {import("../../types/math").
|
|
3
|
-
* @typedef {import("../../types/math").
|
|
4
|
-
* @typedef {import("../../types/math").
|
|
2
|
+
* @typedef {import("../../types/math/vectors").Vector} Vector
|
|
3
|
+
* @typedef {import("../../types/math/vectors").Vector2} Vector2
|
|
4
|
+
* @typedef {import("../../types/math/vectors").Vector3} Vector3
|
|
5
|
+
* @typedef {import("../../types/math/vectors").Vector7} Vector7
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
8
|
import { v } from "../v.js"
|
|
8
|
-
import {
|
|
9
|
-
|
|
9
|
+
import {
|
|
10
|
+
abs as nAbs,
|
|
11
|
+
clamp as nClamp,
|
|
12
|
+
mod as nMod,
|
|
13
|
+
snap as nSnap,
|
|
14
|
+
} from "./numbers.js"
|
|
15
|
+
import { quaternion } from "./quaternions.js"
|
|
16
|
+
import { hypothenuse } from "./triangle.js"
|
|
17
|
+
import { atan2, cos, sin } from "./trigonometry.js"
|
|
18
|
+
|
|
19
|
+
const ZERO_VECTOR = v(0, 0, 0) // eslint-disable-line no-magic-numbers
|
|
20
|
+
const UNIT_VECTOR = v(1, 0, 0) // eslint-disable-line no-magic-numbers
|
|
21
|
+
|
|
22
|
+
const X = 0
|
|
23
|
+
const Y = 1
|
|
24
|
+
const Z = 2
|
|
25
|
+
const LAST_COORDINATE = 1
|
|
26
|
+
const TWO_COORDINATES = 2
|
|
27
|
+
const NO_Y = 0
|
|
28
|
+
const DEFAULT_PRECISION = 1
|
|
29
|
+
const DEFAULT_DECIMALS = 0
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Returns the absolute value of each component in the vector.
|
|
33
|
+
* @param {Vector} vector - The input vector.
|
|
34
|
+
* @returns {Vector} The vector with absolute values.
|
|
35
|
+
*/
|
|
36
|
+
export function abs(vector) {
|
|
37
|
+
return v(...vector.map(nAbs))
|
|
38
|
+
}
|
|
10
39
|
|
|
11
40
|
/**
|
|
12
41
|
* Alias for the sum function.
|
|
@@ -14,6 +43,65 @@ import { magnitude, shift } from "./vector.js"
|
|
|
14
43
|
*/
|
|
15
44
|
export const add = sum
|
|
16
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Calculates the angle of the vector in radians.
|
|
48
|
+
* @param {Vector} vector - The input vector.
|
|
49
|
+
* @returns {number} The angle of the vector in the XZ plane (for 3D) or XY plane (for 2D), in radians.
|
|
50
|
+
*/
|
|
51
|
+
export function angle(vector) {
|
|
52
|
+
return atan2(vector[vector.length - LAST_COORDINATE], vector[X])
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Clamps the magnitude of the vector between the given min and max values.
|
|
57
|
+
* @param {Vector} vector - The input vector.
|
|
58
|
+
* @param {number|Vector} min - The minimum magnitude or a vector representing the lower bounds for each component.
|
|
59
|
+
* @param {number|Vector} max - The maximum magnitude or a vector representing the upper bounds for each component.
|
|
60
|
+
* @returns {Vector} The clamped vector.
|
|
61
|
+
*/
|
|
62
|
+
export function clamp(vector, min, max) {
|
|
63
|
+
const length = magnitude(vector)
|
|
64
|
+
|
|
65
|
+
if (typeof min === "number" && length < min) {
|
|
66
|
+
return setMagnitude(vector, min)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (typeof max === "number" && length > max) {
|
|
70
|
+
return setMagnitude(vector, max)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (typeof min !== "number" && typeof max !== "number") {
|
|
74
|
+
return v(
|
|
75
|
+
...vector.map((coordinate, index) =>
|
|
76
|
+
nClamp(coordinate, min[index], max[index]),
|
|
77
|
+
),
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return vector
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Returns the conjugate of the vector.
|
|
86
|
+
* @param {Vector} vector - The input vector.
|
|
87
|
+
* @returns {Vector} The conjugated vector.
|
|
88
|
+
*/
|
|
89
|
+
export function conjugate(vector) {
|
|
90
|
+
return v(
|
|
91
|
+
...vector.map((coordinate, index) => (index ? -coordinate : coordinate)),
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Creates a 3D vector with the given magnitude and angle.
|
|
97
|
+
* @param {number} magnitude - The magnitude of the vector.
|
|
98
|
+
* @param {number} angle - The angle of the vector in radians.
|
|
99
|
+
* @returns {Vector3} The created 3D vector.
|
|
100
|
+
*/
|
|
101
|
+
export function createVector(magnitude, angle) {
|
|
102
|
+
return scale(fromAngle(angle), magnitude)
|
|
103
|
+
}
|
|
104
|
+
|
|
17
105
|
/**
|
|
18
106
|
* Computes the cross product of multiple vectors.
|
|
19
107
|
* @param {...Vector3 | Vector7} vectors - The vectors to compute the cross product for.
|
|
@@ -33,12 +121,23 @@ export function distance(...vectors) {
|
|
|
33
121
|
}
|
|
34
122
|
|
|
35
123
|
/**
|
|
36
|
-
* Computes the component-wise division of
|
|
37
|
-
*
|
|
124
|
+
* Computes the component-wise division of vectors. A scalar operand is applied
|
|
125
|
+
* to every component.
|
|
126
|
+
* @param {...(Vector2 | Vector3 | number)} operands - The vectors to divide, or a scalar to divide each component by.
|
|
38
127
|
* @returns {Vector2 | Vector3} The resulting vector.
|
|
39
128
|
*/
|
|
40
|
-
export function divide(...
|
|
41
|
-
return v(...
|
|
129
|
+
export function divide(...operands) {
|
|
130
|
+
return v(...operands.reduce(divideCoordinates))
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Divides a scalar by each component of the vector.
|
|
135
|
+
* @param {number} scalar - The dividend.
|
|
136
|
+
* @param {Vector} vector - The divisor vector.
|
|
137
|
+
* @returns {Vector} The resulting vector.
|
|
138
|
+
*/
|
|
139
|
+
export function divideBy(scalar, vector) {
|
|
140
|
+
return v(...vector.map((coordinate) => scalar / coordinate))
|
|
42
141
|
}
|
|
43
142
|
|
|
44
143
|
/**
|
|
@@ -52,6 +151,25 @@ export function dot(...vectors) {
|
|
|
52
151
|
.reduce((coord1, coord2) => coord1 + coord2)
|
|
53
152
|
}
|
|
54
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Converts a 2D vector [x, z] into a 3D vector [x, 0, z].
|
|
156
|
+
* @param {Vector2} vector - A 2D vector represented as [x, z].
|
|
157
|
+
* @returns {Vector3} A 3D vector represented as [x, 0, z].
|
|
158
|
+
*/
|
|
159
|
+
export function from2D(vector) {
|
|
160
|
+
const [x, z] = vector
|
|
161
|
+
return v(x, NO_Y, z)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Creates a 3D unit vector from the given angle in the XZ plane.
|
|
166
|
+
* @param {number} angle - The angle in radians.
|
|
167
|
+
* @returns {Vector3} The unit vector.
|
|
168
|
+
*/
|
|
169
|
+
export function fromAngle(angle) {
|
|
170
|
+
return rotate(UNIT_VECTOR, angle)
|
|
171
|
+
}
|
|
172
|
+
|
|
55
173
|
/**
|
|
56
174
|
* Alias for the multiply function.
|
|
57
175
|
* @type {typeof multiply}
|
|
@@ -59,30 +177,114 @@ export function dot(...vectors) {
|
|
|
59
177
|
export const hadamard = multiply
|
|
60
178
|
|
|
61
179
|
/**
|
|
62
|
-
*
|
|
63
|
-
*
|
|
180
|
+
* Checks if a value is a vector.
|
|
181
|
+
* This is determined by checking for the `__isVector__` property, which is
|
|
182
|
+
* added by the `v()` factory function for efficient type checking.
|
|
183
|
+
* @param {*} value - The value to check.
|
|
184
|
+
* @returns {boolean} True if the value is a vector, false otherwise.
|
|
185
|
+
*/
|
|
186
|
+
export function isVector(value) {
|
|
187
|
+
return !!value?.__isVector__
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Calculates the magnitude (length) of the vector.
|
|
192
|
+
* @param {Vector} vector - The input vector.
|
|
193
|
+
* @returns {number} The magnitude of the vector.
|
|
194
|
+
*/
|
|
195
|
+
export function magnitude(vector) {
|
|
196
|
+
return hypothenuse(...vector)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export const length = magnitude
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Computes the component-wise modulus of vectors. A scalar operand is applied
|
|
203
|
+
* to every component.
|
|
204
|
+
* @param {...(Vector2 | Vector3 | number)} operands - The vectors to compute the modulus for, or a scalar divisor for each component.
|
|
64
205
|
* @returns {Vector2 | Vector3} The resulting vector after the modulus.
|
|
65
206
|
*/
|
|
66
|
-
export function mod(...
|
|
67
|
-
return v(...
|
|
207
|
+
export function mod(...operands) {
|
|
208
|
+
return v(...operands.reduce(modCoordinates))
|
|
68
209
|
}
|
|
69
210
|
|
|
70
211
|
/**
|
|
71
|
-
*
|
|
72
|
-
* @param {
|
|
212
|
+
* Calculates the modulus of a scalar with each component of the vector.
|
|
213
|
+
* @param {number} scalar - The dividend.
|
|
214
|
+
* @param {Vector} vector - The divisor vector.
|
|
215
|
+
* @returns {Vector} The resulting vector.
|
|
216
|
+
*/
|
|
217
|
+
export function modOf(scalar, vector) {
|
|
218
|
+
return v(...vector.map((coordinate) => nMod(scalar, coordinate)))
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Computes the component-wise multiplication of vectors. A scalar operand is
|
|
223
|
+
* applied to every component.
|
|
224
|
+
* @param {...(Vector2 | Vector3 | number)} operands - The vectors to multiply, or a scalar to multiply each component by.
|
|
73
225
|
* @returns {Vector2 | Vector3} The resulting vector.
|
|
74
226
|
*/
|
|
75
|
-
export function multiply(...
|
|
76
|
-
return v(...
|
|
227
|
+
export function multiply(...operands) {
|
|
228
|
+
return v(...operands.reduce(multiplyCoordinates))
|
|
77
229
|
}
|
|
78
230
|
|
|
79
231
|
/**
|
|
80
|
-
*
|
|
81
|
-
* @param {
|
|
232
|
+
* Normalizes the vector to have a magnitude of 1.
|
|
233
|
+
* @param {Vector} vector - The input vector.
|
|
234
|
+
* @returns {Vector} The normalized vector.
|
|
235
|
+
*/
|
|
236
|
+
export function normalize(vector) {
|
|
237
|
+
const length = magnitude(vector)
|
|
238
|
+
return v(...vector.map((coordinate) => coordinate / length))
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Alias for the power function.
|
|
243
|
+
* @type {typeof power}
|
|
244
|
+
*/
|
|
245
|
+
export const pow = power
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Computes the component-wise power of vectors. A scalar operand is applied
|
|
249
|
+
* to every component.
|
|
250
|
+
* @param {...(Vector2 | Vector3 | number)} operands - The vectors to compute the power for, or a scalar exponent for each component.
|
|
82
251
|
* @returns {Vector2 | Vector3} The resulting vector after the power.
|
|
83
252
|
*/
|
|
84
|
-
export function power(...
|
|
85
|
-
return v(...
|
|
253
|
+
export function power(...operands) {
|
|
254
|
+
return v(...operands.reduce(powerCoordinates))
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Raises a scalar to the power of each component of the vector.
|
|
259
|
+
* @param {number} scalar - The base value.
|
|
260
|
+
* @param {Vector} vector - The exponent vector.
|
|
261
|
+
* @returns {Vector} The resulting vector.
|
|
262
|
+
*/
|
|
263
|
+
export function powerOf(scalar, vector) {
|
|
264
|
+
return v(...vector.map((coordinate) => scalar ** coordinate))
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Alias for the mod function.
|
|
269
|
+
* @type {typeof mod}
|
|
270
|
+
*/
|
|
271
|
+
export const remainder = mod
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Rotates the vector by the given angle. Handles 2D and 3D vectors.
|
|
275
|
+
* For 3D vectors, rotation is around the Y-axis.
|
|
276
|
+
* @param {Vector} vector - The input vector (2D or 3D).
|
|
277
|
+
* @param {number} angle - The angle in radians.
|
|
278
|
+
* @returns {Vector} The rotated vector.
|
|
279
|
+
*/
|
|
280
|
+
export function rotate(vector, angle) {
|
|
281
|
+
const is2D = vector.length === TWO_COORDINATES
|
|
282
|
+
|
|
283
|
+
const vector3 = is2D ? from2D(vector) : vector
|
|
284
|
+
|
|
285
|
+
const result = rotateWithQuaternion(vector3, angle)
|
|
286
|
+
|
|
287
|
+
return is2D ? to2D(result) : result
|
|
86
288
|
}
|
|
87
289
|
|
|
88
290
|
/**
|
|
@@ -91,6 +293,63 @@ export function power(...vectors) {
|
|
|
91
293
|
*/
|
|
92
294
|
export const scalarProduct = dot
|
|
93
295
|
|
|
296
|
+
/**
|
|
297
|
+
* Alias for the multiply function.
|
|
298
|
+
* @type {typeof multiply}
|
|
299
|
+
*/
|
|
300
|
+
export const scale = multiply
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Sets the angle of the vector in the XZ plane while maintaining its magnitude.
|
|
304
|
+
* @param {Vector} vector - The input vector.
|
|
305
|
+
* @param {number} angle - The new angle in radians.
|
|
306
|
+
* @returns {Vector3} The vector with the updated angle.
|
|
307
|
+
*/
|
|
308
|
+
export function setAngle(vector, angle) {
|
|
309
|
+
const length = magnitude(vector)
|
|
310
|
+
const [x, z] = toCartesian([length, angle])
|
|
311
|
+
return v(x, NO_Y, z)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Alias for the setMagnitude function.
|
|
316
|
+
* @type {typeof setMagnitude}
|
|
317
|
+
*/
|
|
318
|
+
export const setLength = setMagnitude
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Sets the magnitude of the vector while maintaining its direction.
|
|
322
|
+
* @param {Vector} vector - The input vector.
|
|
323
|
+
* @param {number} length - The new magnitude.
|
|
324
|
+
* @returns {Vector} The vector with the updated magnitude.
|
|
325
|
+
*/
|
|
326
|
+
export function setMagnitude(vector, length) {
|
|
327
|
+
const normalized = normalize(vector)
|
|
328
|
+
return scale(normalized, length)
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Shifts the components of the vector by the given index.
|
|
333
|
+
* @param {Vector} vector - The input vector.
|
|
334
|
+
* @param {number} index - The index to shift by.
|
|
335
|
+
* @returns {Vector} The shifted vector.
|
|
336
|
+
*/
|
|
337
|
+
export function shift(vector, index) {
|
|
338
|
+
return v(...vector.slice(index), ...vector.slice(X, index))
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Snaps each component of the vector to the nearest multiple of the given precision.
|
|
343
|
+
* @param {Vector} vector - The input vector.
|
|
344
|
+
* @param {number} [precision=DEFAULT_PRECISION] - The precision value.
|
|
345
|
+
* @returns {Vector} The snapped vector.
|
|
346
|
+
*/
|
|
347
|
+
export function snap(vector, precision = DEFAULT_PRECISION) {
|
|
348
|
+
return v(
|
|
349
|
+
...vector.map((coordinate) => nSnap(coordinate, -precision, precision)),
|
|
350
|
+
)
|
|
351
|
+
}
|
|
352
|
+
|
|
94
353
|
/**
|
|
95
354
|
* Subtracts multiple vectors.
|
|
96
355
|
* @param {...Vector2 | Vector3} vectors - The vectors to subtract.
|
|
@@ -110,71 +369,121 @@ export function sum(...vectors) {
|
|
|
110
369
|
}
|
|
111
370
|
|
|
112
371
|
/**
|
|
113
|
-
* Alias for the
|
|
114
|
-
* @type {typeof
|
|
372
|
+
* Alias for the multiply function.
|
|
373
|
+
* @type {typeof multiply}
|
|
115
374
|
*/
|
|
116
|
-
export const
|
|
375
|
+
export const times = multiply
|
|
117
376
|
|
|
118
377
|
/**
|
|
119
|
-
*
|
|
120
|
-
* @param {
|
|
121
|
-
* @
|
|
122
|
-
* @returns {Vector2 | Vector3} The resulting vector after addition.
|
|
378
|
+
* Converts a 3D vector [x, y, z] into a 2D vector [x, z].
|
|
379
|
+
* @param {Vector3} vector - A 3D vector represented as [x, y, z].
|
|
380
|
+
* @returns {Vector2} A 2D vector represented as [x, z].
|
|
123
381
|
*/
|
|
124
|
-
function
|
|
125
|
-
|
|
382
|
+
export function to2D(vector) {
|
|
383
|
+
const [x, , z] = vector
|
|
384
|
+
return v(x, z)
|
|
126
385
|
}
|
|
127
386
|
|
|
128
387
|
/**
|
|
129
|
-
*
|
|
130
|
-
* @param {Vector2
|
|
131
|
-
* @
|
|
132
|
-
* @returns {Vector2 | Vector3} The resulting vector after subtraction.
|
|
388
|
+
* Converts 2D polar coordinates to 2D Cartesian coordinates.
|
|
389
|
+
* @param {Vector2} vector - The polar coordinates [magnitude, angle].
|
|
390
|
+
* @returns {Vector2} The Cartesian coordinates [x, y].
|
|
133
391
|
*/
|
|
134
|
-
function
|
|
135
|
-
return v(
|
|
392
|
+
export function toCartesian([magnitude, angle]) {
|
|
393
|
+
return v(magnitude * cos(angle), magnitude * sin(angle))
|
|
136
394
|
}
|
|
137
395
|
|
|
138
396
|
/**
|
|
139
|
-
*
|
|
140
|
-
* @param {
|
|
141
|
-
* @
|
|
142
|
-
* @returns {Vector2 | Vector3} The resulting vector.
|
|
397
|
+
* Converts a 3D cartesian vector to cylindrical coordinates.
|
|
398
|
+
* @param {Vector3} vector - The input vector [x, y, z].
|
|
399
|
+
* @returns {Vector3} The cylindrical coordinates [radius, theta, z].
|
|
143
400
|
*/
|
|
144
|
-
function
|
|
145
|
-
|
|
401
|
+
export function toCylindrical(vector) {
|
|
402
|
+
const radius = magnitude(vector)
|
|
403
|
+
const theta = angle(vector)
|
|
404
|
+
return v(radius * cos(theta), radius * sin(theta), vector[Z])
|
|
146
405
|
}
|
|
147
406
|
|
|
148
407
|
/**
|
|
149
|
-
*
|
|
150
|
-
* @param {Vector2
|
|
151
|
-
* @
|
|
152
|
-
* @returns {Vector2 | Vector3} The resulting vector after the modulus.
|
|
408
|
+
* Converts a 2D cartesian vector to 2D polar coordinates.
|
|
409
|
+
* @param {Vector2} vector - The input vector [x, y].
|
|
410
|
+
* @returns {Vector2} The polar coordinates [magnitude, angle].
|
|
153
411
|
*/
|
|
154
|
-
function
|
|
155
|
-
return v(
|
|
156
|
-
...vector1.map((coordinate, index) => nMod(coordinate, vector2[index])),
|
|
157
|
-
)
|
|
412
|
+
export function toPolar(vector) {
|
|
413
|
+
return v(magnitude(vector), angle(vector))
|
|
158
414
|
}
|
|
159
415
|
|
|
160
416
|
/**
|
|
161
|
-
*
|
|
162
|
-
* @param {
|
|
163
|
-
* @param {
|
|
164
|
-
* @returns {
|
|
417
|
+
* Converts a vector to a string representation.
|
|
418
|
+
* @param {Vector} vector - The input vector.
|
|
419
|
+
* @param {number} [decimals=DEFAULT_DECIMALS] - The number of decimal places.
|
|
420
|
+
* @returns {string} The string representation of the vector.
|
|
165
421
|
*/
|
|
166
|
-
function
|
|
167
|
-
return
|
|
422
|
+
export function toString(vector, decimals = DEFAULT_DECIMALS) {
|
|
423
|
+
return `[${vector
|
|
424
|
+
.map((coordinate) => coordinate.toFixed(decimals))
|
|
425
|
+
.join(", ")}]`
|
|
168
426
|
}
|
|
169
427
|
|
|
170
428
|
/**
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
429
|
+
* Converts a 3D cartesian vector to spherical coordinates [radius, inclination, azimuth].
|
|
430
|
+
* - radius (r): distance from the origin.
|
|
431
|
+
* - inclination (θ): angle from the Y-axis (0 to PI).
|
|
432
|
+
* - azimuth (φ): angle from the X-axis in the XZ-plane (-PI to PI).
|
|
433
|
+
* @param {Vector3} vector The cartesian vector [x, y, z].
|
|
434
|
+
* @returns {Vector3} The spherical coordinates [r, θ, φ].
|
|
175
435
|
*/
|
|
176
|
-
function
|
|
177
|
-
|
|
436
|
+
export function toSpherical(vector) {
|
|
437
|
+
const r = magnitude(vector)
|
|
438
|
+
|
|
439
|
+
if (!r) {
|
|
440
|
+
return zero()
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// In a Y-up system, inclination is the angle with the Y axis.
|
|
444
|
+
const inclination = Math.acos(vector[Y] / r)
|
|
445
|
+
// Azimuth is the angle in the XZ plane, which `angle()` calculates.
|
|
446
|
+
const azimuth = angle(vector)
|
|
447
|
+
|
|
448
|
+
return v(r, inclination, azimuth)
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Creates a 3D unit vector in the XZ plane with the given angle.
|
|
453
|
+
* @param {number} [angle=0] - The angle in radians.
|
|
454
|
+
* @returns {Vector3} The unit vector.
|
|
455
|
+
*/
|
|
456
|
+
export function unit(angle) {
|
|
457
|
+
if (!angle) {
|
|
458
|
+
return v(...UNIT_VECTOR)
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
return setAngle(UNIT_VECTOR, angle)
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Alias for the cross product function.
|
|
466
|
+
* @type {typeof cross}
|
|
467
|
+
*/
|
|
468
|
+
export const vectorProduct = cross
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Creates a zero vector of 3 dimensions.
|
|
472
|
+
* @returns {Vector3} The zero vector.
|
|
473
|
+
*/
|
|
474
|
+
export function zero() {
|
|
475
|
+
return v(...ZERO_VECTOR)
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Reads the value at the given index of a vector operand, broadcasting a
|
|
480
|
+
* scalar operand to every index.
|
|
481
|
+
* @param {number | Vector2 | Vector3 | Vector7} operand - A vector or a scalar.
|
|
482
|
+
* @param {number} index - The index of the coordinate to read.
|
|
483
|
+
* @returns {number} The coordinate value.
|
|
484
|
+
*/
|
|
485
|
+
function broadcast(operand, index) {
|
|
486
|
+
return typeof operand === "number" ? operand : operand[index]
|
|
178
487
|
}
|
|
179
488
|
|
|
180
489
|
/**
|
|
@@ -202,11 +511,108 @@ function crossMultiplyCoordinates(vector1, vector2) {
|
|
|
202
511
|
}
|
|
203
512
|
|
|
204
513
|
/**
|
|
205
|
-
*
|
|
514
|
+
* Divides the coordinates of two vectors component-wise. Scalars are broadcast.
|
|
515
|
+
* @param {Vector2 | Vector3} vector1 - The dividend vector.
|
|
516
|
+
* @param {number | Vector2 | Vector3} vector2 - The divisor vector or scalar.
|
|
517
|
+
* @returns {Vector2 | Vector3} The resulting vector.
|
|
518
|
+
*/
|
|
519
|
+
function divideCoordinates(vector1, vector2) {
|
|
520
|
+
return v(
|
|
521
|
+
...vector1.map(
|
|
522
|
+
(coordinate, index) => coordinate / broadcast(vector2, index),
|
|
523
|
+
),
|
|
524
|
+
)
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Multiplies the coordinates of two vectors component-wise. Scalars are broadcast.
|
|
206
529
|
* @param {Vector2 | Vector3} vector1 - The first vector.
|
|
207
|
-
* @param {Vector2 | Vector3} vector2 - The second vector.
|
|
208
|
-
* @returns {Vector2 | Vector3} The resulting vector
|
|
530
|
+
* @param {number | Vector2 | Vector3} vector2 - The second vector or scalar.
|
|
531
|
+
* @returns {Vector2 | Vector3} The resulting vector.
|
|
209
532
|
*/
|
|
210
533
|
function dotMultiplyCoordinates(vector1, vector2) {
|
|
211
534
|
return v(...vector1.map((coordinate, index) => coordinate * vector2[index]))
|
|
212
535
|
}
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Computes the component-wise modulus of two vectors. Scalars are broadcast.
|
|
539
|
+
* @param {Vector2 | Vector3} vector1 - The first vector.
|
|
540
|
+
* @param {number | Vector2 | Vector3} vector2 - The second vector or scalar.
|
|
541
|
+
* @returns {Vector2 | Vector3} The resulting vector.
|
|
542
|
+
*/
|
|
543
|
+
function modCoordinates(vector1, vector2) {
|
|
544
|
+
return v(
|
|
545
|
+
...vector1.map((coordinate, index) =>
|
|
546
|
+
nMod(coordinate, broadcast(vector2, index)),
|
|
547
|
+
),
|
|
548
|
+
)
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Multiplies the coordinates of two vectors component-wise. Scalars are broadcast.
|
|
553
|
+
* @param {Vector2 | Vector3} vector1 - The first vector.
|
|
554
|
+
* @param {number | Vector2 | Vector3} vector2 - The second vector or scalar.
|
|
555
|
+
* @returns {Vector2 | Vector3} The resulting vector.
|
|
556
|
+
*/
|
|
557
|
+
function multiplyCoordinates(vector1, vector2) {
|
|
558
|
+
return v(
|
|
559
|
+
...vector1.map(
|
|
560
|
+
(coordinate, index) => coordinate * broadcast(vector2, index),
|
|
561
|
+
),
|
|
562
|
+
)
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Raises the coordinates of the first vector to the power of the second vector's coordinates. Scalars are broadcast.
|
|
567
|
+
* @param {Vector2 | Vector3} vector1 - The base vector.
|
|
568
|
+
* @param {number | Vector2 | Vector3} vector2 - The exponent vector or scalar.
|
|
569
|
+
* @returns {Vector2 | Vector3} The resulting vector.
|
|
570
|
+
*/
|
|
571
|
+
function powerCoordinates(vector1, vector2) {
|
|
572
|
+
return v(
|
|
573
|
+
...vector1.map(
|
|
574
|
+
(coordinate, index) => coordinate ** broadcast(vector2, index),
|
|
575
|
+
),
|
|
576
|
+
)
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Subtracts the coordinates of two vectors.
|
|
581
|
+
* @param {Vector2 | Vector3} vector1 - The first vector.
|
|
582
|
+
* @param {Vector2 | Vector3} vector2 - The second vector.
|
|
583
|
+
* @returns {Vector2 | Vector3} The resulting vector after subtraction.
|
|
584
|
+
*/
|
|
585
|
+
function subtractCoordinates(vector1, vector2) {
|
|
586
|
+
return v(...vector1.map((coordinate, index) => coordinate - vector2[index]))
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Adds the coordinates of two vectors.
|
|
591
|
+
* @param {Vector2 | Vector3} vector1 - The first vector.
|
|
592
|
+
* @param {Vector2 | Vector3} vector2 - The second vector.
|
|
593
|
+
* @returns {Vector2 | Vector3} The resulting vector after addition.
|
|
594
|
+
*/
|
|
595
|
+
function sumCoordinates(vector1, vector2) {
|
|
596
|
+
return v(...vector1.map((coordinate, index) => coordinate + vector2[index]))
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* Rotates a 3D vector around the Y-axis using a quaternion.
|
|
601
|
+
* @param {Vector3} vector - The input vector.
|
|
602
|
+
* @param {number} angle - The angle in radians.
|
|
603
|
+
* @returns {Vector3} The rotated vector.
|
|
604
|
+
*/
|
|
605
|
+
function rotateWithQuaternion(vector, angle) {
|
|
606
|
+
if (!angle) {
|
|
607
|
+
return vector
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// @see https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation#Performance_comparisons
|
|
611
|
+
const [w, ...r] = quaternion(angle)
|
|
612
|
+
const result = sum(
|
|
613
|
+
vector,
|
|
614
|
+
cross(scale(r, 2), sum(cross(r, vector), scale(vector, w))), // eslint-disable-line no-magic-numbers
|
|
615
|
+
)
|
|
616
|
+
|
|
617
|
+
return conjugate(result) // HACK: not really sure why I should invert the result, it just works this way
|
|
618
|
+
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef {import("../../types/math").Vector3} Vector3
|
|
2
|
+
* @typedef {import("../../types/math/vectors").Vector3} Vector3
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { clamp, multiply, zero } from "../math/
|
|
6
|
-
import { sum } from "../math/vectors.js"
|
|
5
|
+
import { clamp, multiply, sum, zero } from "../math/vectors.js"
|
|
7
6
|
import { applyFriction } from "./friction.js"
|
|
8
7
|
|
|
9
8
|
const DEFAULT_DT = 1 // Default time delta for the applyAcceleration function.
|
package/src/physics/friction.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef {import("../../types/math").Vector3} Vector3
|
|
2
|
+
* @typedef {import("../../types/math/vectors").Vector3} Vector3
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { magnitude, setMagnitude, zero } from "../math/
|
|
5
|
+
import { magnitude, setMagnitude, zero } from "../math/vectors.js"
|
|
6
6
|
|
|
7
7
|
const DEFAULT_DT = 1 // Default time delta for the applyFriction function.
|
|
8
8
|
const NO_FRICTION = 0 // No friction constant.
|
package/src/physics/gravity.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef {import("../../types/math").Vector3} Vector3
|
|
2
|
+
* @typedef {import("../../types/math/vectors").Vector3} Vector3
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
/* eslint-disable no-magic-numbers */
|
|
6
6
|
|
|
7
|
-
import { zero } from "../math/
|
|
7
|
+
import { zero } from "../math/vectors.js"
|
|
8
8
|
|
|
9
9
|
const DEFAULT_DT = 1 // Default delta time for the applyGravity function.
|
|
10
10
|
const DEFAULT_JUMP = 0 // Default maximum jump height.
|