@inglorious/utils 2.1.0 → 2.3.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/package.json +1 -1
- package/src/data-structures/array.js +6 -6
- package/src/data-structures/object.js +3 -3
- package/src/math/geometry/point.js +13 -4
- package/src/math/geometry/point.test.js +12 -0
- package/src/math/linear-algebra/types.d.ts +1 -0
- package/src/math/linear-algebra/vector.js +119 -48
- package/src/math/linear-algebra/vector.test.js +44 -0
- package/src/math/linear-algebra/2d.js +0 -28
- package/src/math/linear-algebra/2d.test.js +0 -17
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inglorious/utils",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "A set of general-purpose utility functions designed with functional programming principles in mind.",
|
|
5
5
|
"author": "IceOnFire <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,21 +25,21 @@ export function contains(arr, item) {
|
|
|
25
25
|
/**
|
|
26
26
|
* Ensures that the given value is an array. If it's not an array, it wraps it in one.
|
|
27
27
|
*
|
|
28
|
-
* @param {*}
|
|
28
|
+
* @param {*} value - The value to check.
|
|
29
29
|
* @returns {Array} - The original array or the value wrapped in a new array.
|
|
30
30
|
*/
|
|
31
|
-
export function ensureArray(
|
|
32
|
-
return isArray(
|
|
31
|
+
export function ensureArray(value) {
|
|
32
|
+
return isArray(value) ? value : [value]
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* Checks if a value is an array.
|
|
37
|
-
* @param {*} arr - The value to check.
|
|
38
37
|
*
|
|
38
|
+
* @param {*} value - The value to check.
|
|
39
39
|
* @returns {boolean} True if the value is an array, false otherwise.
|
|
40
40
|
*/
|
|
41
|
-
export function isArray(
|
|
42
|
-
return Array.isArray(
|
|
41
|
+
export function isArray(value) {
|
|
42
|
+
return Array.isArray(value)
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/**
|
|
@@ -44,11 +44,11 @@ export function find(obj, callback) {
|
|
|
44
44
|
/**
|
|
45
45
|
* Checks if a value is a plain object.
|
|
46
46
|
*
|
|
47
|
-
* @param {*}
|
|
47
|
+
* @param {*} value - The value to check.
|
|
48
48
|
* @returns {boolean} True if the value is a plain object, false otherwise.
|
|
49
49
|
*/
|
|
50
|
-
export function isObject(
|
|
51
|
-
return
|
|
50
|
+
export function isObject(value) {
|
|
51
|
+
return value != null && value.constructor === Object
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/**
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
const SQUARED = 2
|
|
9
9
|
const HALF = 2
|
|
10
10
|
|
|
11
|
+
import { isVector } from "../linear-algebra/vector.js"
|
|
11
12
|
import { distanceFromPoint } from "./line.js"
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -27,8 +28,8 @@ export function getDistanceFromLine(point, line) {
|
|
|
27
28
|
* @returns {boolean} True if the points intersect, false otherwise.
|
|
28
29
|
*/
|
|
29
30
|
export function intersectsPoint(point1, point2) {
|
|
30
|
-
const [x1, y1, z1] = point1
|
|
31
|
-
const [x2, y2, z2] = point2
|
|
31
|
+
const [x1, y1, z1] = ensurePoint(point1)
|
|
32
|
+
const [x2, y2, z2] = ensurePoint(point2)
|
|
32
33
|
return x1 === x2 && y1 === y2 && z1 === z2
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -39,7 +40,7 @@ export function intersectsPoint(point1, point2) {
|
|
|
39
40
|
* @returns {boolean} True if the point intersects the circle, false otherwise.
|
|
40
41
|
*/
|
|
41
42
|
export function intersectsCircle(point, circle) {
|
|
42
|
-
const [x, y, z] = point
|
|
43
|
+
const [x, y, z] = ensurePoint(point)
|
|
43
44
|
const [cx, cy, cz] = circle.position
|
|
44
45
|
const radius = circle.radius
|
|
45
46
|
|
|
@@ -56,7 +57,7 @@ export function intersectsCircle(point, circle) {
|
|
|
56
57
|
* @returns {boolean} True if the point intersects the rectangle, false otherwise.
|
|
57
58
|
*/
|
|
58
59
|
export function intersectsRectangle(point, rectangle) {
|
|
59
|
-
const [x, y, z] = point
|
|
60
|
+
const [x, y, z] = ensurePoint(point)
|
|
60
61
|
const [rectX, rectY, rectZ] = rectangle.position
|
|
61
62
|
const [width, height, depth] = rectangle.size
|
|
62
63
|
|
|
@@ -76,3 +77,11 @@ export function intersectsRectangle(point, rectangle) {
|
|
|
76
77
|
z <= front
|
|
77
78
|
)
|
|
78
79
|
}
|
|
80
|
+
|
|
81
|
+
function ensurePoint(value) {
|
|
82
|
+
if (!isVector(value)) {
|
|
83
|
+
return value.position
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return value
|
|
87
|
+
}
|
|
@@ -79,3 +79,15 @@ test("it should prove that a point outside of a rectangle does not intersect wit
|
|
|
79
79
|
|
|
80
80
|
expect(intersectsRectangle(point, rectangle)).toBe(false)
|
|
81
81
|
})
|
|
82
|
+
|
|
83
|
+
test("it should work even if the point is an object with a position", () => {
|
|
84
|
+
const point = {
|
|
85
|
+
position: [1.5, 1.5, 0],
|
|
86
|
+
}
|
|
87
|
+
const rectangle = {
|
|
88
|
+
position: [1, 1, 0],
|
|
89
|
+
size: [2, 2, 0],
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
expect(intersectsRectangle(point, rectangle)).toBe(true)
|
|
93
|
+
})
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* @typedef {import('./types').Vector} Vector
|
|
2
3
|
* @typedef {import('./types').Vector2} Vector2
|
|
3
4
|
* @typedef {import('./types').Vector3} Vector3
|
|
4
5
|
*/
|
|
5
6
|
|
|
7
|
+
import { isArray } from "../../data-structures/array.js"
|
|
6
8
|
import { hypothenuse } from "../geometry/triangle.js"
|
|
7
9
|
import {
|
|
8
10
|
abs as nAbs,
|
|
@@ -11,7 +13,6 @@ import {
|
|
|
11
13
|
snap as nSnap,
|
|
12
14
|
} from "../numbers.js"
|
|
13
15
|
import { atan2, cos, sin } from "../trigonometry.js"
|
|
14
|
-
import { from2D, to2D } from "./2d.js"
|
|
15
16
|
import { quaternion } from "./quaternion.js"
|
|
16
17
|
import { cross, sum } from "./vectors.js"
|
|
17
18
|
|
|
@@ -29,8 +30,9 @@ const DEFAULT_DECIMALS = 0
|
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
32
|
* Returns the absolute value of each component in the vector.
|
|
32
|
-
*
|
|
33
|
-
* @
|
|
33
|
+
*
|
|
34
|
+
* @param {Vector} vector - The input vector.
|
|
35
|
+
* @returns {Vector} The vector with absolute values.
|
|
34
36
|
*/
|
|
35
37
|
export function abs(vector) {
|
|
36
38
|
return vector.map(nAbs)
|
|
@@ -38,8 +40,9 @@ export function abs(vector) {
|
|
|
38
40
|
|
|
39
41
|
/**
|
|
40
42
|
* Calculates the angle of the vector in radians.
|
|
41
|
-
*
|
|
42
|
-
* @
|
|
43
|
+
*
|
|
44
|
+
* @param {Vector} vector - The input vector.
|
|
45
|
+
* @returns {number} The angle of the vector in the XZ plane (for 3D) or XY plane (for 2D), in radians.
|
|
43
46
|
*/
|
|
44
47
|
export function angle(vector) {
|
|
45
48
|
return atan2(vector[vector.length - LAST_COORDINATE], vector[X])
|
|
@@ -47,10 +50,11 @@ export function angle(vector) {
|
|
|
47
50
|
|
|
48
51
|
/**
|
|
49
52
|
* Clamps the magnitude of the vector between the given min and max values.
|
|
50
|
-
*
|
|
51
|
-
* @param {
|
|
52
|
-
* @param {number}
|
|
53
|
-
* @
|
|
53
|
+
*
|
|
54
|
+
* @param {Vector} vector - The input vector.
|
|
55
|
+
* @param {number|Vector} min - The minimum magnitude or a vector representing the lower bounds for each component.
|
|
56
|
+
* @param {number|Vector} max - The maximum magnitude or a vector representing the upper bounds for each component.
|
|
57
|
+
* @returns {Vector} The clamped vector.
|
|
54
58
|
*/
|
|
55
59
|
export function clamp(vector, min, max) {
|
|
56
60
|
const length = magnitude(vector)
|
|
@@ -74,18 +78,20 @@ export function clamp(vector, min, max) {
|
|
|
74
78
|
|
|
75
79
|
/**
|
|
76
80
|
* Returns the conjugate of the vector.
|
|
77
|
-
*
|
|
78
|
-
* @
|
|
81
|
+
*
|
|
82
|
+
* @param {Vector} vector - The input vector.
|
|
83
|
+
* @returns {Vector} The conjugated vector.
|
|
79
84
|
*/
|
|
80
85
|
export function conjugate(vector) {
|
|
81
86
|
return vector.map((coordinate, index) => (index ? -coordinate : coordinate))
|
|
82
87
|
}
|
|
83
88
|
|
|
84
89
|
/**
|
|
85
|
-
* Creates a vector with the given magnitude and angle.
|
|
90
|
+
* Creates a 3D vector with the given magnitude and angle.
|
|
91
|
+
*
|
|
86
92
|
* @param {number} magnitude - The magnitude of the vector.
|
|
87
93
|
* @param {number} angle - The angle of the vector in radians.
|
|
88
|
-
* @returns {Vector3} The created vector.
|
|
94
|
+
* @returns {Vector3} The created 3D vector.
|
|
89
95
|
*/
|
|
90
96
|
export function createVector(magnitude, angle) {
|
|
91
97
|
return multiply(fromAngle(angle), magnitude)
|
|
@@ -93,16 +99,28 @@ export function createVector(magnitude, angle) {
|
|
|
93
99
|
|
|
94
100
|
/**
|
|
95
101
|
* Divides each component of the vector by the given scalar.
|
|
96
|
-
*
|
|
102
|
+
*
|
|
103
|
+
* @param {Vector} vector - The input vector.
|
|
97
104
|
* @param {number} scalar - The scalar value.
|
|
98
|
-
* @returns {
|
|
105
|
+
* @returns {Vector} The resulting vector.
|
|
99
106
|
*/
|
|
100
107
|
export function divide(vector, scalar) {
|
|
101
108
|
return vector.map((coordinate) => coordinate / scalar)
|
|
102
109
|
}
|
|
103
110
|
|
|
104
111
|
/**
|
|
105
|
-
*
|
|
112
|
+
* Converts a 2D vector [x, z] into a 3D vector [x, 0, z].
|
|
113
|
+
*
|
|
114
|
+
* @param {Vector2} vector - A 2D vector represented as [x, z].
|
|
115
|
+
* @returns {Vector3} A 3D vector represented as [x, 0, z].
|
|
116
|
+
*/
|
|
117
|
+
export function from2D(vector) {
|
|
118
|
+
const [x, z] = vector
|
|
119
|
+
return [x, NO_Y, z]
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Creates a 3D unit vector from the given angle in the XZ plane.
|
|
106
124
|
* @param {number} angle - The angle in radians.
|
|
107
125
|
* @returns {Vector3} The unit vector.
|
|
108
126
|
*/
|
|
@@ -113,8 +131,22 @@ export function fromAngle(angle) {
|
|
|
113
131
|
export const length = magnitude
|
|
114
132
|
|
|
115
133
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
134
|
+
* Checks if a value is a vector.
|
|
135
|
+
*
|
|
136
|
+
* @param {*} value - The value to check.
|
|
137
|
+
* @returns {boolean} True if the value is a vector, false otherwise.
|
|
138
|
+
*/
|
|
139
|
+
export function isVector(value) {
|
|
140
|
+
return (
|
|
141
|
+
isArray(value) &&
|
|
142
|
+
value.every((coordinate) => typeof coordinate === "number")
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Calculates the magnitude (length) of the vector.
|
|
148
|
+
*
|
|
149
|
+
* @param {Vector} vector - The input vector.
|
|
118
150
|
* @returns {number} The magnitude of the vector.
|
|
119
151
|
*/
|
|
120
152
|
export function magnitude(vector) {
|
|
@@ -123,9 +155,10 @@ export function magnitude(vector) {
|
|
|
123
155
|
|
|
124
156
|
/**
|
|
125
157
|
* Calculates the modulus of each component in the vector with the given divisor.
|
|
126
|
-
*
|
|
158
|
+
*
|
|
159
|
+
* @param {Vector} vector - The input vector.
|
|
127
160
|
* @param {number} divisor - The divisor value.
|
|
128
|
-
* @returns {
|
|
161
|
+
* @returns {Vector} The resulting vector.
|
|
129
162
|
*/
|
|
130
163
|
export function mod(vector, divisor) {
|
|
131
164
|
return vector.map((coordinate) => nMod(coordinate, divisor))
|
|
@@ -133,9 +166,10 @@ export function mod(vector, divisor) {
|
|
|
133
166
|
|
|
134
167
|
/**
|
|
135
168
|
* Multiplies each component of the vector by the given scalar.
|
|
136
|
-
*
|
|
169
|
+
*
|
|
170
|
+
* @param {Vector} vector - The input vector.
|
|
137
171
|
* @param {number} scalar - The scalar value.
|
|
138
|
-
* @returns {
|
|
172
|
+
* @returns {Vector} The resulting vector.
|
|
139
173
|
*/
|
|
140
174
|
export function multiply(vector, scalar) {
|
|
141
175
|
return vector.map((coordinate) => coordinate * scalar)
|
|
@@ -143,8 +177,9 @@ export function multiply(vector, scalar) {
|
|
|
143
177
|
|
|
144
178
|
/**
|
|
145
179
|
* Normalizes the vector to have a magnitude of 1.
|
|
146
|
-
*
|
|
147
|
-
* @
|
|
180
|
+
*
|
|
181
|
+
* @param {Vector} vector - The input vector.
|
|
182
|
+
* @returns {Vector} The normalized vector.
|
|
148
183
|
*/
|
|
149
184
|
export function normalize(vector) {
|
|
150
185
|
const length = magnitude(vector)
|
|
@@ -154,10 +189,12 @@ export function normalize(vector) {
|
|
|
154
189
|
export const remainder = mod
|
|
155
190
|
|
|
156
191
|
/**
|
|
157
|
-
* Rotates the vector by the given angle.
|
|
158
|
-
*
|
|
192
|
+
* Rotates the vector by the given angle. Handles 2D and 3D vectors.
|
|
193
|
+
* For 3D vectors, rotation is around the Y-axis.
|
|
194
|
+
*
|
|
195
|
+
* @param {Vector} vector - The input vector (2D or 3D).
|
|
159
196
|
* @param {number} angle - The angle in radians.
|
|
160
|
-
* @returns {
|
|
197
|
+
* @returns {Vector} The rotated vector.
|
|
161
198
|
*/
|
|
162
199
|
export function rotate(vector, angle) {
|
|
163
200
|
const is2D = vector.length === TWO_COORDINATES
|
|
@@ -171,15 +208,17 @@ export function rotate(vector, angle) {
|
|
|
171
208
|
|
|
172
209
|
/**
|
|
173
210
|
* Scales the vector by the given scalar. Alias of `multiply`.
|
|
174
|
-
*
|
|
211
|
+
*
|
|
212
|
+
* @param {Vector} vector - The input vector.
|
|
175
213
|
* @param {number} scalar - The scalar value.
|
|
176
|
-
* @returns {
|
|
214
|
+
* @returns {Vector} The resulting vector.
|
|
177
215
|
*/
|
|
178
216
|
export const scale = multiply
|
|
179
217
|
|
|
180
218
|
/**
|
|
181
|
-
* Sets the angle of the vector while maintaining its magnitude.
|
|
182
|
-
*
|
|
219
|
+
* Sets the angle of the vector in the XZ plane while maintaining its magnitude.
|
|
220
|
+
*
|
|
221
|
+
* @param {Vector} vector - The input vector.
|
|
183
222
|
* @param {number} angle - The new angle in radians.
|
|
184
223
|
* @returns {Vector3} The vector with the updated angle.
|
|
185
224
|
*/
|
|
@@ -196,9 +235,10 @@ export const setLength = setMagnitude
|
|
|
196
235
|
|
|
197
236
|
/**
|
|
198
237
|
* Sets the magnitude of the vector while maintaining its direction.
|
|
199
|
-
*
|
|
238
|
+
*
|
|
239
|
+
* @param {Vector} vector - The input vector.
|
|
200
240
|
* @param {number} length - The new magnitude.
|
|
201
|
-
* @returns {
|
|
241
|
+
* @returns {Vector} The vector with the updated magnitude.
|
|
202
242
|
*/
|
|
203
243
|
export function setMagnitude(vector, length) {
|
|
204
244
|
const normalized = normalize(vector)
|
|
@@ -207,9 +247,10 @@ export function setMagnitude(vector, length) {
|
|
|
207
247
|
|
|
208
248
|
/**
|
|
209
249
|
* Shifts the components of the vector by the given index.
|
|
210
|
-
*
|
|
250
|
+
*
|
|
251
|
+
* @param {Vector} vector - The input vector.
|
|
211
252
|
* @param {number} index - The index to shift by.
|
|
212
|
-
* @returns {
|
|
253
|
+
* @returns {Vector} The shifted vector.
|
|
213
254
|
*/
|
|
214
255
|
export function shift(vector, index) {
|
|
215
256
|
return [...vector.slice(index), ...vector.slice(X, index)]
|
|
@@ -217,9 +258,10 @@ export function shift(vector, index) {
|
|
|
217
258
|
|
|
218
259
|
/**
|
|
219
260
|
* Snaps each component of the vector to the nearest multiple of the given precision.
|
|
220
|
-
*
|
|
261
|
+
*
|
|
262
|
+
* @param {Vector} vector - The input vector.
|
|
221
263
|
* @param {number} [precision=DEFAULT_PRECISION] - The precision value.
|
|
222
|
-
* @returns {
|
|
264
|
+
* @returns {Vector} The snapped vector.
|
|
223
265
|
*/
|
|
224
266
|
export function snap(vector, precision = DEFAULT_PRECISION) {
|
|
225
267
|
return vector.map((coordinate) => nSnap(coordinate, -precision, precision))
|
|
@@ -228,7 +270,19 @@ export function snap(vector, precision = DEFAULT_PRECISION) {
|
|
|
228
270
|
export const times = multiply
|
|
229
271
|
|
|
230
272
|
/**
|
|
231
|
-
* Converts
|
|
273
|
+
* Converts a 3D vector [x, y, z] into a 2D vector [x, z].
|
|
274
|
+
*
|
|
275
|
+
* @param {Vector3} vector - A 3D vector represented as [x, y, z].
|
|
276
|
+
* @returns {Vector2} A 2D vector represented as [x, z].
|
|
277
|
+
*/
|
|
278
|
+
export function to2D(vector) {
|
|
279
|
+
const [x, , z] = vector
|
|
280
|
+
return [x, z]
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Converts 2D polar coordinates to 2D Cartesian coordinates.
|
|
285
|
+
*
|
|
232
286
|
* @param {Vector2} vector - The polar coordinates [magnitude, angle].
|
|
233
287
|
* @returns {Vector2} The Cartesian coordinates [x, y].
|
|
234
288
|
*/
|
|
@@ -237,9 +291,10 @@ export function toCartesian([magnitude, angle]) {
|
|
|
237
291
|
}
|
|
238
292
|
|
|
239
293
|
/**
|
|
240
|
-
* Converts a vector to cylindrical coordinates.
|
|
241
|
-
*
|
|
242
|
-
* @
|
|
294
|
+
* Converts a 3D cartesian vector to cylindrical coordinates.
|
|
295
|
+
*
|
|
296
|
+
* @param {Vector3} vector - The input vector [x, y, z].
|
|
297
|
+
* @returns {Vector3} The cylindrical coordinates [radius, theta, z].
|
|
243
298
|
*/
|
|
244
299
|
export function toCylindrical(vector) {
|
|
245
300
|
const radius = magnitude(vector)
|
|
@@ -248,8 +303,9 @@ export function toCylindrical(vector) {
|
|
|
248
303
|
}
|
|
249
304
|
|
|
250
305
|
/**
|
|
251
|
-
* Converts a vector to polar coordinates.
|
|
252
|
-
*
|
|
306
|
+
* Converts a 2D cartesian vector to 2D polar coordinates.
|
|
307
|
+
*
|
|
308
|
+
* @param {Vector2} vector - The input vector [x, y].
|
|
253
309
|
* @returns {Vector2} The polar coordinates [magnitude, angle].
|
|
254
310
|
*/
|
|
255
311
|
export function toPolar(vector) {
|
|
@@ -258,7 +314,8 @@ export function toPolar(vector) {
|
|
|
258
314
|
|
|
259
315
|
/**
|
|
260
316
|
* Converts a vector to a string representation.
|
|
261
|
-
*
|
|
317
|
+
*
|
|
318
|
+
* @param {Vector} vector - The input vector.
|
|
262
319
|
* @param {number} [decimals=DEFAULT_DECIMALS] - The number of decimal places.
|
|
263
320
|
* @returns {string} The string representation of the vector.
|
|
264
321
|
*/
|
|
@@ -295,8 +352,9 @@ export function toSpherical(vector) {
|
|
|
295
352
|
}
|
|
296
353
|
|
|
297
354
|
/**
|
|
298
|
-
* Creates a unit vector with the given angle.
|
|
299
|
-
*
|
|
355
|
+
* Creates a 3D unit vector in the XZ plane with the given angle.
|
|
356
|
+
*
|
|
357
|
+
* @param {number} [angle=0] - The angle in radians.
|
|
300
358
|
* @returns {Vector3} The unit vector.
|
|
301
359
|
*/
|
|
302
360
|
export function unit(angle) {
|
|
@@ -308,7 +366,19 @@ export function unit(angle) {
|
|
|
308
366
|
}
|
|
309
367
|
|
|
310
368
|
/**
|
|
311
|
-
*
|
|
369
|
+
* A utility function to create a vector from a list of coordinates.
|
|
370
|
+
* This is a shorthand for `[x, y, z, ...]`.
|
|
371
|
+
*
|
|
372
|
+
* @param {...number} coords - The coordinates of the vector.
|
|
373
|
+
* @returns {Vector} The created vector.
|
|
374
|
+
*/
|
|
375
|
+
export function v(...coords) {
|
|
376
|
+
return coords
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Creates a zero vector of 3 dimensions.
|
|
381
|
+
*
|
|
312
382
|
* @returns {Vector3} The zero vector.
|
|
313
383
|
*/
|
|
314
384
|
export function zero() {
|
|
@@ -316,7 +386,8 @@ export function zero() {
|
|
|
316
386
|
}
|
|
317
387
|
|
|
318
388
|
/**
|
|
319
|
-
* Rotates
|
|
389
|
+
* Rotates a 3D vector around the Y-axis using a quaternion.
|
|
390
|
+
*
|
|
320
391
|
* @param {Vector3} vector - The input vector.
|
|
321
392
|
* @param {number} angle - The angle in radians.
|
|
322
393
|
* @returns {Vector3} The rotated vector.
|
|
@@ -9,7 +9,9 @@ import {
|
|
|
9
9
|
conjugate,
|
|
10
10
|
createVector,
|
|
11
11
|
divide,
|
|
12
|
+
from2D,
|
|
12
13
|
fromAngle,
|
|
14
|
+
isVector,
|
|
13
15
|
magnitude,
|
|
14
16
|
mod,
|
|
15
17
|
multiply,
|
|
@@ -19,12 +21,15 @@ import {
|
|
|
19
21
|
setMagnitude,
|
|
20
22
|
shift,
|
|
21
23
|
snap,
|
|
24
|
+
to2D,
|
|
22
25
|
toCartesian,
|
|
23
26
|
toCylindrical,
|
|
24
27
|
toPolar,
|
|
25
28
|
toSpherical,
|
|
26
29
|
toString,
|
|
27
30
|
unit,
|
|
31
|
+
v,
|
|
32
|
+
zero,
|
|
28
33
|
} from "./vector.js"
|
|
29
34
|
|
|
30
35
|
test("it should compute the absolute value of a vector's coordinates", () => {
|
|
@@ -98,6 +103,13 @@ test("it should divide a vector by a scalar", () => {
|
|
|
98
103
|
expect(divide(vector, scalar)).toStrictEqual(expectedResult)
|
|
99
104
|
})
|
|
100
105
|
|
|
106
|
+
test("it should build a 3D vector from a 2D one", () => {
|
|
107
|
+
const vector = [3, 4]
|
|
108
|
+
const expectedResult = [3, 0, 4]
|
|
109
|
+
|
|
110
|
+
expect(from2D(vector)).toStrictEqual(expectedResult)
|
|
111
|
+
})
|
|
112
|
+
|
|
101
113
|
test("it should create a 3D unit vector from an angle", () => {
|
|
102
114
|
const angle = pi() / 4
|
|
103
115
|
const expectedResult = [0.7071067811865475, -0, 0.7071067811865476] // close to [cos(angle), 0, sin(angle)]
|
|
@@ -112,6 +124,19 @@ test("it should compute the magnitude of a vector (aka length)", () => {
|
|
|
112
124
|
expect(magnitude(vector)).toBe(expectedResult)
|
|
113
125
|
})
|
|
114
126
|
|
|
127
|
+
test("it should check if a value is a vector", () => {
|
|
128
|
+
expect(isVector([1, 2, 3])).toBe(true)
|
|
129
|
+
expect(isVector([])).toBe(true)
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
test("it should check if a value is not a vector", () => {
|
|
133
|
+
expect(isVector([1, "a", 3])).toBe(false)
|
|
134
|
+
expect(isVector({ x: 1, y: 2 })).toBe(false)
|
|
135
|
+
expect(isVector(null)).toBe(false)
|
|
136
|
+
expect(isVector("vector")).toBe(false)
|
|
137
|
+
expect(isVector(123)).toBe(false)
|
|
138
|
+
})
|
|
139
|
+
|
|
115
140
|
test("it should apply the mod operator (aka remainder) on a vector", () => {
|
|
116
141
|
const vector = [10, 12, -18]
|
|
117
142
|
const divisor = 12
|
|
@@ -213,6 +238,13 @@ test("it should snap a floating vector to a certain precision", () => {
|
|
|
213
238
|
expect(snap(vector, precision)).toStrictEqual(expectedResult)
|
|
214
239
|
})
|
|
215
240
|
|
|
241
|
+
test("it should build a 2D vector from a 3D one", () => {
|
|
242
|
+
const vector = [3, 0, 4]
|
|
243
|
+
const expectedResult = [3, 4]
|
|
244
|
+
|
|
245
|
+
expect(to2D(vector)).toStrictEqual(expectedResult)
|
|
246
|
+
})
|
|
247
|
+
|
|
216
248
|
test("it should convert a 2D polar vector to cartesian coordinates", () => {
|
|
217
249
|
const vector = [sqrt(2), pi() / 4]
|
|
218
250
|
const expectedResult = [1.0000000000000002, 1]
|
|
@@ -263,3 +295,15 @@ test("it should create a unit vector oriented on the X-axis", () => {
|
|
|
263
295
|
test("it should create a unit vector oriented on the Z-axis", () => {
|
|
264
296
|
expect(unit(pi() / 2)).toStrictEqual([6.123233995736766e-17, 0, 1]) // close to [0, 0, 1]
|
|
265
297
|
})
|
|
298
|
+
|
|
299
|
+
test("it should create a vector from a list of coordinates", () => {
|
|
300
|
+
expect(v(1, 2, 3)).toStrictEqual([1, 2, 3])
|
|
301
|
+
expect(v()).toStrictEqual([])
|
|
302
|
+
expect(v(0, -5.5)).toStrictEqual([0, -5.5])
|
|
303
|
+
})
|
|
304
|
+
|
|
305
|
+
test("it should create a 3D zero vector", () => {
|
|
306
|
+
const expectedResult = [0, 0, 0]
|
|
307
|
+
|
|
308
|
+
expect(zero()).toStrictEqual(expectedResult)
|
|
309
|
+
})
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef {import('../../../types').Vector2} Vector2
|
|
3
|
-
* @typedef {import('../../../types').Vector3} Vector3
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const NO_Y = 0 // Default Y-coordinate value for 3D vectors derived from 2D vectors.
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Converts a 2D vector [x, z] into a 3D vector [x, 0, z].
|
|
10
|
-
*
|
|
11
|
-
* @param {Vector2} vector - A 2D vector represented as [x, z].
|
|
12
|
-
* @returns {Vector3} A 3D vector represented as [x, 0, z].
|
|
13
|
-
*/
|
|
14
|
-
export function from2D(vector) {
|
|
15
|
-
const [x, z] = vector
|
|
16
|
-
return [x, NO_Y, z]
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Converts a 3D vector [x, y, z] into a 2D vector [x, z].
|
|
21
|
-
*
|
|
22
|
-
* @param {Vector3} vector - A 3D vector represented as [x, y, z].
|
|
23
|
-
* @returns {Vector2} A 2D vector represented as [x, z].
|
|
24
|
-
*/
|
|
25
|
-
export function to2D(vector) {
|
|
26
|
-
const [x, , z] = vector
|
|
27
|
-
return [x, z]
|
|
28
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { expect, test } from "vitest"
|
|
2
|
-
|
|
3
|
-
import { from2D, to2D } from "./2d.js"
|
|
4
|
-
|
|
5
|
-
test("build a 3D vector from a 2D one", () => {
|
|
6
|
-
const vector = [3, 4]
|
|
7
|
-
const expectedResult = [3, 0, 4]
|
|
8
|
-
|
|
9
|
-
expect(from2D(vector)).toStrictEqual(expectedResult)
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
test("build a 2D vector from a 3D one", () => {
|
|
13
|
-
const vector = [3, 0, 4]
|
|
14
|
-
const expectedResult = [3, 4]
|
|
15
|
-
|
|
16
|
-
expect(to2D(vector)).toStrictEqual(expectedResult)
|
|
17
|
-
})
|