@pawells/math-extended 1.0.5 → 2.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 (106) hide show
  1. package/README.md +5 -5
  2. package/build/angles.d.ts +43 -3
  3. package/build/angles.d.ts.map +1 -1
  4. package/build/angles.js +61 -34
  5. package/build/angles.js.map +1 -1
  6. package/build/clamp.d.ts +5 -3
  7. package/build/clamp.d.ts.map +1 -1
  8. package/build/clamp.js +5 -3
  9. package/build/clamp.js.map +1 -1
  10. package/build/interpolation.d.ts +444 -67
  11. package/build/interpolation.d.ts.map +1 -1
  12. package/build/interpolation.js +444 -67
  13. package/build/interpolation.js.map +1 -1
  14. package/build/matrices/_exports.d.ts +13 -0
  15. package/build/matrices/_exports.d.ts.map +1 -0
  16. package/build/matrices/_exports.js +13 -0
  17. package/build/matrices/_exports.js.map +1 -0
  18. package/build/matrices/arithmetic.d.ts +170 -181
  19. package/build/matrices/arithmetic.d.ts.map +1 -1
  20. package/build/matrices/arithmetic.js +192 -202
  21. package/build/matrices/arithmetic.js.map +1 -1
  22. package/build/matrices/asserts.d.ts +244 -116
  23. package/build/matrices/asserts.d.ts.map +1 -1
  24. package/build/matrices/asserts.js +291 -94
  25. package/build/matrices/asserts.js.map +1 -1
  26. package/build/matrices/core.d.ts +40 -41
  27. package/build/matrices/core.d.ts.map +1 -1
  28. package/build/matrices/core.js +12 -13
  29. package/build/matrices/core.js.map +1 -1
  30. package/build/matrices/decompositions.d.ts +121 -124
  31. package/build/matrices/decompositions.d.ts.map +1 -1
  32. package/build/matrices/decompositions.js +168 -226
  33. package/build/matrices/decompositions.js.map +1 -1
  34. package/build/matrices/index.d.ts +3 -2
  35. package/build/matrices/index.d.ts.map +1 -1
  36. package/build/matrices/index.js +5 -2
  37. package/build/matrices/index.js.map +1 -1
  38. package/build/matrices/linear-algebra.d.ts +18 -13
  39. package/build/matrices/linear-algebra.d.ts.map +1 -1
  40. package/build/matrices/linear-algebra.js +58 -23
  41. package/build/matrices/linear-algebra.js.map +1 -1
  42. package/build/matrices/normalization.d.ts +8 -8
  43. package/build/matrices/transformations.d.ts +184 -168
  44. package/build/matrices/transformations.d.ts.map +1 -1
  45. package/build/matrices/transformations.js +99 -83
  46. package/build/matrices/transformations.js.map +1 -1
  47. package/build/matrices/types.d.ts +12 -12
  48. package/build/matrices/types.d.ts.map +1 -1
  49. package/build/quaternions/_exports.d.ts +11 -0
  50. package/build/quaternions/_exports.d.ts.map +1 -0
  51. package/build/quaternions/_exports.js +11 -0
  52. package/build/quaternions/_exports.js.map +1 -0
  53. package/build/quaternions/asserts.d.ts +115 -7
  54. package/build/quaternions/asserts.d.ts.map +1 -1
  55. package/build/quaternions/asserts.js +162 -8
  56. package/build/quaternions/asserts.js.map +1 -1
  57. package/build/quaternions/conversions.d.ts +31 -21
  58. package/build/quaternions/conversions.d.ts.map +1 -1
  59. package/build/quaternions/conversions.js +28 -18
  60. package/build/quaternions/conversions.js.map +1 -1
  61. package/build/quaternions/core.d.ts +73 -41
  62. package/build/quaternions/core.d.ts.map +1 -1
  63. package/build/quaternions/core.js +84 -49
  64. package/build/quaternions/core.js.map +1 -1
  65. package/build/quaternions/index.d.ts +3 -2
  66. package/build/quaternions/index.d.ts.map +1 -1
  67. package/build/quaternions/index.js +5 -2
  68. package/build/quaternions/index.js.map +1 -1
  69. package/build/quaternions/interpolation.d.ts +15 -9
  70. package/build/quaternions/interpolation.d.ts.map +1 -1
  71. package/build/quaternions/interpolation.js +15 -9
  72. package/build/quaternions/interpolation.js.map +1 -1
  73. package/build/quaternions/predefined.d.ts +9 -3
  74. package/build/quaternions/predefined.d.ts.map +1 -1
  75. package/build/quaternions/predefined.js +9 -3
  76. package/build/quaternions/predefined.js.map +1 -1
  77. package/build/quaternions/types.d.ts +3 -3
  78. package/build/random.d.ts +5 -2
  79. package/build/random.d.ts.map +1 -1
  80. package/build/random.js +20 -17
  81. package/build/random.js.map +1 -1
  82. package/build/vectors/_exports.d.ts +10 -0
  83. package/build/vectors/_exports.d.ts.map +1 -0
  84. package/build/vectors/_exports.js +10 -0
  85. package/build/vectors/_exports.js.map +1 -0
  86. package/build/vectors/asserts.d.ts +153 -49
  87. package/build/vectors/asserts.d.ts.map +1 -1
  88. package/build/vectors/asserts.js +202 -52
  89. package/build/vectors/asserts.js.map +1 -1
  90. package/build/vectors/core.d.ts +216 -137
  91. package/build/vectors/core.d.ts.map +1 -1
  92. package/build/vectors/core.js +217 -158
  93. package/build/vectors/core.js.map +1 -1
  94. package/build/vectors/index.d.ts +1 -0
  95. package/build/vectors/index.d.ts.map +1 -1
  96. package/build/vectors/index.js +3 -0
  97. package/build/vectors/index.js.map +1 -1
  98. package/build/vectors/interpolation.d.ts +39 -27
  99. package/build/vectors/interpolation.d.ts.map +1 -1
  100. package/build/vectors/interpolation.js +39 -27
  101. package/build/vectors/interpolation.js.map +1 -1
  102. package/build/vectors/predefined.d.ts +48 -24
  103. package/build/vectors/predefined.d.ts.map +1 -1
  104. package/build/vectors/predefined.js +38 -18
  105. package/build/vectors/predefined.js.map +1 -1
  106. package/package.json +12 -15
@@ -13,9 +13,11 @@ import { AssertVector, AssertVectors, AssertVectorValue, VectorError, AssertVect
13
13
  * @returns A new vector with identical components
14
14
  *
15
15
  * @example
16
- * const original = [1, 2, 3];
17
- * const copy = VectorClone(original);
18
- * copy[0] = 10; // original remains unchanged
16
+ * ```typescript
17
+ * const original = [1, 2, 3];
18
+ * const copy = VectorClone(original);
19
+ * copy[0] = 10; // original remains unchanged
20
+ * ```
19
21
  */
20
22
  export function VectorClone(vector) {
21
23
  AssertVector(vector);
@@ -32,10 +34,12 @@ export function VectorClone(vector) {
32
34
  * @returns True if vectors are equal within tolerance, false otherwise
33
35
  *
34
36
  * @example
35
- * const a = [1.0001, 2.0001];
36
- * const b = [1.0002, 2.0002];
37
- * const exactlyEqual = VectorEquals(a, b); // false
38
- * const approximatelyEqual = VectorEquals(a, b, 0.001); // true
37
+ * ```typescript
38
+ * const a = [1.0001, 2.0001];
39
+ * const b = [1.0002, 2.0002];
40
+ * const exactlyEqual = VectorEquals(a, b); // false
41
+ * const approximatelyEqual = VectorEquals(a, b, 0.001); // true
42
+ * ```
39
43
  */
40
44
  export function VectorEquals(a, b, tolerance = 0) {
41
45
  AssertVectors([a, b]);
@@ -64,9 +68,11 @@ export function VectorEquals(a, b, tolerance = 0) {
64
68
  * @returns String representation of the vector
65
69
  *
66
70
  * @example
67
- * const vec = [1, 2, 3];
68
- * const parens = VectorToString(vec, 'parens'); // "(1, 2, 3)"
69
- * const brackets = VectorToString(vec, 'brackets'); // "[1, 2, 3]"
71
+ * ```typescript
72
+ * const vec = [1, 2, 3];
73
+ * const parens = VectorToString(vec, 'parens'); // "(1, 2, 3)"
74
+ * const brackets = VectorToString(vec, 'brackets'); // "[1, 2, 3]"
75
+ * ```
70
76
  */
71
77
  export function VectorToString(vector, style = 'parens') {
72
78
  AssertVector(vector);
@@ -74,12 +80,7 @@ export function VectorToString(vector, style = 'parens') {
74
80
  if (style === 'parens') {
75
81
  return `(${components})`;
76
82
  }
77
- else if (style === 'brackets') {
78
- return `[${components}]`;
79
- }
80
- else {
81
- throw new Error(`Invalid style: ${style}. Use 'parens' or 'brackets'.`);
82
- }
83
+ return `[${components}]`;
83
84
  }
84
85
  /**
85
86
  * Performs component-wise addition of two vectors.
@@ -91,9 +92,11 @@ export function VectorToString(vector, style = 'parens') {
91
92
  * @returns New vector where each component is the sum of corresponding components
92
93
  *
93
94
  * @example
94
- * const position = [10, 20, 30];
95
- * const velocity = [1, -2, 0.5];
96
- * const newPosition = VectorAdd(position, velocity); // [11, 18, 30.5]
95
+ * ```typescript
96
+ * const position = [10, 20, 30];
97
+ * const velocity = [1, -2, 0.5];
98
+ * const newPosition = VectorAdd(position, velocity); // [11, 18, 30.5]
99
+ * ```
97
100
  */
98
101
  export function VectorAdd(a, b) {
99
102
  AssertVectors([a, b]);
@@ -117,9 +120,11 @@ export function VectorAdd(a, b) {
117
120
  * @returns New vector where each component is the difference of corresponding components
118
121
  *
119
122
  * @example
120
- * const target = [100, 50, 0];
121
- * const current = [80, 30, 0];
122
- * const direction = VectorSubtract(target, current); // [20, 20, 0]
123
+ * ```typescript
124
+ * const target = [100, 50, 0];
125
+ * const current = [80, 30, 0];
126
+ * const direction = VectorSubtract(target, current); // [20, 20, 0]
127
+ * ```
123
128
  */
124
129
  export function VectorSubtract(a, b) {
125
130
  AssertVectors([a, b]);
@@ -143,10 +148,12 @@ export function VectorSubtract(a, b) {
143
148
  * @returns New vector with multiplied components
144
149
  *
145
150
  * @example
146
- * const velocity = [10, 5, 0];
147
- * const scaled = VectorMultiply(velocity, 2); // [20, 10, 0] - scalar multiplication
148
- * const factors = [1, -1, 0.5];
149
- * const componentWise = VectorMultiply(velocity, factors); // [10, -5, 0] - component-wise
151
+ * ```typescript
152
+ * const velocity = [10, 5, 0];
153
+ * const scaled = VectorMultiply(velocity, 2); // [20, 10, 0] - scalar multiplication
154
+ * const factors = [1, -1, 0.5];
155
+ * const componentWise = VectorMultiply(velocity, factors); // [10, -5, 0] - component-wise
156
+ * ```
150
157
  */
151
158
  export function VectorMultiply(a, b) {
152
159
  const result = [];
@@ -180,9 +187,11 @@ export function VectorMultiply(a, b) {
180
187
  * @returns The straight-line distance between the two points represented by the vectors
181
188
  *
182
189
  * @example
183
- * const pointA = [0, 0, 0];
184
- * const pointB = [3, 4, 0];
185
- * const distance = VectorDistance(pointA, pointB); // 5.0 (3-4-5 triangle)
190
+ * ```typescript
191
+ * const pointA = [0, 0, 0];
192
+ * const pointB = [3, 4, 0];
193
+ * const distance = VectorDistance(pointA, pointB); // 5.0 (3-4-5 triangle)
194
+ * ```
186
195
  */
187
196
  export function VectorDistance(a, b) {
188
197
  return Math.sqrt(VectorDistanceSquared(a, b));
@@ -197,9 +206,11 @@ export function VectorDistance(a, b) {
197
206
  * @returns The squared distance between vectors
198
207
  *
199
208
  * @example
200
- * const pointA = [1, 1];
201
- * const pointB = [4, 5];
202
- * const distSq = VectorDistanceSquared(pointA, pointB); // 25 (faster than distance comparison)
209
+ * ```typescript
210
+ * const pointA = [1, 1];
211
+ * const pointB = [4, 5];
212
+ * const distSq = VectorDistanceSquared(pointA, pointB); // 25 (faster than distance comparison)
213
+ * ```
203
214
  */
204
215
  export function VectorDistanceSquared(a, b) {
205
216
  AssertVectors([a, b]);
@@ -209,7 +220,8 @@ export function VectorDistanceSquared(a, b) {
209
220
  AssertVectorValue(av, {});
210
221
  const bv = b[i];
211
222
  AssertVectorValue(bv, {});
212
- sum += Math.pow(bv - av, 2);
223
+ const diff = bv - av;
224
+ sum += diff * diff;
213
225
  }
214
226
  return sum;
215
227
  }
@@ -223,12 +235,13 @@ export function VectorDistanceSquared(a, b) {
223
235
  * @returns The dot product (scalar value)
224
236
  *
225
237
  * @example
226
- * const forward = [0, 0, 1];
227
- * const direction = [0, 0, 2];
228
- * const dot = VectorDot(forward, direction); // 2 (same direction)
229
- *
230
- * const perpendicular = [1, 0, 0];
231
- * const dotPerp = VectorDot(forward, perpendicular); // 0 (perpendicular)
238
+ * ```typescript
239
+ * const forward = [0, 0, 1];
240
+ * const direction = [0, 0, 2];
241
+ * const dot = VectorDot(forward, direction); // 2 (same direction)
242
+ * const perpendicular = [1, 0, 0];
243
+ * const dotPerp = VectorDot(forward, perpendicular); // 0 (perpendicular)
244
+ * ```
232
245
  */
233
246
  export function VectorDot(a, b) {
234
247
  AssertVectors([a, b]);
@@ -253,11 +266,12 @@ export function VectorDot(a, b) {
253
266
  * @throws {VectorError} If the vector is zero or has infinite magnitude
254
267
  *
255
268
  * @example
256
- * const vector = [3, 4, 0];
257
- * const normalized = VectorNormalize(vector); // [0.6, 0.8, 0] (magnitude = 1)
258
- *
259
- * const direction = [10, 0, 0];
260
- * const unitDirection = VectorNormalize(direction); // [1, 0, 0]
269
+ * ```typescript
270
+ * const vector = [3, 4, 0];
271
+ * const normalized = VectorNormalize(vector); // [0.6, 0.8, 0] (magnitude = 1)
272
+ * const direction = [10, 0, 0];
273
+ * const unitDirection = VectorNormalize(direction); // [1, 0, 0]
274
+ * ```
261
275
  */
262
276
  export function VectorNormalize(a) {
263
277
  AssertVector(a);
@@ -282,18 +296,19 @@ export function VectorNormalize(a) {
282
296
  * @returns The magnitude (length) of the vector
283
297
  *
284
298
  * @example
285
- * const velocity = [3, 4, 0];
286
- * const speed = VectorMagnitude(velocity); // 5.0
287
- *
288
- * const unitVector = [1, 0, 0];
289
- * const unitLength = VectorMagnitude(unitVector); // 1.0
299
+ * ```typescript
300
+ * const velocity = [3, 4, 0];
301
+ * const speed = VectorMagnitude(velocity); // 5.0
302
+ * const unitVector = [1, 0, 0];
303
+ * const unitLength = VectorMagnitude(unitVector); // 1.0
304
+ * ```
290
305
  */
291
306
  export function VectorMagnitude(a) {
292
307
  AssertVector(a);
293
308
  let sum = 0;
294
309
  for (const av of a) {
295
310
  AssertVectorValue(av, {});
296
- sum += Math.pow(av, 2);
311
+ sum += av * av;
297
312
  }
298
313
  return Math.sqrt(sum);
299
314
  }
@@ -306,11 +321,12 @@ export function VectorMagnitude(a) {
306
321
  * @returns New vector with absolute values of all components
307
322
  *
308
323
  * @example
309
- * const vector = [-3, 4, -2];
310
- * const absolute = VectorAbs(vector); // [3, 4, 2]
311
- *
312
- * const mixed = [1.5, -2.7, 0];
313
- * const absValues = VectorAbs(mixed); // [1.5, 2.7, 0]
324
+ * ```typescript
325
+ * const vector = [-3, 4, -2];
326
+ * const absolute = VectorAbs(vector); // [3, 4, 2]
327
+ * const mixed = [1.5, -2.7, 0];
328
+ * const absValues = VectorAbs(mixed); // [1.5, 2.7, 0]
329
+ * ```
314
330
  */
315
331
  export function VectorAbs(a) {
316
332
  AssertVector(a);
@@ -329,11 +345,12 @@ export function VectorAbs(a) {
329
345
  * @returns True if all components are zero, false otherwise
330
346
  *
331
347
  * @example
332
- * const zero = [0, 0, 0];
333
- * const isZero = VectorIsZero(zero); // true
334
- *
335
- * const notZero = [0, 0.001, 0];
336
- * const isNotZero = VectorIsZero(notZero); // false
348
+ * ```typescript
349
+ * const zero = [0, 0, 0];
350
+ * const isZero = VectorIsZero(zero); // true
351
+ * const notZero = [0, 0.001, 0];
352
+ * const isNotZero = VectorIsZero(notZero); // false
353
+ * ```
337
354
  */
338
355
  export function VectorIsZero(vector) {
339
356
  return vector.every((v) => v === 0);
@@ -349,13 +366,14 @@ export function VectorIsZero(vector) {
349
366
  * @throws {VectorError} If either vector is zero
350
367
  *
351
368
  * @example
352
- * const right = [1, 0, 0];
353
- * const up = [0, 1, 0];
354
- * const angle = VectorAngle(right, up); // π/2 (90 degrees)
355
- *
356
- * const forward = [0, 0, 1];
357
- * const backward = [0, 0, -1];
358
- * const oppositeAngle = VectorAngle(forward, backward); // π (180 degrees)
369
+ * ```typescript
370
+ * const right = [1, 0, 0];
371
+ * const up = [0, 1, 0];
372
+ * const angle = VectorAngle(right, up); // π/2 (90 degrees)
373
+ * const forward = [0, 0, 1];
374
+ * const backward = [0, 0, -1];
375
+ * const oppositeAngle = VectorAngle(forward, backward); // π (180 degrees)
376
+ * ```
359
377
  */
360
378
  export function VectorAngle(a, b) {
361
379
  AssertVectors([a, b]);
@@ -375,9 +393,11 @@ export function VectorAngle(a, b) {
375
393
  * @returns New rotated 2D vector
376
394
  *
377
395
  * @example
378
- * const right = [1, 0];
379
- * const rotated90 = Vector2Rotate(right, Math.PI / 2); // [0, 1] (up)
380
- * const rotated180 = Vector2Rotate(right, Math.PI); // [-1, 0] (left)
396
+ * ```typescript
397
+ * const right = [1, 0];
398
+ * const rotated90 = Vector2Rotate(right, Math.PI / 2); // [0, 1] (up)
399
+ * const rotated180 = Vector2Rotate(right, Math.PI); // [-1, 0] (left)
400
+ * ```
381
401
  */
382
402
  export function Vector2Rotate(vector, radians) {
383
403
  AssertVector2(vector);
@@ -397,9 +417,11 @@ export function Vector2Rotate(vector, radians) {
397
417
  * @returns Unit vector pointing in the specified direction
398
418
  *
399
419
  * @example
400
- * const right = Vector2FromAngle(0); // [1, 0]
401
- * const up = Vector2FromAngle(Math.PI / 2); // [0, 1]
402
- * const diagonal = Vector2FromAngle(Math.PI / 4); // [0.707, 0.707]
420
+ * ```typescript
421
+ * const right = Vector2FromAngle(0); // [1, 0]
422
+ * const up = Vector2FromAngle(Math.PI / 2); // [0, 1]
423
+ * const diagonal = Vector2FromAngle(Math.PI / 4); // [0.707, 0.707]
424
+ * ```
403
425
  */
404
426
  export function Vector2FromAngle(radians) {
405
427
  return [Math.cos(radians), Math.sin(radians)];
@@ -414,10 +436,12 @@ export function Vector2FromAngle(radians) {
414
436
  * @returns Scalar cross product (positive = counterclockwise, negative = clockwise)
415
437
  *
416
438
  * @example
417
- * const right = [1, 0];
418
- * const up = [0, 1];
419
- * const cross = Vector2Cross(right, up); // 1 (counterclockwise)
420
- * const crossReverse = Vector2Cross(up, right); // -1 (clockwise)
439
+ * ```typescript
440
+ * const right = [1, 0];
441
+ * const up = [0, 1];
442
+ * const cross = Vector2Cross(right, up); // 1 (counterclockwise)
443
+ * const crossReverse = Vector2Cross(up, right); // -1 (clockwise)
444
+ * ```
421
445
  */
422
446
  export function Vector2Cross(a, b) {
423
447
  AssertVector2(a);
@@ -435,9 +459,11 @@ export function Vector2Cross(a, b) {
435
459
  * @throws {VectorError} If vector b is zero
436
460
  *
437
461
  * @example
438
- * const force = [5, 3, 0];
439
- * const surface = [1, 0, 0];
440
- * const perpendicular = Vector3Reject(force, surface); // [0, 3, 0]
462
+ * ```typescript
463
+ * const force = [5, 3, 0];
464
+ * const surface = [1, 0, 0];
465
+ * const perpendicular = Vector3Reject(force, surface); // [0, 3, 0]
466
+ * ```
441
467
  */
442
468
  export function Vector3Reject(a, b) {
443
469
  AssertVector3(a);
@@ -459,16 +485,18 @@ export function Vector3Reject(a, b) {
459
485
  * @throws {VectorError} If vector b is zero
460
486
  *
461
487
  * @example
462
- * const force = [5, 3, 0];
463
- * const surface = [1, 0, 0];
464
- * const parallel = VectorProject(force, surface); // [5, 0, 0]
488
+ * ```typescript
489
+ * const force = [5, 3, 0];
490
+ * const surface = [1, 0, 0];
491
+ * const parallel = VectorProject(force, surface); // [5, 0, 0]
492
+ * ```
465
493
  */
466
494
  export function VectorProject(a, b) {
467
495
  AssertVectors([a, b]);
468
496
  if (VectorIsZero(b))
469
497
  throw new VectorError('Cannot project onto a zero vector');
470
498
  const dot = VectorDot(a, b);
471
- const magSquared = Math.pow(VectorMagnitude(b), 2);
499
+ const magSquared = VectorDot(b, b);
472
500
  const scalar = dot / magSquared;
473
501
  const result = [];
474
502
  for (const bv of b) {
@@ -488,9 +516,11 @@ export function VectorProject(a, b) {
488
516
  * @throws {VectorError} If the normal is a zero vector
489
517
  *
490
518
  * @example
491
- * const incoming = [1, -1, 0];
492
- * const normal = [0, 1, 0]; // surface normal (upward)
493
- * const reflected = Vector3Reflect(incoming, normal); // [1, 1, 0]
519
+ * ```typescript
520
+ * const incoming = [1, -1, 0];
521
+ * const normal = [0, 1, 0]; // surface normal (upward)
522
+ * const reflected = Vector3Reflect(incoming, normal); // [1, 1, 0]
523
+ * ```
494
524
  */
495
525
  export function Vector3Reflect(incident, normal) {
496
526
  AssertVector3(incident);
@@ -510,11 +540,12 @@ export function Vector3Reflect(incident, normal) {
510
540
  * @returns Vector perpendicular to both a and b (following right-hand rule)
511
541
  *
512
542
  * @example
513
- * const right = [1, 0, 0];
514
- * const forward = [0, 0, 1];
515
- * const up = Vector3Cross(right, forward); // [0, 1, 0]
516
- *
517
- * const normal = Vector3Cross([1, 0, 0], [0, 1, 0]); // [0, 0, 1]
543
+ * ```typescript
544
+ * const right = [1, 0, 0];
545
+ * const forward = [0, 0, 1];
546
+ * const up = Vector3Cross(right, forward); // [0, 1, 0]
547
+ * const normal = Vector3Cross([1, 0, 0], [0, 1, 0]); // [0, 0, 1]
548
+ * ```
518
549
  */
519
550
  export function Vector3Cross(a, b) {
520
551
  AssertVector3(a);
@@ -535,9 +566,11 @@ export function Vector3Cross(a, b) {
535
566
  * @returns Magnitude of the cross product
536
567
  *
537
568
  * @example
538
- * const side1 = [3, 0, 0];
539
- * const side2 = [0, 4, 0];
540
- * const area = VectorCrossMagnitude(side1, side2); // 12 (area of rectangle)
569
+ * ```typescript
570
+ * const side1 = [3, 0, 0];
571
+ * const side2 = [0, 4, 0];
572
+ * const area = VectorCrossMagnitude(side1, side2); // 12 (area of rectangle)
573
+ * ```
541
574
  */
542
575
  export function VectorCrossMagnitude(a, b) {
543
576
  AssertVector3(a);
@@ -556,10 +589,12 @@ export function VectorCrossMagnitude(a, b) {
556
589
  * @returns Signed volume (positive = right-handed orientation)
557
590
  *
558
591
  * @example
559
- * const x = [1, 0, 0];
560
- * const y = [0, 1, 0];
561
- * const z = [0, 0, 1];
562
- * const volume = Vector3ScalarTripleProduct(x, y, z); // 1 (unit cube)
592
+ * ```typescript
593
+ * const x = [1, 0, 0];
594
+ * const y = [0, 1, 0];
595
+ * const z = [0, 0, 1];
596
+ * const volume = Vector3ScalarTripleProduct(x, y, z); // 1 (unit cube)
597
+ * ```
563
598
  */
564
599
  export function Vector3ScalarTripleProduct(a, b, c) {
565
600
  AssertVector3(a);
@@ -579,10 +614,12 @@ export function Vector3ScalarTripleProduct(a, b, c) {
579
614
  * @returns Vector result of a × (b × c)
580
615
  *
581
616
  * @example
582
- * const a = [1, 0, 0];
583
- * const b = [0, 1, 0];
584
- * const c = [0, 0, 1];
585
- * const result = Vector3TripleProduct(a, b, c); // [0, 0, 0]
617
+ * ```typescript
618
+ * const a = [1, 0, 0];
619
+ * const b = [0, 1, 0];
620
+ * const c = [0, 0, 1];
621
+ * const result = Vector3TripleProduct(a, b, c); // [0, 0, 0]
622
+ * ```
586
623
  */
587
624
  export function Vector3TripleProduct(a, b, c) {
588
625
  AssertVector3(a);
@@ -602,9 +639,11 @@ export function Vector3TripleProduct(a, b, c) {
602
639
  * @returns The reflected vector
603
640
  *
604
641
  * @example
605
- * const incoming = [1, -1, 0];
606
- * const wall = [0, 1, 0]; // vertical wall normal
607
- * const bounced = VectorReflect(incoming, wall); // [1, 1, 0]
642
+ * ```typescript
643
+ * const incoming = [1, -1, 0];
644
+ * const wall = [0, 1, 0]; // vertical wall normal
645
+ * const bounced = VectorReflect(incoming, wall); // [1, 1, 0]
646
+ * ```
608
647
  */
609
648
  export function VectorReflect(incident, normal) {
610
649
  AssertVectors([incident, normal]);
@@ -630,11 +669,12 @@ export function VectorReflect(incident, normal) {
630
669
  * @returns Vector with all components negated
631
670
  *
632
671
  * @example
633
- * const forward = [0, 0, 1];
634
- * const backward = VectorNegate(forward); // [0, 0, -1]
635
- *
636
- * const velocity = [5, -3, 2];
637
- * const opposite = VectorNegate(velocity); // [-5, 3, -2]
672
+ * ```typescript
673
+ * const forward = [0, 0, 1];
674
+ * const backward = VectorNegate(forward); // [0, 0, -1]
675
+ * const velocity = [5, -3, 2];
676
+ * const opposite = VectorNegate(velocity); // [-5, 3, -2]
677
+ * ```
638
678
  */
639
679
  export function VectorNegate(a) {
640
680
  const result = [];
@@ -661,10 +701,12 @@ export function VectorNegate(a) {
661
701
  * @throws {VectorError} If any divisor component is zero
662
702
  *
663
703
  * @example
664
- * const velocity = [20, 10, 0];
665
- * const halved = VectorDivide(velocity, 2); // [10, 5, 0] - scalar division
666
- * const factors = [2, 5, 1];
667
- * const componentWise = VectorDivide(velocity, factors); // [10, 2, 0] - component-wise
704
+ * ```typescript
705
+ * const velocity = [20, 10, 0];
706
+ * const halved = VectorDivide(velocity, 2); // [10, 5, 0] - scalar division
707
+ * const factors = [2, 5, 1];
708
+ * const componentWise = VectorDivide(velocity, factors); // [10, 2, 0] - component-wise
709
+ * ```
668
710
  */
669
711
  export function VectorDivide(a, b) {
670
712
  const result = [];
@@ -705,12 +747,13 @@ export function VectorDivide(a, b) {
705
747
  * @returns New vector with each component clamped between min and max
706
748
  *
707
749
  * @example
708
- * const v = [5, -3, 12, 0];
709
- * VectorClamp(v, 0, 10); // [5, 0, 10, 0] - scalar bounds
710
- *
711
- * const mins = [0, -5, 0, -1];
712
- * const maxs = [10, 5, 8, 1];
713
- * VectorClamp(v, mins, maxs); // [5, -3, 8, 0] - per-component bounds
750
+ * ```typescript
751
+ * const v = [5, -3, 12, 0];
752
+ * VectorClamp(v, 0, 10); // [5, 0, 10, 0] - scalar bounds
753
+ * const mins = [0, -5, 0, -1];
754
+ * const maxs = [10, 5, 8, 1];
755
+ * VectorClamp(v, mins, maxs); // [5, -3, 8, 0] - per-component bounds
756
+ * ```
714
757
  */
715
758
  export function VectorClamp(a, min, max) {
716
759
  AssertVector(a);
@@ -736,44 +779,58 @@ export function VectorClamp(a, min, max) {
736
779
  * @throws {VectorError} If max is negative
737
780
  *
738
781
  * @example
739
- * const velocity = [15, 20, 0]; // magnitude ≈ 25
740
- * const limited = VectorLimit(velocity, 10); // magnitude = 10, same direction
741
- *
742
- * const small = [1, 1, 0]; // magnitude ≈ 1.414
743
- * const unchanged = VectorLimit(small, 5); // unchanged since already under limit
744
- */
745
- export function VectorLimit(a, max) {
746
- if (max < 0)
747
- throw new VectorError('Maximum magnitude cannot be negative');
748
- const magnitude = VectorMagnitude(a);
749
- if (magnitude <= max || magnitude === 0)
750
- return VectorClone(a);
751
- const scaleFactor = max / magnitude;
752
- return VectorMultiply(a, scaleFactor);
753
- }
754
- /**
755
- * Validates if the input is a properly formatted vector.
756
- * Performs comprehensive validation without throwing errors.
757
- * Useful for input validation and defensive programming.
758
- *
759
- * @param vector - Input to validate
760
- * @returns True if input is a valid vector, false otherwise
761
- *
762
- * @example
763
- * const valid = VectorIsValid([1, 2, 3]); // true
764
- * const invalid = VectorIsValid("not a vector"); // false
765
- * const nullVector = VectorIsValid(null); // false
766
- * const emptyArray = VectorIsValid([]); // depends on implementation
767
- */
768
- export function VectorIsValid(vector) {
769
- try {
782
+ * ```typescript
783
+ * const velocity = [15, 20, 0]; // magnitude 25
784
+ * const limited = VectorLimit(velocity, 10); // magnitude = 10, same direction
785
+ * const small = [1, 1, 0]; // magnitude ≈ 1.414
786
+ * const unchanged = VectorLimit(small, 5); // unchanged since already under limit
787
+ * ```
788
+ export function VectorGramSchmidt<T extends TAnyVector>(vectors: T[], normalize: boolean = false): TVectorResult<T>[] {
789
+ if (vectors.length === 0) throw new VectorError('GramSchmidt: Empty Vector Set');
790
+ const [firstVector] = vectors;
791
+ if (!firstVector) throw new VectorError('GramSchmidt: Undefined First Vector');
792
+ const dimension = firstVector.length;
793
+ for (const [i, vector] of vectors.entries()) {
770
794
  AssertVector(vector);
771
- return true;
795
+ if (vector.length !== dimension) throw new VectorError(`GramSchmidt: Vector at index ${i} has different dimension than first vector. Expected ${dimension}, got ${vector.length}`);
796
+ if (VectorIsZero(vector)) throw new VectorError(`GramSchmidt: Vector at index ${i} is a zero vector. Cannot orthogonalize zero vectors.`);
772
797
  }
773
- catch {
774
- return false;
798
+
799
+ const result: TVectorResult<T>[] = [];
800
+
801
+ for (const [i, currentVector] of vectors.entries()) {
802
+ AssertVector(currentVector);
803
+
804
+ // Start with a clone of the current vector
805
+ let orthogonalVector = VectorClone(currentVector);
806
+
807
+ // Subtract projections of all previous vectors
808
+ for (let j = 0; j < i; j++) {
809
+ const previousVector = result[j];
810
+ AssertVector(previousVector);
811
+
812
+ // Both vectors have the same dimension, projection result is compatible
813
+ const vectorT = currentVector as unknown as T;
814
+ const prevT = previousVector as unknown as T;
815
+ const projection = VectorProject(vectorT, prevT);
816
+ orthogonalVector = VectorSubtract(orthogonalVector as unknown as T, projection as unknown as T);
817
+ }
818
+
819
+ if (VectorIsZero(orthogonalVector as unknown as T)) {
820
+ throw new VectorError(`GramSchmidt: Vector at index ${i} is linearly dependent on previous vectors. Cannot orthogonalize linearly dependent vectors.`);
821
+ }
822
+
823
+ if (normalize) {
824
+ orthogonalVector = VectorNormalize(orthogonalVector as unknown as T);
825
+ }
826
+
827
+ result.push(orthogonalVector as TVectorResult<T>);
775
828
  }
829
+
830
+ return result;
831
+ }}
776
832
  }
833
+
777
834
  /**
778
835
  * Performs Gram-Schmidt orthogonalization on a set of vectors.
779
836
  * Converts a set of linearly independent vectors into an orthogonal (or orthonormal) set.
@@ -786,9 +843,11 @@ export function VectorIsValid(vector) {
786
843
  * @throws {VectorError} If vectors are linearly dependent or invalid
787
844
  *
788
845
  * @example
789
- * const vectors = [[1, 1, 0], [1, 0, 1], [0, 1, 1]];
790
- * const orthogonal = VectorGramSchmidt(vectors); // Orthogonal set
791
- * const orthonormal = VectorGramSchmidt(vectors, true); // Orthonormal set
846
+ * ```typescript
847
+ * const vectors = [[1, 1, 0], [1, 0, 1], [0, 1, 1]];
848
+ * const orthogonal = VectorGramSchmidt(vectors); // Orthogonal set
849
+ * const orthonormal = VectorGramSchmidt(vectors, true); // Orthonormal set
850
+ * ```
792
851
  */
793
852
  export function VectorGramSchmidt(vectors, normalize = false) {
794
853
  if (vectors.length === 0)