@inglorious/utils 3.8.0 → 5.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 +83 -3
- package/package.json +104 -12
- package/src/algorithms/decision-tree.js +3 -3
- package/src/algorithms/path-finding.js +6 -6
- package/src/data-structures/array.js +12 -0
- package/src/data-structures/board.js +97 -15
- package/src/data-structures/index.js +1 -2
- package/src/data-structures/object.js +164 -2
- package/src/data-structures/string.js +77 -0
- package/src/data-structures/tree.js +1 -1
- package/src/functions/function.js +190 -0
- package/src/functions/index.js +1 -4
- package/src/math/circle.js +5 -7
- package/src/math/hitmask.js +1 -1
- package/src/math/index.js +2 -6
- package/src/math/line.js +4 -4
- package/src/math/point.js +31 -9
- package/src/math/quaternion.js +19 -2
- package/src/math/rectangle.js +16 -4
- package/src/math/rng.js +5 -2
- package/src/math/segment.js +11 -5
- package/src/math/trigonometry.js +1 -1
- package/src/math/vector.js +288 -37
- package/src/physics/acceleration.js +2 -3
- package/src/physics/friction.js +1 -1
- package/src/physics/gravity.js +1 -1
- 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 +61 -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/object.d.ts +237 -0
- package/types/data-structures/set.d.ts +4 -0
- package/types/data-structures/tree.d.ts +21 -0
- package/types/functions/function.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/number.d.ts +26 -0
- package/types/math/point.d.ts +50 -0
- package/types/math/quaternion.d.ts +10 -0
- package/types/math/rectangle.d.ts +57 -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/vector.d.ts +219 -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/objects.js +0 -113
- package/src/functions/functions.js +0 -31
- package/src/math/quaternions.js +0 -23
- package/src/math/vectors.js +0 -212
- 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/{numbers.js → number.js} +0 -0
package/src/math/quaternion.js
CHANGED
|
@@ -1,16 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef {import("../../types/math").Vector3} Vector3
|
|
3
|
-
* @typedef {import("../../types/math").Quaternion} Quaternion
|
|
2
|
+
* @typedef {import("../../types/math/vector").Vector3} Vector3
|
|
3
|
+
* @typedef {import("../../types/math/quaternion").Quaternion} Quaternion
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { v } from "../v.js"
|
|
7
7
|
import { cos, sin } from "./trigonometry.js"
|
|
8
|
+
import { cross, dot, multiply, sum } from "./vector.js"
|
|
8
9
|
|
|
9
10
|
const DEFAULT_ANGLE = 0
|
|
10
11
|
const HALF = 2 // Constant representing the divisor for halving an angle.
|
|
11
12
|
// eslint-disable-next-line no-magic-numbers
|
|
12
13
|
const Y_AXIS = v(0, 1, 0) // Default axis of rotation (Y-axis).
|
|
13
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Combines two quaternions using the Hamilton product.
|
|
17
|
+
* @param {Quaternion} q1 - The first quaternion.
|
|
18
|
+
* @param {Quaternion} q2 - The second quaternion.
|
|
19
|
+
* @returns {Quaternion} - The resulting quaternion after combining q1 and q2.
|
|
20
|
+
*/
|
|
21
|
+
export function combine(q1, q2) {
|
|
22
|
+
const [s1, ...v1] = q1
|
|
23
|
+
const [s2, ...v2] = q2
|
|
24
|
+
|
|
25
|
+
return v(
|
|
26
|
+
s1 * s2 - dot(v1, v2),
|
|
27
|
+
...sum(multiply(v2, s1), multiply(v1, s2), cross(v1, v2)),
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
14
31
|
/**
|
|
15
32
|
* Computes a quaternion representing a rotation around a given axis.
|
|
16
33
|
* @param {number} [angle=0] - The angle of rotation in radians. Defaults to 0.
|
package/src/math/rectangle.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* `height` and `depth` are independent axes, not halves of one screen
|
|
3
|
+
* dimension, so a body on the `xy` plane is sized `v(w, h, 0)` and one on the
|
|
4
|
+
* `xz` plane `v(w, 0, h)`. `@inglorious/renderer-2d` flattens both onto the
|
|
5
|
+
* screen and draws a rectangle `height + depth` tall, while
|
|
6
|
+
* {@link intersectsRectangle} tests the two axes separately.
|
|
7
|
+
*
|
|
8
|
+
* @typedef {import("../../types/math/rectangle").Size} Size
|
|
9
|
+
* @typedef {import("../../types/math/circle").Circle} Circle
|
|
10
|
+
* @typedef {import("../../types/math/point").PointInput} PointInput
|
|
11
|
+
* @typedef {import("../../types/math/rectangle").Rectangle} Rectangle
|
|
5
12
|
*/
|
|
6
13
|
|
|
7
14
|
import { intersectsRectangle as circleIntersectsRectangle } from "./circle.js"
|
|
@@ -11,8 +18,13 @@ const HALF = 2
|
|
|
11
18
|
|
|
12
19
|
/**
|
|
13
20
|
* Checks if a rectangle intersects with a point.
|
|
21
|
+
*
|
|
22
|
+
* The rectangle's `position` is its center, and `size` extends around it. An
|
|
23
|
+
* anchored shape is the exception: its `anchor` picks which point sits on the
|
|
24
|
+
* position, so the two only line up when the anchor matches, such as
|
|
25
|
+
* `[0.5, 0.5]` for a centred one.
|
|
14
26
|
* @param {Rectangle} rectangle - The rectangle to check.
|
|
15
|
-
* @param {
|
|
27
|
+
* @param {PointInput} point - The point to check.
|
|
16
28
|
* @returns {boolean} True if the point intersects the circle, false otherwise.
|
|
17
29
|
*/
|
|
18
30
|
export function intersectsPoint(rectangle, point) {
|
package/src/math/rng.js
CHANGED
|
@@ -31,10 +31,13 @@ export function random(...args) {
|
|
|
31
31
|
return Math.random()
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
// A range with a fractional bound cannot be stepped through as integers, so it
|
|
35
|
+
// is read as a continuous range. Requiring both bounds to be floats used to
|
|
36
|
+
// send `random(0.5, 1)` down the integer path, where it could only ever answer
|
|
37
|
+
// 0 or 1.
|
|
34
38
|
if (
|
|
35
39
|
args.length > 1 &&
|
|
36
|
-
!Number.isInteger(args[0])
|
|
37
|
-
!Number.isInteger(args[1])
|
|
40
|
+
(!Number.isInteger(args[0]) || !Number.isInteger(args[1]))
|
|
38
41
|
) {
|
|
39
42
|
const [from, to] = args
|
|
40
43
|
return Math.random() * (to - from) + from
|
package/src/math/segment.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef {import("../../types/math").Segment} Segment
|
|
3
|
-
* @typedef {import("../../types/math").Point} Point
|
|
4
|
-
* @typedef {import("../../types/math").Circle} Circle
|
|
2
|
+
* @typedef {import("../../types/math/segment").Segment} Segment
|
|
3
|
+
* @typedef {import("../../types/math/point").Point} Point
|
|
4
|
+
* @typedef {import("../../types/math/circle").Circle} Circle
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
7
|
+
import {
|
|
8
|
+
distance,
|
|
9
|
+
dot,
|
|
10
|
+
magnitude,
|
|
11
|
+
setMagnitude,
|
|
12
|
+
subtract,
|
|
13
|
+
sum,
|
|
14
|
+
} from "./vector.js"
|
|
9
15
|
|
|
10
16
|
const BEFORE_SEGMENT = 0
|
|
11
17
|
|
package/src/math/trigonometry.js
CHANGED
package/src/math/vector.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef {import("../../types/math").Vector} Vector
|
|
3
|
-
* @typedef {import("../../types/math").Vector2} Vector2
|
|
4
|
-
* @typedef {import("../../types/math").Vector3} Vector3
|
|
2
|
+
* @typedef {import("../../types/math/vector").Vector} Vector
|
|
3
|
+
* @typedef {import("../../types/math/vector").Vector2} Vector2
|
|
4
|
+
* @typedef {import("../../types/math/vector").Vector3} Vector3
|
|
5
|
+
* @typedef {import("../../types/math/vector").Vector7} Vector7
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
8
|
import { v } from "../v.js"
|
|
@@ -10,14 +11,32 @@ import {
|
|
|
10
11
|
clamp as nClamp,
|
|
11
12
|
mod as nMod,
|
|
12
13
|
snap as nSnap,
|
|
13
|
-
} from "./
|
|
14
|
+
} from "./number.js"
|
|
14
15
|
import { quaternion } from "./quaternion.js"
|
|
16
|
+
import { random } from "./rng.js"
|
|
15
17
|
import { hypothenuse } from "./triangle.js"
|
|
16
18
|
import { atan2, cos, sin } from "./trigonometry.js"
|
|
17
|
-
import { cross, sum } from "./vectors.js"
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
|
+
* The vector with every component at zero. Useful for naming the components you
|
|
22
|
+
* care about, and for building a vector up from scratch:
|
|
23
|
+
*
|
|
24
|
+
* const [, NO_RISE, NO_DEPTH] = ZERO_VECTOR
|
|
25
|
+
* const position = v(10, 20, NO_DEPTH)
|
|
26
|
+
*
|
|
27
|
+
* Vectors are mutable arrays, so copy it rather than storing it where something
|
|
28
|
+
* writes to one, such as an entity position. Copy it with `v(...ZERO_VECTOR)`,
|
|
29
|
+
* since a plain spread drops the tag `isVector` looks for.
|
|
30
|
+
*/
|
|
31
|
+
export const ZERO_VECTOR = v(0, 0, 0) // eslint-disable-line no-magic-numbers
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The vector one unit long along the x axis. Useful for facing a direction, as
|
|
35
|
+
* in `rotate(UNIT_VECTOR, angle)`.
|
|
36
|
+
*
|
|
37
|
+
* As with `ZERO_VECTOR`, copy it with `v(...UNIT_VECTOR)` before storing it.
|
|
38
|
+
*/
|
|
39
|
+
export const UNIT_VECTOR = v(1, 0, 0) // eslint-disable-line no-magic-numbers
|
|
21
40
|
|
|
22
41
|
const X = 0
|
|
23
42
|
const Y = 1
|
|
@@ -25,6 +44,7 @@ const Z = 2
|
|
|
25
44
|
const LAST_COORDINATE = 1
|
|
26
45
|
const TWO_COORDINATES = 2
|
|
27
46
|
const NO_Y = 0
|
|
47
|
+
const NO_COMPONENT = 0
|
|
28
48
|
const DEFAULT_PRECISION = 1
|
|
29
49
|
const DEFAULT_DECIMALS = 0
|
|
30
50
|
|
|
@@ -37,6 +57,12 @@ export function abs(vector) {
|
|
|
37
57
|
return v(...vector.map(nAbs))
|
|
38
58
|
}
|
|
39
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Alias for the sum function.
|
|
62
|
+
* @type {typeof sum}
|
|
63
|
+
*/
|
|
64
|
+
export const add = sum
|
|
65
|
+
|
|
40
66
|
/**
|
|
41
67
|
* Calculates the angle of the vector in radians.
|
|
42
68
|
* @param {Vector} vector - The input vector.
|
|
@@ -96,6 +122,34 @@ export function createVector(magnitude, angle) {
|
|
|
96
122
|
return scale(fromAngle(angle), magnitude)
|
|
97
123
|
}
|
|
98
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Computes the cross product of multiple vectors.
|
|
127
|
+
* @param {...Vector3 | Vector7} vectors - The vectors to compute the cross product for.
|
|
128
|
+
* @returns {Vector3 | Vector7} The resulting vector after the cross product.
|
|
129
|
+
*/
|
|
130
|
+
export function cross(...vectors) {
|
|
131
|
+
return v(...vectors.reduce(crossMultiplyCoordinates))
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Computes the distance between multiple vectors.
|
|
136
|
+
* @param {...Vector2 | Vector3} vectors - The vectors to compute the distance between.
|
|
137
|
+
* @returns {number} The distance between the vectors.
|
|
138
|
+
*/
|
|
139
|
+
export function distance(...vectors) {
|
|
140
|
+
return magnitude(subtract(...vectors))
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Computes the component-wise division of vectors. A scalar operand is applied
|
|
145
|
+
* to every component.
|
|
146
|
+
* @param {...(Vector2 | Vector3 | number)} operands - The vectors to divide, or a scalar to divide each component by.
|
|
147
|
+
* @returns {Vector2 | Vector3} The resulting vector.
|
|
148
|
+
*/
|
|
149
|
+
export function divide(...operands) {
|
|
150
|
+
return v(...operands.reduce(divideCoordinates))
|
|
151
|
+
}
|
|
152
|
+
|
|
99
153
|
/**
|
|
100
154
|
* Divides a scalar by each component of the vector.
|
|
101
155
|
* @param {number} scalar - The dividend.
|
|
@@ -107,13 +161,14 @@ export function divideBy(scalar, vector) {
|
|
|
107
161
|
}
|
|
108
162
|
|
|
109
163
|
/**
|
|
110
|
-
*
|
|
111
|
-
* @param {
|
|
112
|
-
* @
|
|
113
|
-
* @returns {Vector} The resulting vector.
|
|
164
|
+
* Computes the dot product of multiple vectors.
|
|
165
|
+
* @param {...Vector2 | Vector3} vectors - The vectors to compute the dot product for.
|
|
166
|
+
* @returns {number} The resulting scalar value of the dot product.
|
|
114
167
|
*/
|
|
115
|
-
export function
|
|
116
|
-
return
|
|
168
|
+
export function dot(...vectors) {
|
|
169
|
+
return vectors
|
|
170
|
+
.reduce(dotMultiplyCoordinates)
|
|
171
|
+
.reduce((coord1, coord2) => coord1 + coord2)
|
|
117
172
|
}
|
|
118
173
|
|
|
119
174
|
/**
|
|
@@ -135,6 +190,12 @@ export function fromAngle(angle) {
|
|
|
135
190
|
return rotate(UNIT_VECTOR, angle)
|
|
136
191
|
}
|
|
137
192
|
|
|
193
|
+
/**
|
|
194
|
+
* Alias for the multiply function.
|
|
195
|
+
* @type {typeof multiply}
|
|
196
|
+
*/
|
|
197
|
+
export const hadamard = multiply
|
|
198
|
+
|
|
138
199
|
/**
|
|
139
200
|
* Checks if a value is a vector.
|
|
140
201
|
* This is determined by checking for the `__isVector__` property, which is
|
|
@@ -158,13 +219,13 @@ export function magnitude(vector) {
|
|
|
158
219
|
export const length = magnitude
|
|
159
220
|
|
|
160
221
|
/**
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
* @param {number}
|
|
164
|
-
* @returns {
|
|
222
|
+
* Computes the component-wise modulus of vectors. A scalar operand is applied
|
|
223
|
+
* to every component.
|
|
224
|
+
* @param {...(Vector2 | Vector3 | number)} operands - The vectors to compute the modulus for, or a scalar divisor for each component.
|
|
225
|
+
* @returns {Vector2 | Vector3} The resulting vector after the modulus.
|
|
165
226
|
*/
|
|
166
|
-
export function mod(
|
|
167
|
-
return v(...
|
|
227
|
+
export function mod(...operands) {
|
|
228
|
+
return v(...operands.reduce(modCoordinates))
|
|
168
229
|
}
|
|
169
230
|
|
|
170
231
|
/**
|
|
@@ -178,13 +239,33 @@ export function modOf(scalar, vector) {
|
|
|
178
239
|
}
|
|
179
240
|
|
|
180
241
|
/**
|
|
181
|
-
*
|
|
242
|
+
* Computes the component-wise multiplication of vectors. A scalar operand is
|
|
243
|
+
* applied to every component.
|
|
244
|
+
* @param {...(Vector2 | Vector3 | number)} operands - The vectors to multiply, or a scalar to multiply each component by.
|
|
245
|
+
* @returns {Vector2 | Vector3} The resulting vector.
|
|
246
|
+
*/
|
|
247
|
+
export function multiply(...operands) {
|
|
248
|
+
return v(...operands.reduce(multiplyCoordinates))
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Flips the direction of every component, so that adding the result to a vector
|
|
253
|
+
* gives back the point mirrored through it.
|
|
182
254
|
* @param {Vector} vector - The input vector.
|
|
183
|
-
* @
|
|
184
|
-
* @returns {Vector} The resulting vector.
|
|
255
|
+
* @returns {Vector} The negated vector.
|
|
185
256
|
*/
|
|
186
|
-
export function
|
|
187
|
-
return v(...vector.map((coordinate) => coordinate
|
|
257
|
+
export function negate(vector) {
|
|
258
|
+
return v(...vector.map((coordinate) => -coordinate))
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Normalizes the vector to have a magnitude of 1.
|
|
263
|
+
* @param {Vector} vector - The input vector.
|
|
264
|
+
* @returns {Vector} The normalized vector.
|
|
265
|
+
*/
|
|
266
|
+
export function normalize(vector) {
|
|
267
|
+
const length = magnitude(vector)
|
|
268
|
+
return v(...vector.map((coordinate) => coordinate / length))
|
|
188
269
|
}
|
|
189
270
|
|
|
190
271
|
/**
|
|
@@ -194,13 +275,13 @@ export function multiply(vector, scalar) {
|
|
|
194
275
|
export const pow = power
|
|
195
276
|
|
|
196
277
|
/**
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
* @param {number}
|
|
200
|
-
* @returns {
|
|
278
|
+
* Computes the component-wise power of vectors. A scalar operand is applied
|
|
279
|
+
* to every component.
|
|
280
|
+
* @param {...(Vector2 | Vector3 | number)} operands - The vectors to compute the power for, or a scalar exponent for each component.
|
|
281
|
+
* @returns {Vector2 | Vector3} The resulting vector after the power.
|
|
201
282
|
*/
|
|
202
|
-
export function power(
|
|
203
|
-
return v(...
|
|
283
|
+
export function power(...operands) {
|
|
284
|
+
return v(...operands.reduce(powerCoordinates))
|
|
204
285
|
}
|
|
205
286
|
|
|
206
287
|
/**
|
|
@@ -214,13 +295,32 @@ export function powerOf(scalar, vector) {
|
|
|
214
295
|
}
|
|
215
296
|
|
|
216
297
|
/**
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
298
|
+
* Draws a random vector, taking each component from its own range: the low end is
|
|
299
|
+
* where that axis starts, the high end where it can reach. This is `random`
|
|
300
|
+
* applied per axis, so it suits ranges that differ by axis, where a single pair of
|
|
301
|
+
* bounds would have to be square.
|
|
302
|
+
*
|
|
303
|
+
* A component whose bounds are the same always comes out equal to them, and either
|
|
304
|
+
* bound may be left out to fall back to zero on that axis.
|
|
305
|
+
*
|
|
306
|
+
* @param {Vector} [low] - Where each axis starts.
|
|
307
|
+
* @param {Vector} [high] - Where each axis can reach.
|
|
308
|
+
* @returns {Vector} The random vector.
|
|
309
|
+
* @example
|
|
310
|
+
* ```js
|
|
311
|
+
* // Debris thrown to the left or right, never up or down.
|
|
312
|
+
* randomVector(v(-15, 0, 0), v(15, 0, 0))
|
|
313
|
+
* ```
|
|
314
|
+
*/
|
|
315
|
+
export function randomVector(low, high) {
|
|
316
|
+
const [lowX, lowY, lowZ] = low ?? []
|
|
317
|
+
const [highX, highY, highZ] = high ?? []
|
|
318
|
+
|
|
319
|
+
return v(
|
|
320
|
+
random(lowX ?? NO_COMPONENT, highX ?? NO_COMPONENT),
|
|
321
|
+
random(lowY ?? NO_COMPONENT, highY ?? NO_COMPONENT),
|
|
322
|
+
random(lowZ ?? NO_COMPONENT, highZ ?? NO_COMPONENT),
|
|
323
|
+
)
|
|
224
324
|
}
|
|
225
325
|
|
|
226
326
|
/**
|
|
@@ -246,6 +346,12 @@ export function rotate(vector, angle) {
|
|
|
246
346
|
return is2D ? to2D(result) : result
|
|
247
347
|
}
|
|
248
348
|
|
|
349
|
+
/**
|
|
350
|
+
* Alias for the dot product function.
|
|
351
|
+
* @type {typeof dot}
|
|
352
|
+
*/
|
|
353
|
+
export const scalarProduct = dot
|
|
354
|
+
|
|
249
355
|
/**
|
|
250
356
|
* Alias for the multiply function.
|
|
251
357
|
* @type {typeof multiply}
|
|
@@ -303,6 +409,24 @@ export function snap(vector, precision = DEFAULT_PRECISION) {
|
|
|
303
409
|
)
|
|
304
410
|
}
|
|
305
411
|
|
|
412
|
+
/**
|
|
413
|
+
* Subtracts multiple vectors.
|
|
414
|
+
* @param {...Vector2 | Vector3} vectors - The vectors to subtract.
|
|
415
|
+
* @returns {Vector2 | Vector3} The resulting vector after subtraction.
|
|
416
|
+
*/
|
|
417
|
+
export function subtract(...vectors) {
|
|
418
|
+
return v(...vectors.reduce(subtractCoordinates))
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Sums multiple vectors.
|
|
423
|
+
* @param {...Vector2 | Vector3} vectors - The vectors to sum.
|
|
424
|
+
* @returns {Vector2 | Vector3} The resulting vector after summation.
|
|
425
|
+
*/
|
|
426
|
+
export function sum(...vectors) {
|
|
427
|
+
return v(...vectors.reduce(sumCoordinates))
|
|
428
|
+
}
|
|
429
|
+
|
|
306
430
|
/**
|
|
307
431
|
* Alias for the multiply function.
|
|
308
432
|
* @type {typeof multiply}
|
|
@@ -396,6 +520,12 @@ export function unit(angle) {
|
|
|
396
520
|
return setAngle(UNIT_VECTOR, angle)
|
|
397
521
|
}
|
|
398
522
|
|
|
523
|
+
/**
|
|
524
|
+
* Alias for the cross product function.
|
|
525
|
+
* @type {typeof cross}
|
|
526
|
+
*/
|
|
527
|
+
export const vectorProduct = cross
|
|
528
|
+
|
|
399
529
|
/**
|
|
400
530
|
* Creates a zero vector of 3 dimensions.
|
|
401
531
|
* @returns {Vector3} The zero vector.
|
|
@@ -404,6 +534,127 @@ export function zero() {
|
|
|
404
534
|
return v(...ZERO_VECTOR)
|
|
405
535
|
}
|
|
406
536
|
|
|
537
|
+
/**
|
|
538
|
+
* Reads the value at the given index of a vector operand, broadcasting a
|
|
539
|
+
* scalar operand to every index.
|
|
540
|
+
* @param {number | Vector2 | Vector3 | Vector7} operand - A vector or a scalar.
|
|
541
|
+
* @param {number} index - The index of the coordinate to read.
|
|
542
|
+
* @returns {number} The coordinate value.
|
|
543
|
+
*/
|
|
544
|
+
function broadcast(operand, index) {
|
|
545
|
+
return typeof operand === "number" ? operand : operand[index]
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Computes the cross product of two vectors' coordinates.
|
|
550
|
+
* @param {Vector3} vector1 - The first vector.
|
|
551
|
+
* @param {Vector3} vector2 - The second vector.
|
|
552
|
+
* @returns {Vector3} The resulting vector after the cross product.
|
|
553
|
+
*/
|
|
554
|
+
function crossMultiplyCoordinates(vector1, vector2) {
|
|
555
|
+
const indexes = Array(vector1.length)
|
|
556
|
+
.fill(null)
|
|
557
|
+
.map((_, index) => index)
|
|
558
|
+
|
|
559
|
+
return v(
|
|
560
|
+
...indexes.map((_, index) => {
|
|
561
|
+
const [index1, index2] = shift(
|
|
562
|
+
indexes.filter((_, i) => i !== index),
|
|
563
|
+
index,
|
|
564
|
+
)
|
|
565
|
+
return (
|
|
566
|
+
vector1[index1] * vector2[index2] - vector1[index2] * vector2[index1]
|
|
567
|
+
)
|
|
568
|
+
}),
|
|
569
|
+
)
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Divides the coordinates of two vectors component-wise. Scalars are broadcast.
|
|
574
|
+
* @param {Vector2 | Vector3} vector1 - The dividend vector.
|
|
575
|
+
* @param {number | Vector2 | Vector3} vector2 - The divisor vector or scalar.
|
|
576
|
+
* @returns {Vector2 | Vector3} The resulting vector.
|
|
577
|
+
*/
|
|
578
|
+
function divideCoordinates(vector1, vector2) {
|
|
579
|
+
return v(
|
|
580
|
+
...vector1.map(
|
|
581
|
+
(coordinate, index) => coordinate / broadcast(vector2, index),
|
|
582
|
+
),
|
|
583
|
+
)
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Multiplies the coordinates of two vectors component-wise. Scalars are broadcast.
|
|
588
|
+
* @param {Vector2 | Vector3} vector1 - The first vector.
|
|
589
|
+
* @param {number | Vector2 | Vector3} vector2 - The second vector or scalar.
|
|
590
|
+
* @returns {Vector2 | Vector3} The resulting vector.
|
|
591
|
+
*/
|
|
592
|
+
function dotMultiplyCoordinates(vector1, vector2) {
|
|
593
|
+
return v(...vector1.map((coordinate, index) => coordinate * vector2[index]))
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/**
|
|
597
|
+
* Computes the component-wise modulus of two vectors. Scalars are broadcast.
|
|
598
|
+
* @param {Vector2 | Vector3} vector1 - The first vector.
|
|
599
|
+
* @param {number | Vector2 | Vector3} vector2 - The second vector or scalar.
|
|
600
|
+
* @returns {Vector2 | Vector3} The resulting vector.
|
|
601
|
+
*/
|
|
602
|
+
function modCoordinates(vector1, vector2) {
|
|
603
|
+
return v(
|
|
604
|
+
...vector1.map((coordinate, index) =>
|
|
605
|
+
nMod(coordinate, broadcast(vector2, index)),
|
|
606
|
+
),
|
|
607
|
+
)
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* Multiplies the coordinates of two vectors component-wise. Scalars are broadcast.
|
|
612
|
+
* @param {Vector2 | Vector3} vector1 - The first vector.
|
|
613
|
+
* @param {number | Vector2 | Vector3} vector2 - The second vector or scalar.
|
|
614
|
+
* @returns {Vector2 | Vector3} The resulting vector.
|
|
615
|
+
*/
|
|
616
|
+
function multiplyCoordinates(vector1, vector2) {
|
|
617
|
+
return v(
|
|
618
|
+
...vector1.map(
|
|
619
|
+
(coordinate, index) => coordinate * broadcast(vector2, index),
|
|
620
|
+
),
|
|
621
|
+
)
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Raises the coordinates of the first vector to the power of the second vector's coordinates. Scalars are broadcast.
|
|
626
|
+
* @param {Vector2 | Vector3} vector1 - The base vector.
|
|
627
|
+
* @param {number | Vector2 | Vector3} vector2 - The exponent vector or scalar.
|
|
628
|
+
* @returns {Vector2 | Vector3} The resulting vector.
|
|
629
|
+
*/
|
|
630
|
+
function powerCoordinates(vector1, vector2) {
|
|
631
|
+
return v(
|
|
632
|
+
...vector1.map(
|
|
633
|
+
(coordinate, index) => coordinate ** broadcast(vector2, index),
|
|
634
|
+
),
|
|
635
|
+
)
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* Subtracts the coordinates of two vectors.
|
|
640
|
+
* @param {Vector2 | Vector3} vector1 - The first vector.
|
|
641
|
+
* @param {Vector2 | Vector3} vector2 - The second vector.
|
|
642
|
+
* @returns {Vector2 | Vector3} The resulting vector after subtraction.
|
|
643
|
+
*/
|
|
644
|
+
function subtractCoordinates(vector1, vector2) {
|
|
645
|
+
return v(...vector1.map((coordinate, index) => coordinate - vector2[index]))
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* Adds the coordinates of two vectors.
|
|
650
|
+
* @param {Vector2 | Vector3} vector1 - The first vector.
|
|
651
|
+
* @param {Vector2 | Vector3} vector2 - The second vector.
|
|
652
|
+
* @returns {Vector2 | Vector3} The resulting vector after addition.
|
|
653
|
+
*/
|
|
654
|
+
function sumCoordinates(vector1, vector2) {
|
|
655
|
+
return v(...vector1.map((coordinate, index) => coordinate + vector2[index]))
|
|
656
|
+
}
|
|
657
|
+
|
|
407
658
|
/**
|
|
408
659
|
* Rotates a 3D vector around the Y-axis using a quaternion.
|
|
409
660
|
* @param {Vector3} vector - The input vector.
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef {import("../../types/math").Vector3} Vector3
|
|
2
|
+
* @typedef {import("../../types/math/vector").Vector3} Vector3
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { clamp, multiply, zero } from "../math/vector.js"
|
|
6
|
-
import { sum } from "../math/vectors.js"
|
|
5
|
+
import { clamp, multiply, sum, zero } from "../math/vector.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
package/src/physics/gravity.js
CHANGED
package/src/physics/jump.js
CHANGED
package/src/physics/velocity.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef {import("../../types/math").Vector3} Vector3
|
|
2
|
+
* @typedef {import("../../types/math/vector").Vector3} Vector3
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { clamp, multiply, zero } from "../math/vector.js"
|
|
6
|
-
import { sum } from "../math/vectors.js"
|
|
5
|
+
import { clamp, multiply, sum, zero } from "../math/vector.js"
|
|
7
6
|
|
|
8
7
|
const DEFAULT_DT = 1 // Default time delta for the applyVelocity function.
|
|
9
8
|
const DEFAULT_MAX_SPEED = 0 // Default maximum speed for velocity clamping.
|
package/src/v.js
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents the input conditions evaluated by a decision tree.
|
|
3
|
+
*/
|
|
4
|
+
export type Conditions = unknown
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Represents the value returned by a decision tree node's test function.
|
|
8
|
+
*/
|
|
9
|
+
export type Outcome = string | boolean
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Represents a node in a decision tree.
|
|
13
|
+
*/
|
|
14
|
+
export interface DecisionTree<C = Conditions> {
|
|
15
|
+
/** Evaluates conditions and returns the key of the branch to follow. */
|
|
16
|
+
test?: (conditions: C) => Outcome
|
|
17
|
+
/** Resolves the branch associated with a test outcome. */
|
|
18
|
+
[outcome: string]: ((conditions: C) => Outcome | DecisionTree<C>) | undefined
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Traverses a decision tree based on the provided conditions.
|
|
23
|
+
*/
|
|
24
|
+
export function decide<C>(
|
|
25
|
+
tree: DecisionTree<C>,
|
|
26
|
+
conditions: NoInfer<C>,
|
|
27
|
+
): Outcome | DecisionTree<C> | undefined
|