@pawells/math-extended 1.0.1
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/LICENSE +21 -0
- package/README.md +319 -0
- package/build/angles.d.ts +31 -0
- package/build/angles.d.ts.map +1 -0
- package/build/angles.js +85 -0
- package/build/angles.js.map +1 -0
- package/build/angles.spec.d.ts +2 -0
- package/build/angles.spec.d.ts.map +1 -0
- package/build/angles.spec.js +147 -0
- package/build/angles.spec.js.map +1 -0
- package/build/clamp.d.ts +17 -0
- package/build/clamp.d.ts.map +1 -0
- package/build/clamp.js +19 -0
- package/build/clamp.js.map +1 -0
- package/build/clamp.spec.d.ts +2 -0
- package/build/clamp.spec.d.ts.map +1 -0
- package/build/clamp.spec.js +19 -0
- package/build/clamp.spec.js.map +1 -0
- package/build/documentation-validation.spec.d.ts +11 -0
- package/build/documentation-validation.spec.d.ts.map +1 -0
- package/build/documentation-validation.spec.js +401 -0
- package/build/documentation-validation.spec.js.map +1 -0
- package/build/index.d.ts +8 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +8 -0
- package/build/index.js.map +1 -0
- package/build/interpolation.d.ts +175 -0
- package/build/interpolation.d.ts.map +1 -0
- package/build/interpolation.js +369 -0
- package/build/interpolation.js.map +1 -0
- package/build/interpolation.spec.d.ts +2 -0
- package/build/interpolation.spec.d.ts.map +1 -0
- package/build/interpolation.spec.js +480 -0
- package/build/interpolation.spec.js.map +1 -0
- package/build/matrices/arithmetic.d.ts +411 -0
- package/build/matrices/arithmetic.d.ts.map +1 -0
- package/build/matrices/arithmetic.js +954 -0
- package/build/matrices/arithmetic.js.map +1 -0
- package/build/matrices/arithmetic.spec.d.ts +2 -0
- package/build/matrices/arithmetic.spec.d.ts.map +1 -0
- package/build/matrices/arithmetic.spec.js +915 -0
- package/build/matrices/arithmetic.spec.js.map +1 -0
- package/build/matrices/asserts.d.ts +306 -0
- package/build/matrices/asserts.d.ts.map +1 -0
- package/build/matrices/asserts.js +396 -0
- package/build/matrices/asserts.js.map +1 -0
- package/build/matrices/asserts.spec.d.ts +2 -0
- package/build/matrices/asserts.spec.d.ts.map +1 -0
- package/build/matrices/asserts.spec.js +565 -0
- package/build/matrices/asserts.spec.js.map +1 -0
- package/build/matrices/core.d.ts +168 -0
- package/build/matrices/core.d.ts.map +1 -0
- package/build/matrices/core.js +457 -0
- package/build/matrices/core.js.map +1 -0
- package/build/matrices/core.spec.d.ts +2 -0
- package/build/matrices/core.spec.d.ts.map +1 -0
- package/build/matrices/core.spec.js +634 -0
- package/build/matrices/core.spec.js.map +1 -0
- package/build/matrices/decompositions.d.ts +326 -0
- package/build/matrices/decompositions.d.ts.map +1 -0
- package/build/matrices/decompositions.js +816 -0
- package/build/matrices/decompositions.js.map +1 -0
- package/build/matrices/decompositions.spec.d.ts +2 -0
- package/build/matrices/decompositions.spec.d.ts.map +1 -0
- package/build/matrices/decompositions.spec.js +195 -0
- package/build/matrices/decompositions.spec.js.map +1 -0
- package/build/matrices/index.d.ts +9 -0
- package/build/matrices/index.d.ts.map +1 -0
- package/build/matrices/index.js +9 -0
- package/build/matrices/index.js.map +1 -0
- package/build/matrices/linear-algebra.d.ts +64 -0
- package/build/matrices/linear-algebra.d.ts.map +1 -0
- package/build/matrices/linear-algebra.js +253 -0
- package/build/matrices/linear-algebra.js.map +1 -0
- package/build/matrices/linear-algebra.spec.d.ts +2 -0
- package/build/matrices/linear-algebra.spec.d.ts.map +1 -0
- package/build/matrices/linear-algebra.spec.js +355 -0
- package/build/matrices/linear-algebra.spec.js.map +1 -0
- package/build/matrices/normalization.d.ts +62 -0
- package/build/matrices/normalization.d.ts.map +1 -0
- package/build/matrices/normalization.js +167 -0
- package/build/matrices/normalization.js.map +1 -0
- package/build/matrices/normalization.spec.d.ts +2 -0
- package/build/matrices/normalization.spec.d.ts.map +1 -0
- package/build/matrices/normalization.spec.js +335 -0
- package/build/matrices/normalization.spec.js.map +1 -0
- package/build/matrices/transformations.d.ts +484 -0
- package/build/matrices/transformations.d.ts.map +1 -0
- package/build/matrices/transformations.js +592 -0
- package/build/matrices/transformations.js.map +1 -0
- package/build/matrices/transformations.spec.d.ts +2 -0
- package/build/matrices/transformations.spec.d.ts.map +1 -0
- package/build/matrices/transformations.spec.js +755 -0
- package/build/matrices/transformations.spec.js.map +1 -0
- package/build/matrices/types.d.ts +134 -0
- package/build/matrices/types.d.ts.map +1 -0
- package/build/matrices/types.js +6 -0
- package/build/matrices/types.js.map +1 -0
- package/build/quaternions/asserts.d.ts +77 -0
- package/build/quaternions/asserts.d.ts.map +1 -0
- package/build/quaternions/asserts.js +175 -0
- package/build/quaternions/asserts.js.map +1 -0
- package/build/quaternions/asserts.spec.d.ts +2 -0
- package/build/quaternions/asserts.spec.d.ts.map +1 -0
- package/build/quaternions/asserts.spec.js +320 -0
- package/build/quaternions/asserts.spec.js.map +1 -0
- package/build/quaternions/conversions.d.ts +73 -0
- package/build/quaternions/conversions.d.ts.map +1 -0
- package/build/quaternions/conversions.js +179 -0
- package/build/quaternions/conversions.js.map +1 -0
- package/build/quaternions/conversions.spec.d.ts +2 -0
- package/build/quaternions/conversions.spec.d.ts.map +1 -0
- package/build/quaternions/conversions.spec.js +344 -0
- package/build/quaternions/conversions.spec.js.map +1 -0
- package/build/quaternions/core.d.ts +203 -0
- package/build/quaternions/core.d.ts.map +1 -0
- package/build/quaternions/core.js +374 -0
- package/build/quaternions/core.js.map +1 -0
- package/build/quaternions/core.spec.d.ts +2 -0
- package/build/quaternions/core.spec.d.ts.map +1 -0
- package/build/quaternions/core.spec.js +294 -0
- package/build/quaternions/core.spec.js.map +1 -0
- package/build/quaternions/index.d.ts +7 -0
- package/build/quaternions/index.d.ts.map +1 -0
- package/build/quaternions/index.js +7 -0
- package/build/quaternions/index.js.map +1 -0
- package/build/quaternions/interpolation.d.ts +54 -0
- package/build/quaternions/interpolation.d.ts.map +1 -0
- package/build/quaternions/interpolation.js +201 -0
- package/build/quaternions/interpolation.js.map +1 -0
- package/build/quaternions/interpolation.spec.d.ts +2 -0
- package/build/quaternions/interpolation.spec.d.ts.map +1 -0
- package/build/quaternions/interpolation.spec.js +64 -0
- package/build/quaternions/interpolation.spec.js.map +1 -0
- package/build/quaternions/predefined.d.ts +36 -0
- package/build/quaternions/predefined.d.ts.map +1 -0
- package/build/quaternions/predefined.js +42 -0
- package/build/quaternions/predefined.js.map +1 -0
- package/build/quaternions/predefined.spec.d.ts +2 -0
- package/build/quaternions/predefined.spec.d.ts.map +1 -0
- package/build/quaternions/predefined.spec.js +35 -0
- package/build/quaternions/predefined.spec.js.map +1 -0
- package/build/quaternions/types.d.ts +55 -0
- package/build/quaternions/types.d.ts.map +1 -0
- package/build/quaternions/types.js +7 -0
- package/build/quaternions/types.js.map +1 -0
- package/build/random.d.ts +66 -0
- package/build/random.d.ts.map +1 -0
- package/build/random.js +115 -0
- package/build/random.js.map +1 -0
- package/build/random.spec.d.ts +2 -0
- package/build/random.spec.d.ts.map +1 -0
- package/build/random.spec.js +267 -0
- package/build/random.spec.js.map +1 -0
- package/build/vectors/asserts.d.ts +182 -0
- package/build/vectors/asserts.d.ts.map +1 -0
- package/build/vectors/asserts.js +285 -0
- package/build/vectors/asserts.js.map +1 -0
- package/build/vectors/asserts.spec.d.ts +2 -0
- package/build/vectors/asserts.spec.d.ts.map +1 -0
- package/build/vectors/asserts.spec.js +260 -0
- package/build/vectors/asserts.spec.js.map +1 -0
- package/build/vectors/core.d.ts +507 -0
- package/build/vectors/core.d.ts.map +1 -0
- package/build/vectors/core.js +825 -0
- package/build/vectors/core.js.map +1 -0
- package/build/vectors/core.spec.d.ts +2 -0
- package/build/vectors/core.spec.d.ts.map +1 -0
- package/build/vectors/core.spec.js +343 -0
- package/build/vectors/core.spec.js.map +1 -0
- package/build/vectors/index.d.ts +6 -0
- package/build/vectors/index.d.ts.map +1 -0
- package/build/vectors/index.js +6 -0
- package/build/vectors/index.js.map +1 -0
- package/build/vectors/interpolation.d.ts +404 -0
- package/build/vectors/interpolation.d.ts.map +1 -0
- package/build/vectors/interpolation.js +585 -0
- package/build/vectors/interpolation.js.map +1 -0
- package/build/vectors/interpolation.spec.d.ts +2 -0
- package/build/vectors/interpolation.spec.d.ts.map +1 -0
- package/build/vectors/interpolation.spec.js +378 -0
- package/build/vectors/interpolation.spec.js.map +1 -0
- package/build/vectors/predefined.d.ts +191 -0
- package/build/vectors/predefined.d.ts.map +1 -0
- package/build/vectors/predefined.js +191 -0
- package/build/vectors/predefined.js.map +1 -0
- package/build/vectors/predefined.spec.d.ts +2 -0
- package/build/vectors/predefined.spec.d.ts.map +1 -0
- package/build/vectors/predefined.spec.js +333 -0
- package/build/vectors/predefined.spec.js.map +1 -0
- package/build/vectors/types.d.ts +62 -0
- package/build/vectors/types.d.ts.map +1 -0
- package/build/vectors/types.js +6 -0
- package/build/vectors/types.js.map +1 -0
- package/package.json +75 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Phillip Aaron Wells
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
# Math Extended
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@pawells/math-extended)
|
|
4
|
+
[](https://github.com/PhillipAWells/math-extended/releases)
|
|
5
|
+
[](https://github.com/PhillipAWells/math-extended/actions/workflows/ci.yml)
|
|
6
|
+
[](https://nodejs.org)
|
|
7
|
+
[](./LICENSE)
|
|
8
|
+
[](https://github.com/sponsors/PhillipAWells)
|
|
9
|
+
|
|
10
|
+
Shared TypeScript math library — vectors, matrices, quaternions, interpolation, angles, and random utilities. ESM-only, targets ES2022.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @pawells/math-extended
|
|
16
|
+
# or
|
|
17
|
+
yarn add @pawells/math-extended
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
All exports are available as individual named imports for tree-shaking.
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import {
|
|
26
|
+
VectorAdd, VectorNormalize, VectorDot,
|
|
27
|
+
MatrixMultiply, MatrixRotation3D,
|
|
28
|
+
QuaternionSLERP, QuaternionFromEuler,
|
|
29
|
+
LinearInterpolation, SmoothStep,
|
|
30
|
+
DegreesToRadians, RandomFloat,
|
|
31
|
+
} from '@pawells/math-extended';
|
|
32
|
+
|
|
33
|
+
// Vector math
|
|
34
|
+
const a = VectorAdd([1, 0, 0], [0, 1, 0]); // [1, 1, 0]
|
|
35
|
+
const n = VectorNormalize([3, 4, 0]); // [0.6, 0.8, 0]
|
|
36
|
+
|
|
37
|
+
// Interpolation
|
|
38
|
+
const v = SmoothStep(0, 10, 0.5); // 5
|
|
39
|
+
|
|
40
|
+
// Angles
|
|
41
|
+
const rad = DegreesToRadians(180); // Math.PI
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## API
|
|
45
|
+
|
|
46
|
+
### Angles
|
|
47
|
+
|
|
48
|
+
| Export | Description |
|
|
49
|
+
|--------|-------------|
|
|
50
|
+
| `DegreesToRadians(degrees)` | Convert degrees to radians |
|
|
51
|
+
| `RadiansToDegrees(radians)` | Convert radians to degrees |
|
|
52
|
+
| `NormalizeRadians(radians)` | Normalize to `[0, 2π)` |
|
|
53
|
+
| `NormalizeDegrees(degrees)` | Normalize to `[0°, 360°)` |
|
|
54
|
+
| `FormatRadians(radians)` | Format radians as a human-readable string |
|
|
55
|
+
|
|
56
|
+
### Clamp
|
|
57
|
+
|
|
58
|
+
| Export | Description |
|
|
59
|
+
|--------|-------------|
|
|
60
|
+
| `Clamp(x, min, max)` | Clamp a number between min and max |
|
|
61
|
+
|
|
62
|
+
### Random
|
|
63
|
+
|
|
64
|
+
| Export | Description |
|
|
65
|
+
|--------|-------------|
|
|
66
|
+
| `RandomInt(min, max)` | Random integer in `[min, max]` |
|
|
67
|
+
| `RandomFloat(min, max)` | Random float in `[min, max)` |
|
|
68
|
+
| `RandomBool(probability?)` | Random boolean with optional probability |
|
|
69
|
+
| `RandomNormal(mean?, stdDev?)` | Normal-distributed random number |
|
|
70
|
+
| `RandomChoice(array)` | Random element from an array |
|
|
71
|
+
| `RandomSample(array, count)` | `count` unique random elements |
|
|
72
|
+
| `RandomShuffle(array, clone?)` | Shuffle an array (in-place or cloned) |
|
|
73
|
+
|
|
74
|
+
### Interpolation
|
|
75
|
+
|
|
76
|
+
All interpolation functions share the signature `(a, b, t)`. `t` is typically in `[0, 1]`, but some functions (e.g. elastic, back, bounce, splines) may accept or produce values outside that range.
|
|
77
|
+
|
|
78
|
+
| Export | Description |
|
|
79
|
+
|--------|-------------|
|
|
80
|
+
| `LinearInterpolation` | Linear interpolation (LERP) |
|
|
81
|
+
| `SmoothStep` | Cubic smooth-step |
|
|
82
|
+
| `SmootherStep` | Quintic smoother-step |
|
|
83
|
+
| `CosineInterpolation` | Cosine interpolation |
|
|
84
|
+
| `CatmullRomInterpolation` | Catmull-Rom spline `(p0, p1, p2, p3, t)` |
|
|
85
|
+
| `HermiteInterpolation` | Hermite spline `(p0, p1, t0, t1, t)` |
|
|
86
|
+
| `SphericalLinearInterpolation` | Shortest-arc scalar SLERP |
|
|
87
|
+
| `StepInterpolation` | Step function with configurable threshold |
|
|
88
|
+
| `QuadraticEaseIn/Out/InOut` | Quadratic easing |
|
|
89
|
+
| `CubicEaseIn/Out/InOut` | Cubic easing |
|
|
90
|
+
| `SineEaseIn/Out/InOut` | Sine easing |
|
|
91
|
+
| `ExponentialEaseIn/Out/InOut` | Exponential easing |
|
|
92
|
+
| `CircularEaseIn/Out/InOut` | Circular easing |
|
|
93
|
+
| `ElasticEaseIn/Out/InOut` | Elastic easing |
|
|
94
|
+
| `BackEaseIn/Out/InOut` | Back (overshoot) easing |
|
|
95
|
+
| `BounceEaseIn/Out/InOut` | Bounce easing |
|
|
96
|
+
|
|
97
|
+
### Vectors
|
|
98
|
+
|
|
99
|
+
Vectors are plain number arrays (`TVector`, `TVector2`, `TVector3`, `TVector4`). All operations return new vectors.
|
|
100
|
+
|
|
101
|
+
#### Core operations
|
|
102
|
+
|
|
103
|
+
| Export | Description |
|
|
104
|
+
|--------|-------------|
|
|
105
|
+
| `VectorAdd(a, b)` | Component-wise addition |
|
|
106
|
+
| `VectorSubtract(a, b)` | Component-wise subtraction |
|
|
107
|
+
| `VectorMultiply(a, b)` | Scalar or component-wise multiplication |
|
|
108
|
+
| `VectorDivide(a, b)` | Scalar or component-wise division |
|
|
109
|
+
| `VectorNegate(a)` | Negate all components |
|
|
110
|
+
| `VectorAbs(a)` | Absolute value of each component |
|
|
111
|
+
| `VectorDot(a, b)` | Dot product |
|
|
112
|
+
| `VectorMagnitude(a)` | Vector length |
|
|
113
|
+
| `VectorNormalize(a)` | Unit vector |
|
|
114
|
+
| `VectorDistance(a, b)` | Euclidean distance |
|
|
115
|
+
| `VectorDistanceSquared(a, b)` | Squared distance (avoids sqrt) |
|
|
116
|
+
| `VectorAngle(a, b)` | Angle between two vectors (radians) |
|
|
117
|
+
| `VectorReflect(a, normal)` | Reflection about a normal |
|
|
118
|
+
| `VectorProject(a, b)` | Projection of `a` onto `b` |
|
|
119
|
+
| `VectorClamp(a, min, max)` | Clamp each component |
|
|
120
|
+
| `VectorLimit(a, max)` | Limit magnitude |
|
|
121
|
+
| `VectorLERP(a, b, t)` | Linear interpolation |
|
|
122
|
+
| `VectorClone(a)` | Deep copy |
|
|
123
|
+
| `VectorEquals(a, b)` | Equality check |
|
|
124
|
+
| `VectorIsZero(a)` | Check if zero vector |
|
|
125
|
+
| `VectorIsValid(v)` | Type-guard validation |
|
|
126
|
+
| `VectorToString(a)` | Human-readable string |
|
|
127
|
+
| `VectorMap(a, fn)` | Map a function over components |
|
|
128
|
+
| `VectorGramSchmidt(vectors, normalize?)` | Gram-Schmidt orthogonalization |
|
|
129
|
+
|
|
130
|
+
#### 2D / 3D extras
|
|
131
|
+
|
|
132
|
+
| Export | Description |
|
|
133
|
+
|--------|-------------|
|
|
134
|
+
| `Vector2Cross(a, b)` | 2D cross product (scalar) |
|
|
135
|
+
| `Vector2Rotate(v, angle)` | Rotate a 2D vector |
|
|
136
|
+
| `Vector2FromAngle(angle)` | Unit vector from angle |
|
|
137
|
+
| `Vector3Cross(a, b)` | 3D cross product |
|
|
138
|
+
| `Vector3Reflect(a, normal)` | 3D reflection |
|
|
139
|
+
| `Vector3TripleProduct(a, b, c)` | Vector triple product |
|
|
140
|
+
| `Vector3ScalarTripleProduct(a, b, c)` | Scalar triple product |
|
|
141
|
+
|
|
142
|
+
#### Predefined vectors
|
|
143
|
+
|
|
144
|
+
`VectorZero`, `VectorOne`, `Vector2Up/Down/Left/Right`, `Vector3Up/Down/Left/Right/Forward/Backward`, `Vector4Up/Down/Left/Right/Forward/Backward`
|
|
145
|
+
|
|
146
|
+
#### Interpolation wrappers
|
|
147
|
+
|
|
148
|
+
Every scalar easing function has a `Vector*` counterpart (e.g., `VectorSmoothStep`, `VectorCubicEaseIn`, `VectorSLERP`, …) that interpolates component-wise.
|
|
149
|
+
|
|
150
|
+
#### Assertions
|
|
151
|
+
|
|
152
|
+
`AssertVector`, `AssertVector2`, `AssertVector3`, `AssertVector4`, `AssertVectorValue`, `AssertVectors`, `VectorError`
|
|
153
|
+
|
|
154
|
+
### Matrices
|
|
155
|
+
|
|
156
|
+
Matrices are `number[][]` arrays (`IMatrix`, `IMatrix1`–`IMatrix4`). All operations return new matrices.
|
|
157
|
+
|
|
158
|
+
#### Core
|
|
159
|
+
|
|
160
|
+
| Export | Description |
|
|
161
|
+
|--------|-------------|
|
|
162
|
+
| `MatrixCreate(rows, cols)` | Zero-filled matrix (typed overloads for 1×1–4×4) |
|
|
163
|
+
| `MatrixIdentity(n)` | Identity matrix |
|
|
164
|
+
| `MatrixClone(m)` | Deep copy |
|
|
165
|
+
| `MatrixEquals(a, b)` | Equality check |
|
|
166
|
+
| `MatrixIsValid(m)` | Validation without throwing |
|
|
167
|
+
| `MatrixIsSquare(m)` | Square check |
|
|
168
|
+
| `MatrixIsIdentity(m)` | Identity check |
|
|
169
|
+
| `MatrixIsSymmetric(m)` | Symmetry check |
|
|
170
|
+
| `MatrixIsDiagonal(m)` | Diagonal check |
|
|
171
|
+
| `MatrixIsZero(m)` | Zero-matrix check |
|
|
172
|
+
| `MatrixSize(m)` | `[rows, cols]` tuple |
|
|
173
|
+
| `MatrixSizeSquare(m)` | `n` for an `n×n` matrix |
|
|
174
|
+
| `MatrixTranspose(m)` | Transpose |
|
|
175
|
+
| `MatrixTrace(m)` | Sum of diagonal elements |
|
|
176
|
+
| `MatrixToString(m)` | Human-readable string |
|
|
177
|
+
| `MatrixMap(m, fn)` | Map a function over every element |
|
|
178
|
+
|
|
179
|
+
#### Arithmetic
|
|
180
|
+
|
|
181
|
+
| Export | Description |
|
|
182
|
+
|--------|-------------|
|
|
183
|
+
| `MatrixAdd(a, b)` | Element-wise addition |
|
|
184
|
+
| `MatrixSubtract(a, b)` | Element-wise subtraction |
|
|
185
|
+
| `MatrixMultiply(a, b)` | Matrix × matrix / vector / scalar (auto-dispatch) |
|
|
186
|
+
| `MatrixSubmatrix(m, col, row, w, h)` | Extract a rectangular region |
|
|
187
|
+
| `MatrixPad(m, rows, cols)` | Zero-pad to target dimensions |
|
|
188
|
+
| `MatrixCombine(c11, c12, c21, c22)` | Assemble four quadrant blocks |
|
|
189
|
+
|
|
190
|
+
#### Linear algebra
|
|
191
|
+
|
|
192
|
+
| Export | Description |
|
|
193
|
+
|--------|-------------|
|
|
194
|
+
| `MatrixDeterminant(m)` | Determinant |
|
|
195
|
+
| `MatrixInverse(m)` | Matrix inverse |
|
|
196
|
+
| `MatrixRank(m)` | Rank |
|
|
197
|
+
| `MatrixMinor(m, row, col)` | Minor |
|
|
198
|
+
| `MatrixCofactor(m, row, col)` | Cofactor |
|
|
199
|
+
| `MatrixAdjoint(m)` | Adjugate (classical adjoint) |
|
|
200
|
+
| `MatrixGramSchmidt(m)` | Gram-Schmidt orthogonalization |
|
|
201
|
+
|
|
202
|
+
#### Decompositions
|
|
203
|
+
|
|
204
|
+
| Export | Description |
|
|
205
|
+
|--------|-------------|
|
|
206
|
+
| `MatrixLU(m)` | LU decomposition `{ L, U }` |
|
|
207
|
+
| `MatrixQR(m)` | QR decomposition `{ Q, R }` |
|
|
208
|
+
| `MatrixCholesky(m)` | Cholesky decomposition `L` |
|
|
209
|
+
| `MatrixEigen(m)` | Eigenvalue decomposition `{ eigenvalues, eigenvectors }` |
|
|
210
|
+
| `MatrixSVD(m)` | Singular value decomposition `{ U, S, VT }` |
|
|
211
|
+
| `MatrixSolve(a, b)` | Solve `Ax = b` |
|
|
212
|
+
|
|
213
|
+
#### Normalization
|
|
214
|
+
|
|
215
|
+
| Export | Description |
|
|
216
|
+
|--------|-------------|
|
|
217
|
+
| `MatrixFrobeniusNorm(m)` | Frobenius norm |
|
|
218
|
+
| `Matrix1Norm(m)` | Column-sum (1-norm) |
|
|
219
|
+
| `MatrixInfinityNorm(m)` | Row-sum (∞-norm) |
|
|
220
|
+
| `MatrixMaxNorm(m)` | Max absolute element |
|
|
221
|
+
| `MatrixNuclearNorm(m)` | Nuclear norm (sum of singular values) |
|
|
222
|
+
| `MatrixSpectralNorm(m)` | Spectral norm (largest singular value) |
|
|
223
|
+
| `MatrixPNorm(m, p)` | Generalized p-norm |
|
|
224
|
+
|
|
225
|
+
#### Transformations
|
|
226
|
+
|
|
227
|
+
| Export | Description |
|
|
228
|
+
|--------|-------------|
|
|
229
|
+
| `MatrixTranslation2D(tx, ty)` | 2D translation matrix |
|
|
230
|
+
| `MatrixTranslation3D(tx, ty, tz)` | 3D translation matrix |
|
|
231
|
+
| `MatrixScale2D(sx, sy)` | 2D scale matrix |
|
|
232
|
+
| `MatrixScale3D(sx, sy, sz)` | 3D scale matrix |
|
|
233
|
+
| `MatrixRotation2D(angle)` | 2D rotation matrix |
|
|
234
|
+
| `MatrixRotation3D(axis, angle)` | 3D rotation around an axis |
|
|
235
|
+
| `MatrixRotation3DPitch/Yaw/Roll(angle)` | Axis-specific 3D rotations |
|
|
236
|
+
| `MatrixRotation3DEulerAngles(...)` | Euler-angles rotation matrix |
|
|
237
|
+
| `MatrixTransform2D(...)` | Combined 2D TRS matrix |
|
|
238
|
+
| `MatrixTransform3D(...)` | Combined 3D TRS matrix |
|
|
239
|
+
| `MatrixDirection3D(forward, up)` | Look-at direction matrix |
|
|
240
|
+
| `MatrixPerspective(fov, aspect, near, far)` | Perspective projection |
|
|
241
|
+
| `MatrixOrthographic(...)` | Orthographic projection |
|
|
242
|
+
| `MatrixView(eye, target, up)` | View/look-at matrix |
|
|
243
|
+
|
|
244
|
+
#### Assertions
|
|
245
|
+
|
|
246
|
+
`AssertMatrix`, `AssertMatrix1`–`AssertMatrix4`, `AssertMatrixRow`, `AssertMatrixValue`, `AssertMatrices`, `MatrixError`
|
|
247
|
+
|
|
248
|
+
### Quaternions
|
|
249
|
+
|
|
250
|
+
Quaternions are `[x, y, z, w]` tuples (`TQuaternion`).
|
|
251
|
+
|
|
252
|
+
#### Core
|
|
253
|
+
|
|
254
|
+
| Export | Description |
|
|
255
|
+
|--------|-------------|
|
|
256
|
+
| `QuaternionMultiply(a, b)` | Hamilton product |
|
|
257
|
+
| `QuaternionConjugate(q)` | Conjugate |
|
|
258
|
+
| `QuaternionInverse(q)` | Inverse |
|
|
259
|
+
| `QuaternionNormalize(q)` | Unit quaternion |
|
|
260
|
+
| `QuaternionMagnitude(q)` | Length |
|
|
261
|
+
| `QuaternionEquals(a, b)` | Equality check |
|
|
262
|
+
| `QuaternionClone(q)` | Deep copy |
|
|
263
|
+
| `QuaternionRotateVector(q, v)` | Rotate a vector by a quaternion |
|
|
264
|
+
|
|
265
|
+
#### Predefined
|
|
266
|
+
|
|
267
|
+
| Export | Description |
|
|
268
|
+
|--------|-------------|
|
|
269
|
+
| `QuaternionIdentity()` | Identity quaternion `[0,0,0,1]` |
|
|
270
|
+
| `QuaternionRotationX/Y/Z(angle)` | Axis-aligned rotation quaternions |
|
|
271
|
+
|
|
272
|
+
#### Conversions
|
|
273
|
+
|
|
274
|
+
| Export | Description |
|
|
275
|
+
|--------|-------------|
|
|
276
|
+
| `QuaternionFromEuler(roll, pitch, yaw)` | Euler angles → quaternion |
|
|
277
|
+
| `QuaternionToEuler(q)` | Quaternion → `TEulerAngles` |
|
|
278
|
+
| `QuaternionFromAxisAngle(axis, angle)` | Axis-angle → quaternion |
|
|
279
|
+
| `QuaternionToAxisAngle(q)` | Quaternion → `TAxisAngle` |
|
|
280
|
+
| `QuaternionFromRotationMatrix(m)` | 3×3 rotation matrix → quaternion |
|
|
281
|
+
| `QuaternionToRotationMatrix(q)` | Quaternion → 3×3 rotation matrix |
|
|
282
|
+
| `QuaternionFromTransformationMatrix(m)` | 4×4 transform matrix → quaternion |
|
|
283
|
+
| `QuaternionToTransformationMatrix(q)` | Quaternion → 4×4 transform matrix |
|
|
284
|
+
|
|
285
|
+
#### Interpolation
|
|
286
|
+
|
|
287
|
+
| Export | Description |
|
|
288
|
+
|--------|-------------|
|
|
289
|
+
| `QuaternionSLERP(a, b, t)` | Spherical linear interpolation |
|
|
290
|
+
| `QuaternionNLERP(a, b, t)` | Normalized linear interpolation |
|
|
291
|
+
| `QuaternionSQUAD(q0, q1, s1, s2, t)` | Spherical cubic spline |
|
|
292
|
+
| `QuaternionCreatePath(qs)` | Pre-compute SQUAD control points |
|
|
293
|
+
|
|
294
|
+
#### Assertions
|
|
295
|
+
|
|
296
|
+
`AssertQuaternion`, `AssertQuaternions`, `AssertNormalizedQuaternion`, `AssertAxisAngle`, `AssertEulerAngles`, `AssertRotationMatrix`, `QuaternionError`
|
|
297
|
+
|
|
298
|
+
## Development
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
yarn install # Install dependencies
|
|
302
|
+
yarn build # Compile TypeScript → ./build/
|
|
303
|
+
yarn dev # Build + run
|
|
304
|
+
yarn watch # Watch mode
|
|
305
|
+
yarn typecheck # Type check without building
|
|
306
|
+
yarn lint # ESLint
|
|
307
|
+
yarn lint:fix # ESLint with auto-fix
|
|
308
|
+
yarn test # Run tests (1077 tests)
|
|
309
|
+
yarn test:ui # Interactive Vitest UI
|
|
310
|
+
yarn test:coverage # Tests with coverage report
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## Requirements
|
|
314
|
+
|
|
315
|
+
- Node.js >= 24.0.0
|
|
316
|
+
|
|
317
|
+
## License
|
|
318
|
+
|
|
319
|
+
MIT — See [LICENSE](./LICENSE) for details.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts degrees to radians
|
|
3
|
+
* @param degrees - Angle in degrees
|
|
4
|
+
* @returns Angle in radians
|
|
5
|
+
*/
|
|
6
|
+
export declare function DegreesToRadians(degrees: number): number;
|
|
7
|
+
/**
|
|
8
|
+
* Converts radians to degrees
|
|
9
|
+
* @param radians - Angle in radians
|
|
10
|
+
* @returns Angle in degrees
|
|
11
|
+
*/
|
|
12
|
+
export declare function RadiansToDegrees(radians: number): number;
|
|
13
|
+
/**
|
|
14
|
+
* Formats an angle in radians to a string representation in terms of π
|
|
15
|
+
* @param radians - Angle in radians
|
|
16
|
+
* @returns String representation of the angle
|
|
17
|
+
*/
|
|
18
|
+
export declare function FormatRadians(radians: number): string;
|
|
19
|
+
/**
|
|
20
|
+
* Normalizes an angle in radians to be between 0 and 2π
|
|
21
|
+
* @param radians - Angle in radians
|
|
22
|
+
* @returns Normalized angle in radians (0 to 2π)
|
|
23
|
+
*/
|
|
24
|
+
export declare function NormalizeRadians(radians: number): number;
|
|
25
|
+
/**
|
|
26
|
+
* Normalizes an angle in degrees to be between 0 and 360
|
|
27
|
+
* @param degrees - Angle in degrees
|
|
28
|
+
* @returns Normalized angle in degrees (0 to 360)
|
|
29
|
+
*/
|
|
30
|
+
export declare function NormalizeDegrees(degrees: number): number;
|
|
31
|
+
//# sourceMappingURL=angles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"angles.d.ts","sourceRoot":"","sources":["../src/angles.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAsCrD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGxD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD"}
|
package/build/angles.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
const DEGREES_PER_HALF_REVOLUTION = 180;
|
|
2
|
+
const DEGREES_PER_FULL_REVOLUTION = 360;
|
|
3
|
+
const ANGLE_FRACTION_DENOMINATOR_3 = 3;
|
|
4
|
+
const ANGLE_FRACTION_DENOMINATOR_6 = 6;
|
|
5
|
+
const ANGLE_FRACTION_QUARTER = 0.25;
|
|
6
|
+
const ANGLE_FRACTION_THREE_QUARTERS = 0.75;
|
|
7
|
+
const ANGLE_FRACTION_TOLERANCE = 0.0001;
|
|
8
|
+
const ANGLE_MAX_DENOMINATOR = 12;
|
|
9
|
+
/**
|
|
10
|
+
* Converts degrees to radians
|
|
11
|
+
* @param degrees - Angle in degrees
|
|
12
|
+
* @returns Angle in radians
|
|
13
|
+
*/
|
|
14
|
+
export function DegreesToRadians(degrees) {
|
|
15
|
+
return (degrees * Math.PI) / DEGREES_PER_HALF_REVOLUTION;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Converts radians to degrees
|
|
19
|
+
* @param radians - Angle in radians
|
|
20
|
+
* @returns Angle in degrees
|
|
21
|
+
*/
|
|
22
|
+
export function RadiansToDegrees(radians) {
|
|
23
|
+
return (radians * DEGREES_PER_HALF_REVOLUTION) / Math.PI;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Formats an angle in radians to a string representation in terms of π
|
|
27
|
+
* @param radians - Angle in radians
|
|
28
|
+
* @returns String representation of the angle
|
|
29
|
+
*/
|
|
30
|
+
export function FormatRadians(radians) {
|
|
31
|
+
const r = radians / Math.PI;
|
|
32
|
+
if (r === 0)
|
|
33
|
+
return '0';
|
|
34
|
+
if (r === 1)
|
|
35
|
+
return 'π';
|
|
36
|
+
if (r === -1)
|
|
37
|
+
return '-π';
|
|
38
|
+
// Handle common fractions of π
|
|
39
|
+
const fractions = [
|
|
40
|
+
{ value: 1 / 2, str: 'π/2' },
|
|
41
|
+
{ value: ANGLE_FRACTION_QUARTER, str: 'π/4' },
|
|
42
|
+
{ value: ANGLE_FRACTION_THREE_QUARTERS, str: '3π/4' },
|
|
43
|
+
{ value: 1 / ANGLE_FRACTION_DENOMINATOR_6, str: 'π/6' },
|
|
44
|
+
{ value: 1 / ANGLE_FRACTION_DENOMINATOR_3, str: 'π/3' },
|
|
45
|
+
{ value: 2 / ANGLE_FRACTION_DENOMINATOR_3, str: '2π/3' },
|
|
46
|
+
];
|
|
47
|
+
for (const fraction of fractions) {
|
|
48
|
+
if (Math.abs(r - fraction.value) < ANGLE_FRACTION_TOLERANCE)
|
|
49
|
+
return fraction.str;
|
|
50
|
+
if (Math.abs(r + fraction.value) < ANGLE_FRACTION_TOLERANCE)
|
|
51
|
+
return '-' + fraction.str;
|
|
52
|
+
}
|
|
53
|
+
// Try to find a simple fraction representation
|
|
54
|
+
const tolerance = ANGLE_FRACTION_TOLERANCE;
|
|
55
|
+
for (let denominator = 2; denominator <= ANGLE_MAX_DENOMINATOR; denominator++) {
|
|
56
|
+
for (let numerator = 1; numerator < denominator; numerator++) {
|
|
57
|
+
const frac = numerator / denominator;
|
|
58
|
+
if (Math.abs(r - frac) < tolerance) {
|
|
59
|
+
return `${numerator === 1 ? '' : numerator}π/${denominator}`;
|
|
60
|
+
}
|
|
61
|
+
if (Math.abs(r + frac) < tolerance) {
|
|
62
|
+
return `-${numerator === 1 ? '' : numerator}π/${denominator}`;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return `${r}π`;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Normalizes an angle in radians to be between 0 and 2π
|
|
70
|
+
* @param radians - Angle in radians
|
|
71
|
+
* @returns Normalized angle in radians (0 to 2π)
|
|
72
|
+
*/
|
|
73
|
+
export function NormalizeRadians(radians) {
|
|
74
|
+
const twoPi = 2 * Math.PI;
|
|
75
|
+
return ((radians % twoPi) + twoPi) % twoPi;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Normalizes an angle in degrees to be between 0 and 360
|
|
79
|
+
* @param degrees - Angle in degrees
|
|
80
|
+
* @returns Normalized angle in degrees (0 to 360)
|
|
81
|
+
*/
|
|
82
|
+
export function NormalizeDegrees(degrees) {
|
|
83
|
+
return ((degrees % DEGREES_PER_FULL_REVOLUTION) + DEGREES_PER_FULL_REVOLUTION) % DEGREES_PER_FULL_REVOLUTION;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=angles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"angles.js","sourceRoot":"","sources":["../src/angles.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"angles.spec.d.ts","sourceRoot":"","sources":["../src/angles.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { DegreesToRadians, RadiansToDegrees, FormatRadians, NormalizeRadians, NormalizeDegrees, } from './angles.ts';
|
|
2
|
+
describe('Math Extended > Angles', () => {
|
|
3
|
+
test('Degrees to Radians', () => {
|
|
4
|
+
expect(DegreesToRadians(0)).toBe(0);
|
|
5
|
+
expect(DegreesToRadians(90)).toBe(Math.PI / 2);
|
|
6
|
+
expect(DegreesToRadians(180)).toBe(Math.PI);
|
|
7
|
+
expect(DegreesToRadians(270)).toBe((3 * Math.PI) / 2);
|
|
8
|
+
expect(DegreesToRadians(360)).toBe(2 * Math.PI);
|
|
9
|
+
expect(DegreesToRadians(-45)).toBe(-Math.PI / 4);
|
|
10
|
+
// Test decimal values
|
|
11
|
+
expect(DegreesToRadians(45.5)).toBeCloseTo(Math.PI * 0.25278);
|
|
12
|
+
// Test large values
|
|
13
|
+
expect(DegreesToRadians(3600)).toBe(20 * Math.PI);
|
|
14
|
+
});
|
|
15
|
+
test('Radians to Degrees', () => {
|
|
16
|
+
expect(RadiansToDegrees(0)).toBe(0);
|
|
17
|
+
expect(RadiansToDegrees(Math.PI / 2)).toBe(90);
|
|
18
|
+
expect(RadiansToDegrees(Math.PI)).toBe(180);
|
|
19
|
+
expect(RadiansToDegrees((3 * Math.PI) / 2)).toBe(270);
|
|
20
|
+
expect(RadiansToDegrees(2 * Math.PI)).toBe(360);
|
|
21
|
+
expect(RadiansToDegrees(-Math.PI / 4)).toBe(-45);
|
|
22
|
+
// Test decimal values
|
|
23
|
+
expect(RadiansToDegrees(Math.PI / 6)).toBeCloseTo(30);
|
|
24
|
+
// Test large values
|
|
25
|
+
expect(RadiansToDegrees(10 * Math.PI)).toBe(1800);
|
|
26
|
+
});
|
|
27
|
+
test('Format Radians', () => {
|
|
28
|
+
expect(FormatRadians(0)).toBe('0');
|
|
29
|
+
expect(FormatRadians(Math.PI)).toBe('π');
|
|
30
|
+
expect(FormatRadians(-Math.PI)).toBe('-π');
|
|
31
|
+
expect(FormatRadians(Math.PI / 2)).toBe('π/2');
|
|
32
|
+
expect(FormatRadians(Math.PI / 4)).toBe('π/4');
|
|
33
|
+
expect(FormatRadians(Math.PI / 3)).toBe('π/3');
|
|
34
|
+
// Based on the current implementation, this returns "1.5π" rather than "3π/2"
|
|
35
|
+
expect(FormatRadians((3 * Math.PI) / 2)).toContain('π');
|
|
36
|
+
// Additional fraction representations
|
|
37
|
+
expect(FormatRadians(Math.PI / 6)).toBe('π/6');
|
|
38
|
+
expect(FormatRadians((2 * Math.PI) / 3)).toBe('2π/3');
|
|
39
|
+
expect(FormatRadians((3 * Math.PI) / 4)).toContain('π'); // Based on the implementation behavior
|
|
40
|
+
// Edge cases
|
|
41
|
+
expect(FormatRadians(0.00001)).toContain('π'); // Very small value
|
|
42
|
+
expect(FormatRadians(100 * Math.PI)).toContain('π'); // Very large value
|
|
43
|
+
// Common angles - adjust expectations to match the actual implementation
|
|
44
|
+
const formattedAngle = FormatRadians(Math.PI * 1.5);
|
|
45
|
+
expect(formattedAngle === '1.5π' || formattedAngle === '3π/2').toBeTruthy();
|
|
46
|
+
// Value that doesn't have a simple fraction representation
|
|
47
|
+
expect(FormatRadians(Math.PI * 0.7)).toContain('π');
|
|
48
|
+
});
|
|
49
|
+
test('Radian Normalization', () => {
|
|
50
|
+
// Basic cases
|
|
51
|
+
expect(NormalizeRadians(0)).toBe(0);
|
|
52
|
+
expect(NormalizeRadians(Math.PI)).toBeCloseTo(Math.PI);
|
|
53
|
+
expect(NormalizeRadians(2 * Math.PI)).toBeCloseTo(0);
|
|
54
|
+
// Values outside the 0-2π range
|
|
55
|
+
expect(NormalizeRadians(3 * Math.PI)).toBeCloseTo(Math.PI);
|
|
56
|
+
expect(NormalizeRadians(-Math.PI)).toBeCloseTo(Math.PI);
|
|
57
|
+
expect(NormalizeRadians(-2 * Math.PI)).toBeCloseTo(0);
|
|
58
|
+
expect(NormalizeRadians(7 * Math.PI)).toBeCloseTo(Math.PI);
|
|
59
|
+
// Extreme values - these need special handling due to floating point precision
|
|
60
|
+
const normalizedLarge = NormalizeRadians(1000 * Math.PI);
|
|
61
|
+
expect(normalizedLarge >= 0 && normalizedLarge < 2 * Math.PI).toBeTruthy();
|
|
62
|
+
const normalizedNegative = NormalizeRadians(-999 * Math.PI);
|
|
63
|
+
expect(normalizedNegative >= 0 && normalizedNegative < 2 * Math.PI).toBeTruthy();
|
|
64
|
+
// Decimal values
|
|
65
|
+
expect(NormalizeRadians(Math.PI + 0.1)).toBeCloseTo(Math.PI + 0.1);
|
|
66
|
+
expect(NormalizeRadians((2 * Math.PI) + 0.2)).toBeCloseTo(0.2);
|
|
67
|
+
});
|
|
68
|
+
test('Degree Normalization', () => {
|
|
69
|
+
// Basic cases
|
|
70
|
+
expect(NormalizeDegrees(0)).toBe(0);
|
|
71
|
+
expect(NormalizeDegrees(180)).toBe(180);
|
|
72
|
+
expect(NormalizeDegrees(360)).toBe(0);
|
|
73
|
+
// Values outside the 0-360 range
|
|
74
|
+
expect(NormalizeDegrees(540)).toBe(180);
|
|
75
|
+
expect(NormalizeDegrees(-180)).toBe(180);
|
|
76
|
+
expect(NormalizeDegrees(-360)).toBe(0);
|
|
77
|
+
expect(NormalizeDegrees(1260)).toBe(180);
|
|
78
|
+
// Extreme values
|
|
79
|
+
expect(NormalizeDegrees(3600)).toBe(0);
|
|
80
|
+
expect(NormalizeDegrees(-3600)).toBe(0);
|
|
81
|
+
// Decimal values
|
|
82
|
+
expect(NormalizeDegrees(45.5)).toBe(45.5);
|
|
83
|
+
expect(NormalizeDegrees(360.5)).toBe(0.5);
|
|
84
|
+
expect(NormalizeDegrees(-0.5)).toBe(359.5);
|
|
85
|
+
});
|
|
86
|
+
test('Preserve Angles when Normalizing', () => {
|
|
87
|
+
// Create a range of angles
|
|
88
|
+
for (let angle = -720; angle <= 720; angle += 45) {
|
|
89
|
+
// For radians
|
|
90
|
+
const radians = DegreesToRadians(angle);
|
|
91
|
+
const normalizedRadians = NormalizeRadians(radians);
|
|
92
|
+
// Convert back to degrees for comparison
|
|
93
|
+
const backToDegrees = RadiansToDegrees(normalizedRadians);
|
|
94
|
+
const normalizedDegrees = NormalizeDegrees(angle);
|
|
95
|
+
// Check if the angles are equivalent (considering circular nature)
|
|
96
|
+
expect(normalizedDegrees).toBeCloseTo(NormalizeDegrees(backToDegrees));
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
test('Additional Angle Conversions', () => {
|
|
100
|
+
// Test random angles to ensure conversion works correctly in both directions
|
|
101
|
+
for (let i = 0; i < 10; i++) {
|
|
102
|
+
const randomDegrees = (Math.random() * 720) - 360; // Random between -360 and 360
|
|
103
|
+
const toRadians = DegreesToRadians(randomDegrees);
|
|
104
|
+
const backToDegrees = RadiansToDegrees(toRadians);
|
|
105
|
+
expect(backToDegrees).toBeCloseTo(randomDegrees);
|
|
106
|
+
}
|
|
107
|
+
// Test that normalization preserves the angle's position on the circle
|
|
108
|
+
// for non-integer values
|
|
109
|
+
for (let angle = -10.5; angle <= 10.5; angle += 0.5) {
|
|
110
|
+
const normalizedDegrees = NormalizeDegrees(angle * 360);
|
|
111
|
+
const normalizedRadians = NormalizeRadians(angle * 2 * Math.PI);
|
|
112
|
+
const convertedDegrees = RadiansToDegrees(normalizedRadians);
|
|
113
|
+
expect(normalizedDegrees).toBeCloseTo(NormalizeDegrees(convertedDegrees));
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
test('NormalizeRadians covers negative non-multiple of π', () => {
|
|
117
|
+
// -5 radians is not a multiple of π, should normalize to [0, 2π)
|
|
118
|
+
const input = -5;
|
|
119
|
+
const normalized = NormalizeRadians(input);
|
|
120
|
+
expect(normalized).toBeGreaterThanOrEqual(0);
|
|
121
|
+
expect(normalized).toBeLessThan(2 * Math.PI);
|
|
122
|
+
// Check that adding/subtracting 2π lands on the same angle
|
|
123
|
+
const expected = ((input % (2 * Math.PI)) + (2 * Math.PI)) % (2 * Math.PI);
|
|
124
|
+
expect(normalized).toBeCloseTo(expected);
|
|
125
|
+
});
|
|
126
|
+
test('NormalizeRadians covers negative just below zero', () => {
|
|
127
|
+
const input = -0.1;
|
|
128
|
+
const normalized = NormalizeRadians(input);
|
|
129
|
+
expect(normalized).toBeCloseTo((2 * Math.PI) - 0.1);
|
|
130
|
+
});
|
|
131
|
+
test('NormalizeRadians covers positive just above 2π', () => {
|
|
132
|
+
const input = (2 * Math.PI) + 0.1;
|
|
133
|
+
const normalized = NormalizeRadians(input);
|
|
134
|
+
expect(normalized).toBeCloseTo(0.1);
|
|
135
|
+
});
|
|
136
|
+
test('FormatRadians handles π/5', () => {
|
|
137
|
+
const input = Math.PI / 5;
|
|
138
|
+
const formatted = FormatRadians(input);
|
|
139
|
+
expect(formatted).toBe('π/5');
|
|
140
|
+
});
|
|
141
|
+
test('FormatRadians handles -π/5', () => {
|
|
142
|
+
const input = -Math.PI / 5;
|
|
143
|
+
const formatted = FormatRadians(input);
|
|
144
|
+
expect(formatted).toBe('-π/5');
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
//# sourceMappingURL=angles.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"angles.spec.js","sourceRoot":"","sources":["../src/angles.spec.ts"],"names":[],"mappings":"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"}
|
package/build/clamp.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clamps a number between a minimum and maximum value.
|
|
3
|
+
* If `x` is less than `min`, returns `min`. If `x` is greater than `max`, returns `max`.
|
|
4
|
+
* Otherwise returns `x` unchanged.
|
|
5
|
+
*
|
|
6
|
+
* @param x - The value to clamp
|
|
7
|
+
* @param min - Lower bound (inclusive)
|
|
8
|
+
* @param max - Upper bound (inclusive)
|
|
9
|
+
* @returns The clamped value in the range [min, max]
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* Clamp(5, 0, 10) // 5 (within range)
|
|
13
|
+
* Clamp(-3, 0, 10) // 0 (below min)
|
|
14
|
+
* Clamp(15, 0, 10) // 10 (above max)
|
|
15
|
+
*/
|
|
16
|
+
export declare function Clamp(x: number, min: number, max: number): number;
|
|
17
|
+
//# sourceMappingURL=clamp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clamp.d.ts","sourceRoot":"","sources":["../src/clamp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEjE"}
|