@inglorious/utils 2.3.0 → 3.1.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 (45) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/algorithms/decision-tree.test.js +7 -6
  4. package/src/algorithms/index.js +4 -0
  5. package/src/algorithms/path-finding.js +2 -2
  6. package/src/data-structures/index.js +10 -0
  7. package/src/functions/index.js +4 -0
  8. package/src/index.js +8 -0
  9. package/src/math/{geometry/circle.js → circle.js} +6 -6
  10. package/src/math/{geometry/circle.test.js → circle.test.js} +23 -22
  11. package/src/math/{geometry/hitmask.test.js → hitmask.test.js} +16 -15
  12. package/src/math/index.js +35 -0
  13. package/src/math/{geometry/line.js → line.js} +4 -6
  14. package/src/math/{geometry/line.test.js → line.test.js} +11 -10
  15. package/src/math/linear-interpolation.js +0 -1
  16. package/src/math/{geometry/point.js → point.js} +5 -5
  17. package/src/math/{geometry/point.test.js → point.test.js} +23 -22
  18. package/src/math/{linear-algebra/quaternion.js → quaternion.js} +4 -4
  19. package/src/math/{linear-algebra/quaternion.test.js → quaternion.test.js} +1 -1
  20. package/src/math/{linear-algebra/quaternions.js → quaternions.js} +7 -4
  21. package/src/math/{linear-algebra/quaternions.test.js → quaternions.test.js} +1 -1
  22. package/src/math/{geometry/rectangle.js → rectangle.js} +3 -5
  23. package/src/math/{geometry/rectangle.test.js → rectangle.test.js} +13 -12
  24. package/src/math/rng.js +0 -2
  25. package/src/math/{geometry/segment.js → segment.js} +5 -9
  26. package/src/math/{geometry/segment.test.js → segment.test.js} +48 -47
  27. package/src/math/{geometry/triangle.js → triangle.js} +1 -1
  28. package/src/math/{geometry/types.d.ts → types.d.ts} +10 -0
  29. package/src/math/{linear-algebra/vector.js → vector.js} +73 -80
  30. package/src/math/{linear-algebra/vector.test.js → vector.test.js} +73 -63
  31. package/src/math/{linear-algebra/vectors.js → vectors.js} +18 -13
  32. package/src/math/{linear-algebra/vectors.test.js → vectors.test.js} +12 -30
  33. package/src/physics/acceleration.js +5 -5
  34. package/src/physics/friction.js +2 -3
  35. package/src/physics/friction.test.js +7 -6
  36. package/src/physics/gravity.js +2 -2
  37. package/src/physics/gravity.test.js +10 -9
  38. package/src/physics/index.js +7 -0
  39. package/src/physics/jump.js +1 -2
  40. package/src/physics/velocity.js +3 -4
  41. package/src/v.js +17 -0
  42. package/src/v.test.js +13 -0
  43. package/src/math/linear-algebra/types.d.ts +0 -5
  44. /package/src/math/{geometry/hitmask.js → hitmask.js} +0 -0
  45. /package/src/math/{geometry/triangle.test.js → triangle.test.js} +0 -0
@@ -1,8 +1,8 @@
1
1
  import { expect, test } from "vitest"
2
2
 
3
- import { cos, pi, sin } from "../trigonometry.js"
4
3
  import { quaternion } from "./quaternion.js"
5
4
  import { combine } from "./quaternions.js"
5
+ import { cos, pi, sin } from "./trigonometry.js"
6
6
 
7
7
  test("it should combine two zero-angle quaternions by giving the same 0-angle quaternion", () => {
8
8
  const q1 = quaternion(0)
@@ -1,7 +1,7 @@
1
1
  /**
2
- * @typedef {import("./types").Circle} Circle
3
- * @typedef {import("./types").Rectangle} Rectangle
4
- * @typedef {import("./types").Platform} Platform
2
+ * @typedef {import("./geometry/types.js").Circle} Circle
3
+ * @typedef {import("./geometry/types.js").Rectangle} Rectangle
4
+ * @typedef {import("./geometry/types.js").Platform} Platform
5
5
  */
6
6
 
7
7
  import { intersectsRectangle as circleIntersectsRectangle } from "./circle.js"
@@ -21,7 +21,6 @@ export function intersectsPoint(rectangle, point) {
21
21
 
22
22
  /**
23
23
  * Checks if a rectangle intersects with a circle.
24
- *
25
24
  * @param {Rectangle} rectangle - The rectangle to check.
26
25
  * @param {Circle} circle - The circle to check.
27
26
  * @returns {boolean} True if the rectangle intersects the circle, false otherwise.
@@ -32,7 +31,6 @@ export function intersectsCircle(rectangle, circle) {
32
31
 
33
32
  /**
34
33
  * Determines whether a rectangle intersects another in 3D space.
35
- *
36
34
  * @param {Rectangle} rectangle1 - The first rectangle, defined by its position (x, y, z) and size (width, height, depth).
37
35
  * @param {Rectangle} rectangle2 - The second rectangle, defined by its position (x, y, z) and size (width, height, depth).
38
36
  * @returns {boolean} True if the two rectangles intersect, false otherwise.
@@ -1,15 +1,16 @@
1
1
  import { expect, test } from "vitest"
2
2
 
3
+ import { v } from "../v.js"
3
4
  import { intersectsRectangle } from "./rectangle.js"
4
5
 
5
6
  test("it should prove that a rectangle crossing another one intersects with it", () => {
6
7
  const rectangle1 = {
7
- position: [0, 0, 0],
8
- size: [2, 2, 2],
8
+ position: v(0, 0, 0),
9
+ size: v(2, 2, 2),
9
10
  }
10
11
  const rectangle2 = {
11
- position: [1, 1, 1],
12
- size: [2, 2, 2],
12
+ position: v(1, 1, 1),
13
+ size: v(2, 2, 2),
13
14
  }
14
15
 
15
16
  expect(intersectsRectangle(rectangle1, rectangle2)).toBe(true)
@@ -17,12 +18,12 @@ test("it should prove that a rectangle crossing another one intersects with it",
17
18
 
18
19
  test("it should prove that a rectangle right on top of another intersects with it", () => {
19
20
  const rectangle1 = {
20
- position: [0, 0, 0],
21
- size: [2, 2, 2],
21
+ position: v(0, 0, 0),
22
+ size: v(2, 2, 2),
22
23
  }
23
24
  const rectangle2 = {
24
- position: [0, 0, 0],
25
- size: [2, 0, 2],
25
+ position: v(0, 0, 0),
26
+ size: v(2, 0, 2),
26
27
  }
27
28
 
28
29
  expect(intersectsRectangle(rectangle1, rectangle2)).toBe(true)
@@ -30,12 +31,12 @@ test("it should prove that a rectangle right on top of another intersects with i
30
31
 
31
32
  test("it should prove that a rectangle not crossing another one does not intersect with it", () => {
32
33
  const rectangle1 = {
33
- position: [0, 0, 0],
34
- size: [2, 2, 2],
34
+ position: v(0, 0, 0),
35
+ size: v(2, 2, 2),
35
36
  }
36
37
  const rectangle2 = {
37
- position: [3, 3, 3],
38
- size: [2, 2, 2],
38
+ position: v(3, 3, 3),
39
+ size: v(2, 2, 2),
39
40
  }
40
41
 
41
42
  expect(intersectsRectangle(rectangle1, rectangle2)).toBe(false)
package/src/math/rng.js CHANGED
@@ -5,7 +5,6 @@
5
5
  * - If no arguments are provided, returns a random float between 0 (inclusive) and 1 (exclusive).
6
6
  * - If one argument is provided, returns a random integer between 0 and the given number (inclusive).
7
7
  * - If two or more arguments are provided, returns a random integer within the specified range and step.
8
- *
9
8
  * @param {number} [to] - The upper bound (inclusive) if one argument is provided.
10
9
  * @param {number} [from] - The lower bound (inclusive) if two arguments are provided.
11
10
  * @param {number} [step=1] - The step size if two or more arguments are provided.
@@ -36,7 +35,6 @@ export function random(...args) {
36
35
  /**
37
36
  * Generates a random binomial value.
38
37
  * The result is the difference between two random numbers.
39
- *
40
38
  * @returns {number} A random binomial value.
41
39
  */
42
40
  export function randomBinomial() {
@@ -1,18 +1,17 @@
1
1
  /**
2
- * @typedef {import("./types").Segment} Segment
3
- * @typedef {import("./types").Point} Point
4
- * @typedef {import("./types").Circle} Circle
2
+ * @typedef {import("./geometry/types.js").Segment} Segment
3
+ * @typedef {import("./geometry/types.js").Point} Point
4
+ * @typedef {import("./geometry/types.js").Circle} Circle
5
5
  */
6
6
 
7
- import { magnitude, setMagnitude } from "../linear-algebra/vector.js"
8
- import { distance, dot, subtract, sum } from "../linear-algebra/vectors.js"
7
+ import { magnitude, setMagnitude } from "./vector.js"
8
+ import { distance, dot, subtract, sum } from "./vectors.js"
9
9
 
10
10
  const BEFORE_SEGMENT = 0
11
11
 
12
12
  /**
13
13
  * Calculates the coefficients [a, b, c] of the line equation ax + bz + c = 0
14
14
  * for a given segment in 2D space.
15
- *
16
15
  * @param {Segment} segment - The segment defined by its start (`from`) and end (`to`) points.
17
16
  * @returns {[number, number, number]} An array [a, b, c] representing the line equation.
18
17
  */
@@ -24,7 +23,6 @@ export function coefficients(segment) {
24
23
 
25
24
  /**
26
25
  * Finds the closest point on a segment to a given point in 3D space.
27
- *
28
26
  * @param {Segment} segment - The segment defined by its start (`from`) and end (`to`) points.
29
27
  * @param {Point} point - The point in 3D space represented as [x, y, z].
30
28
  * @returns {Point} The closest point on the segment to the given point.
@@ -50,7 +48,6 @@ export function closestPoint(segment, point) {
50
48
 
51
49
  /**
52
50
  * Calculates the shortest distance from a point to a segment in 3D space.
53
- *
54
51
  * @param {Segment} segment - The segment defined by its start (`from`) and end (`to`) points.
55
52
  * @param {Point} point - The point in 3D space represented as [x, y, z].
56
53
  * @returns {number} The shortest distance from the point to the segment.
@@ -62,7 +59,6 @@ export function distanceFromPoint(segment, point) {
62
59
 
63
60
  /**
64
61
  * Determines whether a segment intersects with the perimeter of a circle.
65
- *
66
62
  * @param {Segment} segment - The segment defined by its start (`from`) and end (`to`) points.
67
63
  * @param {Circle} circle - The circle defined by its position (center) and radius.
68
64
  * @returns {boolean} `true` if the segment intersects the circle's perimeter, otherwise `false`.
@@ -1,6 +1,7 @@
1
1
  import { expect, test } from "vitest"
2
2
 
3
- import { isClose } from "../numbers.js"
3
+ import { v } from "../v.js"
4
+ import { isClose } from "./numbers.js"
4
5
  import {
5
6
  closestPoint,
6
7
  coefficients,
@@ -21,64 +22,64 @@ expect.extend({
21
22
 
22
23
  test("it should retrieve values of *a*, *b*, and *c* from a segment, so it looks like a line in the form *ax + by + c = 0*", () => {
23
24
  const segment = {
24
- from: [0, 0, 0],
25
- to: [1, 0, 2],
25
+ from: v(0, 0, 0),
26
+ to: v(1, 0, 2),
26
27
  }
27
- const expectedResult = [-2, 1, 0]
28
+ const expectedResult = v(-2, 1, 0)
28
29
 
29
30
  expect(coefficients(segment)).toStrictEqual(expectedResult)
30
31
  })
31
32
 
32
33
  test("it should find the closest point in a segment to a point projectable on it", () => {
33
34
  const segment = {
34
- from: [0, 0, 0],
35
- to: [2, 0, 2],
35
+ from: v(0, 0, 0),
36
+ to: v(2, 0, 2),
36
37
  }
37
- const point = [2, 0, 0]
38
- const expectedResult = [1, 0, 1]
38
+ const point = v(2, 0, 0)
39
+ const expectedResult = v(1, 0, 1)
39
40
 
40
41
  expect(closestPoint(segment, point)).toStrictEqualVector(expectedResult)
41
42
  })
42
43
 
43
44
  test("it should find the closest point as the point itself when resting on the segment", () => {
44
45
  const segment = {
45
- from: [0, 0, 0],
46
- to: [2, 0, 2],
46
+ from: v(0, 0, 0),
47
+ to: v(2, 0, 2),
47
48
  }
48
- const point = [1, 0, 1]
49
- const expectedResult = [1, 0, 1]
49
+ const point = v(1, 0, 1)
50
+ const expectedResult = v(1, 0, 1)
50
51
 
51
52
  expect(closestPoint(segment, point)).toStrictEqualVector(expectedResult)
52
53
  })
53
54
 
54
55
  test("it return the start of a segment when the point is close to its start", () => {
55
56
  const segment = {
56
- from: [0, 0, 0],
57
- to: [3, 0, 4],
57
+ from: v(0, 0, 0),
58
+ to: v(3, 0, 4),
58
59
  }
59
- const point = [-2, 0, 0]
60
- const expectedResult = [0, 0, 0]
60
+ const point = v(-2, 0, 0)
61
+ const expectedResult = v(0, 0, 0)
61
62
 
62
63
  expect(closestPoint(segment, point)).toStrictEqualVector(expectedResult)
63
64
  })
64
65
 
65
66
  test("it should return the end of a segment when the point is close to its end", () => {
66
67
  const segment = {
67
- from: [0, 0, 0],
68
- to: [3, 0, 4],
68
+ from: v(0, 0, 0),
69
+ to: v(3, 0, 4),
69
70
  }
70
- const point = [5, 0, 4]
71
- const expectedResult = [3, 0, 4]
71
+ const point = v(5, 0, 4)
72
+ const expectedResult = v(3, 0, 4)
72
73
 
73
74
  expect(closestPoint(segment, point)).toStrictEqualVector(expectedResult)
74
75
  })
75
76
 
76
77
  test("it should compute the distance between a segment and a point projectable on it", () => {
77
78
  const segment = {
78
- from: [0, 0, 0],
79
- to: [3, 0, 4],
79
+ from: v(0, 0, 0),
80
+ to: v(3, 0, 4),
80
81
  }
81
- const point = [5, 0, 0]
82
+ const point = v(5, 0, 0)
82
83
  const expectedResult = 4
83
84
 
84
85
  expect(distanceFromPoint(segment, point)).toBe(expectedResult)
@@ -86,10 +87,10 @@ test("it should compute the distance between a segment and a point projectable o
86
87
 
87
88
  test("it should compute the distance between a segment and a point resting on it", () => {
88
89
  const segment = {
89
- from: [0, 0, 0],
90
- to: [2, 0, 2],
90
+ from: v(0, 0, 0),
91
+ to: v(2, 0, 2),
91
92
  }
92
- const point = [1, 0, 1]
93
+ const point = v(1, 0, 1)
93
94
  const expectedResult = 0
94
95
 
95
96
  expect(distanceFromPoint(segment, point)).toBeCloseTo(expectedResult)
@@ -97,10 +98,10 @@ test("it should compute the distance between a segment and a point resting on it
97
98
 
98
99
  test("it should compute the distance between a segment and a point close to the start", () => {
99
100
  const segment = {
100
- from: [0, 0, 0],
101
- to: [3, 0, 4],
101
+ from: v(0, 0, 0),
102
+ to: v(3, 0, 4),
102
103
  }
103
- const point = [-2, 0, 0]
104
+ const point = v(-2, 0, 0)
104
105
  const expectedResult = 2
105
106
 
106
107
  expect(distanceFromPoint(segment, point)).toBe(expectedResult)
@@ -108,10 +109,10 @@ test("it should compute the distance between a segment and a point close to the
108
109
 
109
110
  test("it should compute the distance between a segment and a point close to the end", () => {
110
111
  const segment = {
111
- from: [0, 0, 0],
112
- to: [3, 0, 4],
112
+ from: v(0, 0, 0),
113
+ to: v(3, 0, 4),
113
114
  }
114
- const point = [5, 0, 4]
115
+ const point = v(5, 0, 4)
115
116
  const expectedResult = 2
116
117
 
117
118
  expect(distanceFromPoint(segment, point)).toBeCloseTo(expectedResult)
@@ -119,11 +120,11 @@ test("it should compute the distance between a segment and a point close to the
119
120
 
120
121
  test("it should prove that a segment that crosses a circle intersects with it", () => {
121
122
  const segment = {
122
- from: [0, 0, 0],
123
- to: [2, 0, 2],
123
+ from: v(0, 0, 0),
124
+ to: v(2, 0, 2),
124
125
  }
125
126
  const circle = {
126
- position: [1, 0, 1],
127
+ position: v(1, 0, 1),
127
128
  radius: 1,
128
129
  }
129
130
 
@@ -132,11 +133,11 @@ test("it should prove that a segment that crosses a circle intersects with it",
132
133
 
133
134
  test("it should prove that a segment tangent to a circle intersects with it", () => {
134
135
  const segment = {
135
- from: [0, 0, 0],
136
- to: [0, 0, 2],
136
+ from: v(0, 0, 0),
137
+ to: v(0, 0, 2),
137
138
  }
138
139
  const circle = {
139
- position: [1, 0, 1],
140
+ position: v(1, 0, 1),
140
141
  radius: 1,
141
142
  }
142
143
 
@@ -145,11 +146,11 @@ test("it should prove that a segment tangent to a circle intersects with it", ()
145
146
 
146
147
  test("it should prove that a segment inside of a circle intersects with it", () => {
147
148
  const segment = {
148
- from: [0.5, 0, 0.5],
149
- to: [1.5, 0, 1.5],
149
+ from: v(0.5, 0, 0.5),
150
+ to: v(1.5, 0, 1.5),
150
151
  }
151
152
  const circle = {
152
- position: [1, 0, 1],
153
+ position: v(1, 0, 1),
153
154
  radius: 1,
154
155
  }
155
156
 
@@ -158,11 +159,11 @@ test("it should prove that a segment inside of a circle intersects with it", ()
158
159
 
159
160
  test("it should prove that a segment that does not cross a circle does not intersect with it", () => {
160
161
  const segment = {
161
- from: [0, 0, 0],
162
- to: [-2, 0, 2],
162
+ from: v(0, 0, 0),
163
+ to: v(-2, 0, 2),
163
164
  }
164
165
  const circle = {
165
- position: [1, 0, 1],
166
+ position: v(1, 0, 1),
166
167
  radius: 1,
167
168
  }
168
169
 
@@ -171,11 +172,11 @@ test("it should prove that a segment that does not cross a circle does not inter
171
172
 
172
173
  test("it should prove that a segment that reaches outside of a circle does not intersect with it", () => {
173
174
  const segment = {
174
- from: [0, 0, 0],
175
- to: [-1, 0, -2],
175
+ from: v(0, 0, 0),
176
+ to: v(-1, 0, -2),
176
177
  }
177
178
  const circle = {
178
- position: [1, 0, 1],
179
+ position: v(1, 0, 1),
179
180
  radius: 1,
180
181
  }
181
182
 
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * Calculates the length of the hypothenuse (or magnitude) for a given set of numbers
3
3
  * using the Pythagorean theorem.
4
- *
5
4
  * @param {number[]} nums - A list of numbers representing the sides of a right triangle.
6
5
  * @returns {number} The length of the hypothenuse.
7
6
  */
@@ -11,5 +10,6 @@ export function hypothenuse(...nums) {
11
10
 
12
11
  /**
13
12
  * Alias for the `hypothenuse` function.
13
+ * @type {typeof hypothenuse}
14
14
  */
15
15
  export const pythagoras = hypothenuse
@@ -1,3 +1,5 @@
1
+ // geometry
2
+
1
3
  export type Point = [number, number, number] // [x, y, z]
2
4
  export type Size = [number, number, number] // [width, height, depth]
3
5
  export type Line = [number, number, number] // [a, b, c]
@@ -21,3 +23,11 @@ export interface Segment {
21
23
  from: Point
22
24
  to: Point
23
25
  }
26
+
27
+ // linear algebra
28
+
29
+ export type Vector = number[]
30
+ export type Vector2 = [number, number]
31
+ export type Vector3 = [number, number, number]
32
+ export type Quaternion = [number, number, number, number]
33
+ export type Vector7 = [number, number, number, number, number, number, number]