@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.
Files changed (69) hide show
  1. package/README.md +67 -3
  2. package/package.json +89 -9
  3. package/src/algorithms/decision-tree.js +3 -3
  4. package/src/algorithms/path-finding.js +6 -6
  5. package/src/data-structures/board.js +97 -15
  6. package/src/data-structures/index.js +2 -2
  7. package/src/data-structures/objects.js +352 -34
  8. package/src/data-structures/string.js +13 -0
  9. package/src/data-structures/tree.js +1 -1
  10. package/src/functions/functions.js +168 -0
  11. package/src/functions/index.js +1 -4
  12. package/src/math/circle.js +5 -7
  13. package/src/math/index.js +0 -4
  14. package/src/math/line.js +3 -3
  15. package/src/math/point.js +10 -9
  16. package/src/math/quaternions.js +20 -4
  17. package/src/math/rectangle.js +4 -4
  18. package/src/math/segment.js +11 -5
  19. package/src/math/vectors.js +471 -65
  20. package/src/physics/acceleration.js +2 -3
  21. package/src/physics/friction.js +2 -2
  22. package/src/physics/gravity.js +2 -2
  23. package/src/physics/jump.js +0 -4
  24. package/src/physics/velocity.js +2 -3
  25. package/src/v.js +1 -1
  26. package/types/algorithms/decision-tree.d.ts +27 -0
  27. package/types/algorithms/index.d.ts +2 -0
  28. package/types/algorithms/path-finding.d.ts +69 -0
  29. package/types/data-structures/array.d.ts +56 -0
  30. package/types/data-structures/board.d.ts +121 -0
  31. package/types/data-structures/boolean.d.ts +4 -0
  32. package/types/data-structures/heap.d.ts +69 -0
  33. package/types/data-structures/index.d.ts +8 -0
  34. package/types/data-structures/objects.d.ts +237 -0
  35. package/types/data-structures/set.d.ts +4 -0
  36. package/types/data-structures/string.d.ts +7 -0
  37. package/types/data-structures/tree.d.ts +21 -0
  38. package/types/functions/functions.d.ts +57 -0
  39. package/types/functions/index.d.ts +1 -0
  40. package/types/index.d.ts +6 -4
  41. package/types/math/circle.d.ts +22 -0
  42. package/types/math/hitmask.d.ts +20 -0
  43. package/types/math/index.d.ts +14 -0
  44. package/types/math/line.d.ts +11 -0
  45. package/types/math/linear-interpolation.d.ts +2 -0
  46. package/types/math/numbers.d.ts +26 -0
  47. package/types/math/point.d.ts +25 -0
  48. package/types/math/quaternions.d.ts +10 -0
  49. package/types/math/rectangle.d.ts +36 -0
  50. package/types/math/rng.d.ts +14 -0
  51. package/types/math/segment.d.ts +23 -0
  52. package/types/math/statistics.d.ts +11 -0
  53. package/types/math/triangle.d.ts +5 -0
  54. package/types/math/trigonometry.d.ts +26 -0
  55. package/types/math/vectors.d.ts +190 -0
  56. package/types/physics/acceleration.d.ts +24 -0
  57. package/types/physics/friction.d.ts +11 -0
  58. package/types/physics/gravity.d.ts +20 -0
  59. package/types/physics/index.d.ts +5 -0
  60. package/types/physics/jump.d.ts +10 -0
  61. package/types/physics/velocity.d.ts +20 -0
  62. package/types/v.d.ts +7 -3
  63. package/src/data-structures/object.js +0 -320
  64. package/src/functions/function.js +0 -9
  65. package/src/math/quaternion.js +0 -22
  66. package/src/math/vector.js +0 -426
  67. package/types/algorithms.d.ts +0 -26
  68. package/types/data-structures.d.ts +0 -53
  69. package/types/math.d.ts +0 -90
@@ -1,426 +0,0 @@
1
- /**
2
- * @typedef {import("../../types/math").Vector} Vector
3
- * @typedef {import("../../types/math").Vector2} Vector2
4
- * @typedef {import("../../types/math").Vector3} Vector3
5
- */
6
-
7
- import { v } from "../v.js"
8
- import {
9
- abs as nAbs,
10
- clamp as nClamp,
11
- mod as nMod,
12
- snap as nSnap,
13
- } from "./numbers.js"
14
- import { quaternion } from "./quaternion.js"
15
- import { hypothenuse } from "./triangle.js"
16
- import { atan2, cos, sin } from "./trigonometry.js"
17
- import { cross, sum } from "./vectors.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
- }
39
-
40
- /**
41
- * Calculates the angle of the vector in radians.
42
- * @param {Vector} vector - The input vector.
43
- * @returns {number} The angle of the vector in the XZ plane (for 3D) or XY plane (for 2D), in radians.
44
- */
45
- export function angle(vector) {
46
- return atan2(vector[vector.length - LAST_COORDINATE], vector[X])
47
- }
48
-
49
- /**
50
- * Clamps the magnitude of the vector between the given min and max values.
51
- * @param {Vector} vector - The input vector.
52
- * @param {number|Vector} min - The minimum magnitude or a vector representing the lower bounds for each component.
53
- * @param {number|Vector} max - The maximum magnitude or a vector representing the upper bounds for each component.
54
- * @returns {Vector} The clamped vector.
55
- */
56
- export function clamp(vector, min, max) {
57
- const length = magnitude(vector)
58
-
59
- if (typeof min === "number" && length < min) {
60
- return setMagnitude(vector, min)
61
- }
62
-
63
- if (typeof max === "number" && length > max) {
64
- return setMagnitude(vector, max)
65
- }
66
-
67
- if (typeof min !== "number" && typeof max !== "number") {
68
- return v(
69
- ...vector.map((coordinate, index) =>
70
- nClamp(coordinate, min[index], max[index]),
71
- ),
72
- )
73
- }
74
-
75
- return vector
76
- }
77
-
78
- /**
79
- * Returns the conjugate of the vector.
80
- * @param {Vector} vector - The input vector.
81
- * @returns {Vector} The conjugated vector.
82
- */
83
- export function conjugate(vector) {
84
- return v(
85
- ...vector.map((coordinate, index) => (index ? -coordinate : coordinate)),
86
- )
87
- }
88
-
89
- /**
90
- * Creates a 3D vector with the given magnitude and angle.
91
- * @param {number} magnitude - The magnitude of the vector.
92
- * @param {number} angle - The angle of the vector in radians.
93
- * @returns {Vector3} The created 3D vector.
94
- */
95
- export function createVector(magnitude, angle) {
96
- return scale(fromAngle(angle), magnitude)
97
- }
98
-
99
- /**
100
- * Divides a scalar by each component of the vector.
101
- * @param {number} scalar - The dividend.
102
- * @param {Vector} vector - The divisor vector.
103
- * @returns {Vector} The resulting vector.
104
- */
105
- export function divideBy(scalar, vector) {
106
- return v(...vector.map((coordinate) => scalar / coordinate))
107
- }
108
-
109
- /**
110
- * Divides each component of the vector by the given scalar.
111
- * @param {Vector} vector - The input vector.
112
- * @param {number} scalar - The scalar value.
113
- * @returns {Vector} The resulting vector.
114
- */
115
- export function divide(vector, scalar) {
116
- return v(...vector.map((coordinate) => coordinate / scalar))
117
- }
118
-
119
- /**
120
- * Converts a 2D vector [x, z] into a 3D vector [x, 0, z].
121
- * @param {Vector2} vector - A 2D vector represented as [x, z].
122
- * @returns {Vector3} A 3D vector represented as [x, 0, z].
123
- */
124
- export function from2D(vector) {
125
- const [x, z] = vector
126
- return v(x, NO_Y, z)
127
- }
128
-
129
- /**
130
- * Creates a 3D unit vector from the given angle in the XZ plane.
131
- * @param {number} angle - The angle in radians.
132
- * @returns {Vector3} The unit vector.
133
- */
134
- export function fromAngle(angle) {
135
- return rotate(UNIT_VECTOR, angle)
136
- }
137
-
138
- /**
139
- * Checks if a value is a vector.
140
- * This is determined by checking for the `__isVector__` property, which is
141
- * added by the `v()` factory function for efficient type checking.
142
- * @param {*} value - The value to check.
143
- * @returns {boolean} True if the value is a vector, false otherwise.
144
- */
145
- export function isVector(value) {
146
- return !!value?.__isVector__
147
- }
148
-
149
- /**
150
- * Calculates the magnitude (length) of the vector.
151
- * @param {Vector} vector - The input vector.
152
- * @returns {number} The magnitude of the vector.
153
- */
154
- export function magnitude(vector) {
155
- return hypothenuse(...vector)
156
- }
157
-
158
- export const length = magnitude
159
-
160
- /**
161
- * Calculates the modulus of each component in the vector with the given divisor.
162
- * @param {Vector} vector - The input vector.
163
- * @param {number} divisor - The divisor value.
164
- * @returns {Vector} The resulting vector.
165
- */
166
- export function mod(vector, divisor) {
167
- return v(...vector.map((coordinate) => nMod(coordinate, divisor)))
168
- }
169
-
170
- /**
171
- * Calculates the modulus of a scalar with each component of the vector.
172
- * @param {number} scalar - The dividend.
173
- * @param {Vector} vector - The divisor vector.
174
- * @returns {Vector} The resulting vector.
175
- */
176
- export function modOf(scalar, vector) {
177
- return v(...vector.map((coordinate) => nMod(scalar, coordinate)))
178
- }
179
-
180
- /**
181
- * Multiplies each component of the vector by the given scalar.
182
- * @param {Vector} vector - The input vector.
183
- * @param {number} scalar - The scalar value.
184
- * @returns {Vector} The resulting vector.
185
- */
186
- export function multiply(vector, scalar) {
187
- return v(...vector.map((coordinate) => coordinate * scalar))
188
- }
189
-
190
- /**
191
- * Alias for the power function.
192
- * @type {typeof power}
193
- */
194
- export const pow = power
195
-
196
- /**
197
- * Raises each component of the vector to the given exponent.
198
- * @param {Vector} vector - The input vector.
199
- * @param {number} exponent - The exponent value.
200
- * @returns {Vector} The resulting vector.
201
- */
202
- export function power(vector, exponent) {
203
- return v(...vector.map((coordinate) => coordinate ** exponent))
204
- }
205
-
206
- /**
207
- * Raises a scalar to the power of each component of the vector.
208
- * @param {number} scalar - The base value.
209
- * @param {Vector} vector - The exponent vector.
210
- * @returns {Vector} The resulting vector.
211
- */
212
- export function powerOf(scalar, vector) {
213
- return v(...vector.map((coordinate) => scalar ** coordinate))
214
- }
215
-
216
- /**
217
- * Normalizes the vector to have a magnitude of 1.
218
- * @param {Vector} vector - The input vector.
219
- * @returns {Vector} The normalized vector.
220
- */
221
- export function normalize(vector) {
222
- const length = magnitude(vector)
223
- return v(...vector.map((coordinate) => coordinate / length))
224
- }
225
-
226
- /**
227
- * Alias for the mod function.
228
- * @type {typeof mod}
229
- */
230
- export const remainder = mod
231
-
232
- /**
233
- * Rotates the vector by the given angle. Handles 2D and 3D vectors.
234
- * For 3D vectors, rotation is around the Y-axis.
235
- * @param {Vector} vector - The input vector (2D or 3D).
236
- * @param {number} angle - The angle in radians.
237
- * @returns {Vector} The rotated vector.
238
- */
239
- export function rotate(vector, angle) {
240
- const is2D = vector.length === TWO_COORDINATES
241
-
242
- const vector3 = is2D ? from2D(vector) : vector
243
-
244
- const result = rotateWithQuaternion(vector3, angle)
245
-
246
- return is2D ? to2D(result) : result
247
- }
248
-
249
- /**
250
- * Alias for the multiply function.
251
- * @type {typeof multiply}
252
- */
253
- export const scale = multiply
254
-
255
- /**
256
- * Sets the angle of the vector in the XZ plane while maintaining its magnitude.
257
- * @param {Vector} vector - The input vector.
258
- * @param {number} angle - The new angle in radians.
259
- * @returns {Vector3} The vector with the updated angle.
260
- */
261
- export function setAngle(vector, angle) {
262
- const length = magnitude(vector)
263
- const [x, z] = toCartesian([length, angle])
264
- return v(x, NO_Y, z)
265
- }
266
-
267
- /**
268
- * Alias for the setMagnitude function.
269
- * @type {typeof setMagnitude}
270
- */
271
- export const setLength = setMagnitude
272
-
273
- /**
274
- * Sets the magnitude of the vector while maintaining its direction.
275
- * @param {Vector} vector - The input vector.
276
- * @param {number} length - The new magnitude.
277
- * @returns {Vector} The vector with the updated magnitude.
278
- */
279
- export function setMagnitude(vector, length) {
280
- const normalized = normalize(vector)
281
- return scale(normalized, length)
282
- }
283
-
284
- /**
285
- * Shifts the components of the vector by the given index.
286
- * @param {Vector} vector - The input vector.
287
- * @param {number} index - The index to shift by.
288
- * @returns {Vector} The shifted vector.
289
- */
290
- export function shift(vector, index) {
291
- return v(...vector.slice(index), ...vector.slice(X, index))
292
- }
293
-
294
- /**
295
- * Snaps each component of the vector to the nearest multiple of the given precision.
296
- * @param {Vector} vector - The input vector.
297
- * @param {number} [precision=DEFAULT_PRECISION] - The precision value.
298
- * @returns {Vector} The snapped vector.
299
- */
300
- export function snap(vector, precision = DEFAULT_PRECISION) {
301
- return v(
302
- ...vector.map((coordinate) => nSnap(coordinate, -precision, precision)),
303
- )
304
- }
305
-
306
- /**
307
- * Alias for the multiply function.
308
- * @type {typeof multiply}
309
- */
310
- export const times = multiply
311
-
312
- /**
313
- * Converts a 3D vector [x, y, z] into a 2D vector [x, z].
314
- * @param {Vector3} vector - A 3D vector represented as [x, y, z].
315
- * @returns {Vector2} A 2D vector represented as [x, z].
316
- */
317
- export function to2D(vector) {
318
- const [x, , z] = vector
319
- return v(x, z)
320
- }
321
-
322
- /**
323
- * Converts 2D polar coordinates to 2D Cartesian coordinates.
324
- * @param {Vector2} vector - The polar coordinates [magnitude, angle].
325
- * @returns {Vector2} The Cartesian coordinates [x, y].
326
- */
327
- export function toCartesian([magnitude, angle]) {
328
- return v(magnitude * cos(angle), magnitude * sin(angle))
329
- }
330
-
331
- /**
332
- * Converts a 3D cartesian vector to cylindrical coordinates.
333
- * @param {Vector3} vector - The input vector [x, y, z].
334
- * @returns {Vector3} The cylindrical coordinates [radius, theta, z].
335
- */
336
- export function toCylindrical(vector) {
337
- const radius = magnitude(vector)
338
- const theta = angle(vector)
339
- return v(radius * cos(theta), radius * sin(theta), vector[Z])
340
- }
341
-
342
- /**
343
- * Converts a 2D cartesian vector to 2D polar coordinates.
344
- * @param {Vector2} vector - The input vector [x, y].
345
- * @returns {Vector2} The polar coordinates [magnitude, angle].
346
- */
347
- export function toPolar(vector) {
348
- return v(magnitude(vector), angle(vector))
349
- }
350
-
351
- /**
352
- * Converts a vector to a string representation.
353
- * @param {Vector} vector - The input vector.
354
- * @param {number} [decimals=DEFAULT_DECIMALS] - The number of decimal places.
355
- * @returns {string} The string representation of the vector.
356
- */
357
- export function toString(vector, decimals = DEFAULT_DECIMALS) {
358
- return `[${vector
359
- .map((coordinate) => coordinate.toFixed(decimals))
360
- .join(", ")}]`
361
- }
362
-
363
- /**
364
- * Converts a 3D cartesian vector to spherical coordinates [radius, inclination, azimuth].
365
- * - radius (r): distance from the origin.
366
- * - inclination (θ): angle from the Y-axis (0 to PI).
367
- * - azimuth (φ): angle from the X-axis in the XZ-plane (-PI to PI).
368
- * @param {Vector3} vector The cartesian vector [x, y, z].
369
- * @returns {Vector3} The spherical coordinates [r, θ, φ].
370
- */
371
- export function toSpherical(vector) {
372
- const r = magnitude(vector)
373
-
374
- if (!r) {
375
- return zero()
376
- }
377
-
378
- // In a Y-up system, inclination is the angle with the Y axis.
379
- const inclination = Math.acos(vector[Y] / r)
380
- // Azimuth is the angle in the XZ plane, which `angle()` calculates.
381
- const azimuth = angle(vector)
382
-
383
- return v(r, inclination, azimuth)
384
- }
385
-
386
- /**
387
- * Creates a 3D unit vector in the XZ plane with the given angle.
388
- * @param {number} [angle=0] - The angle in radians.
389
- * @returns {Vector3} The unit vector.
390
- */
391
- export function unit(angle) {
392
- if (!angle) {
393
- return v(...UNIT_VECTOR)
394
- }
395
-
396
- return setAngle(UNIT_VECTOR, angle)
397
- }
398
-
399
- /**
400
- * Creates a zero vector of 3 dimensions.
401
- * @returns {Vector3} The zero vector.
402
- */
403
- export function zero() {
404
- return v(...ZERO_VECTOR)
405
- }
406
-
407
- /**
408
- * Rotates a 3D vector around the Y-axis using a quaternion.
409
- * @param {Vector3} vector - The input vector.
410
- * @param {number} angle - The angle in radians.
411
- * @returns {Vector3} The rotated vector.
412
- */
413
- function rotateWithQuaternion(vector, angle) {
414
- if (!angle) {
415
- return vector
416
- }
417
-
418
- // @see https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation#Performance_comparisons
419
- const [w, ...r] = quaternion(angle)
420
- const result = sum(
421
- vector,
422
- cross(scale(r, 2), sum(cross(r, vector), scale(vector, w))), // eslint-disable-line no-magic-numbers
423
- )
424
-
425
- return conjugate(result) // HACK: not really sure why I should invert the result, it just works this way
426
- }
@@ -1,26 +0,0 @@
1
- /**
2
- * Represents the input conditions to be evaluated by a decision tree node.
3
- * The `unknown` type is used to allow for flexible condition structures.
4
- */
5
- export type Conditions = unknown
6
-
7
- /**
8
- * Represents the result of a decision tree's `test` function, which is used
9
- * as a key to determine the next branch.
10
- */
11
- export type Outcome = string
12
-
13
- /**
14
- * Represents a node in a decision tree. It consists of:
15
- * - A `test` function that evaluates conditions and returns an outcome.
16
- * - A map of outcomes to subsequent actions, which can be either a final outcome
17
- * or another `DecisionTree` node.
18
- */
19
- export type DecisionTree = {
20
- /**
21
- * A function that takes a set of conditions and returns an outcome string.
22
- * @param conditions - The conditions to evaluate.
23
- * @returns The outcome of the test.
24
- */
25
- test: (conditions: Conditions) => Outcome
26
- } & Record<Outcome, () => Outcome | DecisionTree>
@@ -1,53 +0,0 @@
1
- /**
2
- * Represents a generic tree data structure.
3
- * Each node in the tree has a value and an array of child nodes.
4
- * @template T - The type of the value stored in the tree nodes. Defaults to `any`.
5
- */
6
- export interface Tree<T = any> {
7
- /** The value of the current node. */
8
- value: T
9
- /** An array of child `Tree` nodes. */
10
- children: Tree<T>[]
11
- }
12
-
13
- /**
14
- * A map where keys are node identifiers and values are their [x, y] coordinates.
15
- * Used for efficient node lookups by ID.
16
- */
17
- export interface NodeMap {
18
- [id: string]: [number, number] // [x, y]
19
- }
20
-
21
- /**
22
- * Represents a node in a graph.
23
- */
24
- export interface Node {
25
- /** A unique identifier for the node. */
26
- id: string
27
- /** The [x, y] coordinates of the node. */
28
- position: [number, number] // [x, y]
29
- /** An optional cost associated with traversing to this node. */
30
- cost?: number
31
- }
32
-
33
- /**
34
- * Represents a directed edge (or arc) between two nodes in a graph.
35
- */
36
- export interface Arc {
37
- /** The ID of the starting node. */
38
- from: string
39
- /** The ID of the ending node. */
40
- to: string
41
- /** An optional cost associated with traversing this arc. */
42
- cost?: number
43
- }
44
-
45
- /**
46
- * Represents a graph structure consisting of nodes and arcs.
47
- */
48
- export interface Graph {
49
- /** The nodes of the graph, as either an array or a map for efficient lookups. */
50
- nodes: NodeMap | Node[]
51
- /** An array of arcs connecting the nodes. */
52
- arcs: Arc[]
53
- }
package/types/math.d.ts DELETED
@@ -1,90 +0,0 @@
1
- // geometry
2
-
3
- /**
4
- * Represents a point in 3D space using a readonly tuple of numbers.
5
- * @public
6
- */
7
- export type Point = readonly [number, number, number] // [x, y, z]
8
-
9
- /**
10
- * Represents the dimensions of an object in 3D space.
11
- * @public
12
- */
13
- export type Size = readonly [number, number, number] // [width, height, depth]
14
-
15
- /**
16
- * Represents a line in 2D space in the form `ax + by + c = 0`.
17
- * @public
18
- */
19
- export type Line = readonly [number, number, number] // [a, b, c]
20
-
21
- /**
22
- * Represents a circle with a position and radius.
23
- * @public
24
- */
25
- export interface Circle {
26
- /** The center point of the circle. */
27
- position: Point
28
- /** The radius of the circle. */
29
- radius: number
30
- }
31
-
32
- /**
33
- * Represents a rectangle with a position and size.
34
- * @public
35
- */
36
- export interface Rectangle {
37
- /** The top-left corner point of the rectangle. */
38
- position: Point
39
- /** The dimensions of the rectangle. */
40
- size: Size
41
- }
42
-
43
- /**
44
- * Represents a platform, typically for physics or collision detection.
45
- * @public
46
- */
47
- export interface Platform {
48
- /** The position of the platform. */
49
- position: Point
50
- /** The dimensions of the platform. */
51
- size: Size
52
- }
53
-
54
- /**
55
- * Represents a line segment defined by two points.
56
- * @public
57
- */
58
- export interface Segment {
59
- /** The starting point of the segment. */
60
- from: Point
61
- /** The ending point of the segment. */
62
- to: Point
63
- }
64
-
65
- // linear algebra
66
-
67
- /**
68
- * A nominal type brand to identify vector types.
69
- * This prevents accidental assignment of a plain number array to a vector.
70
- * @internal
71
- */
72
- type IsVector = {
73
- readonly __isVector__: true
74
- }
75
-
76
- /** A generic, dynamically-sized vector. */
77
- export type Vector = IsVector & readonly number[]
78
-
79
- /** A 2-dimensional vector. */
80
- export type Vector2 = IsVector & readonly [number, number]
81
-
82
- /** A 3-dimensional vector. */
83
- export type Vector3 = IsVector & readonly [number, number, number]
84
-
85
- /** A 4-dimensional vector, often used for quaternions. */
86
- export type Quaternion = IsVector & readonly [number, number, number, number]
87
-
88
- /** A 7-dimensional vector. */
89
- export type Vector7 = IsVector &
90
- readonly [number, number, number, number, number, number, number]