glmaths 0.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/README.md +952 -0
- package/benchmark.js +747 -0
- package/dist/cjs/glmaths.d.ts +12053 -0
- package/dist/cjs/glmaths.js +6496 -0
- package/dist/cjs/glmaths.js.map +1 -0
- package/dist/cjs/glmaths.min.js +2 -0
- package/dist/cjs/glmaths.min.js.map +1 -0
- package/dist/esm/glmaths.d.ts +12053 -0
- package/dist/esm/glmaths.js +6453 -0
- package/dist/esm/glmaths.js.map +1 -0
- package/dist/esm/glmaths.min.js +2 -0
- package/dist/esm/glmaths.min.js.map +1 -0
- package/dist/glmaths.d.ts +12053 -0
- package/dist/glmaths.js +6501 -0
- package/dist/glmaths.js.map +1 -0
- package/dist/glmaths.min.js +2 -0
- package/dist/glmaths.min.js.map +1 -0
- package/docs.js +64 -0
- package/package.json +37 -0
- package/rollup.config.js +70 -0
- package/src/index.ts +19 -0
- package/src/internalUtils.ts +78 -0
- package/src/mat2.ts +324 -0
- package/src/mat2x3.ts +328 -0
- package/src/mat3.ts +629 -0
- package/src/mat4.ts +1319 -0
- package/src/quat.ts +819 -0
- package/src/quat2.ts +412 -0
- package/src/utils.ts +248 -0
- package/src/vec2.ts +798 -0
- package/src/vec3.ts +1069 -0
- package/src/vec4.ts +810 -0
- package/tests/mat2.test.ts +277 -0
- package/tests/mat2x3.test.ts +217 -0
- package/tests/mat3.test.ts +306 -0
- package/tests/mat4.test.ts +586 -0
- package/tests/quat.test.ts +418 -0
- package/tests/quat2.test.ts +222 -0
- package/tests/utils.test.ts +115 -0
- package/tests/vec2.test.ts +617 -0
- package/tests/vec3.test.ts +649 -0
- package/tests/vec4.test.ts +390 -0
- package/tsconfig.json +17 -0
- package/tsconfig.test.json +8 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { describe, it } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import glmaths, { Mat2, mat2, Vec2 } from '../dist/esm/glmaths'
|
|
4
|
+
|
|
5
|
+
function closeTo(actual: number, expected: number, numDigits = 5) { const pass = Math.abs(actual - expected) < Math.pow(10, -numDigits) / 2; assert.ok(pass, `expected ${actual} to be close to ${expected}`) }
|
|
6
|
+
|
|
7
|
+
describe('Mat2', () => {
|
|
8
|
+
describe('constructor', () => {
|
|
9
|
+
it('creates zero matrix by default', () => {
|
|
10
|
+
const m = new Mat2()
|
|
11
|
+
assert.strictEqual(m[0], 0)
|
|
12
|
+
assert.strictEqual(m[1], 0)
|
|
13
|
+
assert.strictEqual(m[2], 0)
|
|
14
|
+
assert.strictEqual(m[3], 0)
|
|
15
|
+
})
|
|
16
|
+
it('creates with given values', () => {
|
|
17
|
+
const m = new Mat2(1, 2, 3, 4)
|
|
18
|
+
assert.strictEqual(m[0], 1)
|
|
19
|
+
assert.strictEqual(m[1], 2)
|
|
20
|
+
assert.strictEqual(m[2], 3)
|
|
21
|
+
assert.strictEqual(m[3], 4)
|
|
22
|
+
})
|
|
23
|
+
it('extends Float32Array with length 4', () => {
|
|
24
|
+
assert.ok(new Mat2() instanceof Float32Array)
|
|
25
|
+
assert.strictEqual(new Mat2().length, 4)
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
describe('identity', () => {
|
|
30
|
+
it('creates identity matrix', () => {
|
|
31
|
+
const m = Mat2.identity
|
|
32
|
+
assert.strictEqual(m[0], 1)
|
|
33
|
+
assert.strictEqual(m[1], 0)
|
|
34
|
+
assert.strictEqual(m[2], 0)
|
|
35
|
+
assert.strictEqual(m[3], 1)
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
describe('clone', () => {
|
|
40
|
+
it('creates independent copy', () => {
|
|
41
|
+
const a = new Mat2(1, 2, 3, 4)
|
|
42
|
+
const b = a.clone()
|
|
43
|
+
assert.strictEqual(b[0], 1)
|
|
44
|
+
b[0] = 99
|
|
45
|
+
assert.strictEqual(a[0], 1)
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
describe('transpose', () => {
|
|
50
|
+
it('transposes in-place', () => {
|
|
51
|
+
const m = new Mat2(1, 2, 3, 4)
|
|
52
|
+
const r = m.transpose()
|
|
53
|
+
assert.strictEqual(r[0], 1)
|
|
54
|
+
assert.strictEqual(r[1], 3)
|
|
55
|
+
assert.strictEqual(r[2], 2)
|
|
56
|
+
assert.strictEqual(r[3], 4)
|
|
57
|
+
})
|
|
58
|
+
it('transposes to out', () => {
|
|
59
|
+
const m = new Mat2(1, 2, 3, 4)
|
|
60
|
+
const out = new Mat2()
|
|
61
|
+
m.transpose(out)
|
|
62
|
+
assert.strictEqual(out[0], 1)
|
|
63
|
+
assert.strictEqual(out[1], 3)
|
|
64
|
+
assert.strictEqual(out[2], 2)
|
|
65
|
+
assert.strictEqual(out[3], 4)
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
describe('invert', () => {
|
|
70
|
+
it('inverts a matrix', () => {
|
|
71
|
+
const m = Mat2.identity
|
|
72
|
+
const inv = m.invert()
|
|
73
|
+
assert.notStrictEqual(inv, null)
|
|
74
|
+
assert.strictEqual(m[0], 1)
|
|
75
|
+
assert.strictEqual(m[3], 1)
|
|
76
|
+
})
|
|
77
|
+
it('inverts correctly', () => {
|
|
78
|
+
const m = new Mat2(1, 2, 3, 4)
|
|
79
|
+
const out = new Mat2()
|
|
80
|
+
m.invert(out)
|
|
81
|
+
// m * m^-1 = identity
|
|
82
|
+
const result = m.multiply(out!, new Mat2())
|
|
83
|
+
closeTo(result[0], 1)
|
|
84
|
+
closeTo(result[1], 0)
|
|
85
|
+
closeTo(result[2], 0)
|
|
86
|
+
closeTo(result[3], 1)
|
|
87
|
+
})
|
|
88
|
+
it('returns null for singular matrix', () => {
|
|
89
|
+
const m = new Mat2(1, 2, 2, 4)
|
|
90
|
+
assert.strictEqual(m.invert(new Mat2()), null)
|
|
91
|
+
})
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
describe('adjoint', () => {
|
|
95
|
+
it('calculates adjugate', () => {
|
|
96
|
+
const m = new Mat2(1, 2, 3, 4)
|
|
97
|
+
const out = new Mat2()
|
|
98
|
+
m.adjoint(out)
|
|
99
|
+
assert.strictEqual(out[0], 4)
|
|
100
|
+
assert.strictEqual(out[1], -2)
|
|
101
|
+
assert.strictEqual(out[2], -3)
|
|
102
|
+
assert.strictEqual(out[3], 1)
|
|
103
|
+
})
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
describe('determinant', () => {
|
|
107
|
+
it('calculates determinant', () => {
|
|
108
|
+
const m = new Mat2(1, 2, 3, 4)
|
|
109
|
+
assert.strictEqual(m.determinant(), -2)
|
|
110
|
+
})
|
|
111
|
+
it('identity determinant is 1', () => {
|
|
112
|
+
assert.strictEqual(Mat2.identity.determinant(), 1)
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
describe('rotate', () => {
|
|
117
|
+
it('rotates identity by 90 degrees', () => {
|
|
118
|
+
const m = Mat2.identity
|
|
119
|
+
const r = m.rotate(Math.PI / 2)
|
|
120
|
+
closeTo(r[0], 0)
|
|
121
|
+
closeTo(r[1], 1)
|
|
122
|
+
closeTo(r[2], -1)
|
|
123
|
+
closeTo(r[3], 0)
|
|
124
|
+
})
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
describe('scale', () => {
|
|
128
|
+
it('scales identity matrix', () => {
|
|
129
|
+
const m = Mat2.identity
|
|
130
|
+
const r = m.scale(new Vec2(2, 3))
|
|
131
|
+
assert.strictEqual(r[0], 2)
|
|
132
|
+
assert.strictEqual(r[1], 0)
|
|
133
|
+
assert.strictEqual(r[2], 0)
|
|
134
|
+
assert.strictEqual(r[3], 3)
|
|
135
|
+
})
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
describe('static fromRotation', () => {
|
|
139
|
+
it('creates rotation matrix', () => {
|
|
140
|
+
const m = Mat2.fromRotation(Math.PI / 2)
|
|
141
|
+
closeTo(m[0], 0)
|
|
142
|
+
closeTo(m[1], 1)
|
|
143
|
+
closeTo(m[2], -1)
|
|
144
|
+
closeTo(m[3], 0)
|
|
145
|
+
})
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
describe('static fromScaling', () => {
|
|
149
|
+
it('creates scaling matrix', () => {
|
|
150
|
+
const m = Mat2.fromScaling(new Vec2(2, 3))
|
|
151
|
+
assert.strictEqual(m[0], 2)
|
|
152
|
+
assert.strictEqual(m[1], 0)
|
|
153
|
+
assert.strictEqual(m[2], 0)
|
|
154
|
+
assert.strictEqual(m[3], 3)
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
describe('multiply', () => {
|
|
159
|
+
it('multiplies two matrices', () => {
|
|
160
|
+
const a = new Mat2(1, 2, 3, 4)
|
|
161
|
+
const b = new Mat2(5, 6, 7, 8)
|
|
162
|
+
const out = new Mat2()
|
|
163
|
+
a.multiply(b, out)
|
|
164
|
+
assert.strictEqual(out[0], 1 * 5 + 3 * 6)
|
|
165
|
+
assert.strictEqual(out[1], 2 * 5 + 4 * 6)
|
|
166
|
+
assert.strictEqual(out[2], 1 * 7 + 3 * 8)
|
|
167
|
+
assert.strictEqual(out[3], 2 * 7 + 4 * 8)
|
|
168
|
+
})
|
|
169
|
+
it('identity * A = A', () => {
|
|
170
|
+
const a = new Mat2(1, 2, 3, 4)
|
|
171
|
+
const out = new Mat2()
|
|
172
|
+
Mat2.identity.multiply(a, out)
|
|
173
|
+
assert.strictEqual(out[0], 1)
|
|
174
|
+
assert.strictEqual(out[1], 2)
|
|
175
|
+
assert.strictEqual(out[2], 3)
|
|
176
|
+
assert.strictEqual(out[3], 4)
|
|
177
|
+
})
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
describe('plus / minus', () => {
|
|
181
|
+
it('adds matrices', () => {
|
|
182
|
+
const a = new Mat2(1, 2, 3, 4)
|
|
183
|
+
const b = new Mat2(5, 6, 7, 8)
|
|
184
|
+
const out = new Mat2()
|
|
185
|
+
a.plus(b, out)
|
|
186
|
+
assert.strictEqual(out[0], 6)
|
|
187
|
+
assert.strictEqual(out[1], 8)
|
|
188
|
+
assert.strictEqual(out[2], 10)
|
|
189
|
+
assert.strictEqual(out[3], 12)
|
|
190
|
+
})
|
|
191
|
+
it('subtracts matrices', () => {
|
|
192
|
+
const a = new Mat2(5, 6, 7, 8)
|
|
193
|
+
const b = new Mat2(1, 2, 3, 4)
|
|
194
|
+
const out = new Mat2()
|
|
195
|
+
a.minus(b, out)
|
|
196
|
+
assert.strictEqual(out[0], 4)
|
|
197
|
+
assert.strictEqual(out[1], 4)
|
|
198
|
+
assert.strictEqual(out[2], 4)
|
|
199
|
+
assert.strictEqual(out[3], 4)
|
|
200
|
+
})
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
describe('scaleScalar', () => {
|
|
204
|
+
it('scales all elements', () => {
|
|
205
|
+
const m = new Mat2(1, 2, 3, 4)
|
|
206
|
+
const r = m.scaleScalar(2)
|
|
207
|
+
assert.strictEqual(r[0], 2)
|
|
208
|
+
assert.strictEqual(r[1], 4)
|
|
209
|
+
assert.strictEqual(r[2], 6)
|
|
210
|
+
assert.strictEqual(r[3], 8)
|
|
211
|
+
})
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
describe('equals / exactEquals', () => {
|
|
215
|
+
it('exactEquals', () => {
|
|
216
|
+
assert.strictEqual(new Mat2(1, 2, 3, 4).exactEquals(new Mat2(1, 2, 3, 4)), true)
|
|
217
|
+
assert.strictEqual(new Mat2(1, 2, 3, 4).exactEquals(new Mat2(1, 2, 3, 5)), false)
|
|
218
|
+
})
|
|
219
|
+
it('equals with epsilon', () => {
|
|
220
|
+
const a = new Mat2(1, 2, 3, 4)
|
|
221
|
+
const b = new Mat2(1 + glmaths.EPSILON * 0.1, 2, 3, 4)
|
|
222
|
+
assert.strictEqual(a.equals(b), true)
|
|
223
|
+
})
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
describe('toString', () => {
|
|
227
|
+
it('returns string representation', () => {
|
|
228
|
+
assert.strictEqual(new Mat2(1, 2, 3, 4).toString(), 'mat2x2(1, 2, 3, 4)')
|
|
229
|
+
})
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
describe('frob', () => {
|
|
233
|
+
it('frobenius norm of identity', () => {
|
|
234
|
+
closeTo(Mat2.identity.frob(), Math.sqrt(2))
|
|
235
|
+
})
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
describe('LDU', () => {
|
|
239
|
+
it('factors a matrix', () => {
|
|
240
|
+
const m = new Mat2(4, 3, 6, 3)
|
|
241
|
+
const [L, D, U] = m.LDU()
|
|
242
|
+
assert.ok(L instanceof Mat2)
|
|
243
|
+
assert.ok(D instanceof Mat2)
|
|
244
|
+
assert.ok(U instanceof Mat2)
|
|
245
|
+
})
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
describe('factory function', () => {
|
|
249
|
+
it('creates Mat2 via mat2()', () => {
|
|
250
|
+
const m = mat2(1, 2, 3, 4)
|
|
251
|
+
assert.ok(m instanceof Mat2)
|
|
252
|
+
assert.strictEqual(m[0], 1)
|
|
253
|
+
})
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
describe('mat * vec operators', () => {
|
|
257
|
+
it('Mat2 * Vec2 rotation', () => {
|
|
258
|
+
const m = Mat2.fromRotation(Math.PI / 3)
|
|
259
|
+
const v = new Vec2(3, 4)
|
|
260
|
+
const expected = v.transformMat2(m, new Vec2())
|
|
261
|
+
const r = m * v
|
|
262
|
+
assert.ok(r instanceof Vec2)
|
|
263
|
+
closeTo(r.x, expected.x)
|
|
264
|
+
closeTo(r.y, expected.y)
|
|
265
|
+
})
|
|
266
|
+
it('Mat2 * Vec2 scale + rotation', () => {
|
|
267
|
+
const m = Mat2.fromScaling(new Vec2(2, 3))
|
|
268
|
+
const rot = Mat2.fromRotation(Math.PI / 5)
|
|
269
|
+
const combined = rot.multiply(m, new Mat2())
|
|
270
|
+
const v = new Vec2(7, -2)
|
|
271
|
+
const expected = v.transformMat2(combined, new Vec2())
|
|
272
|
+
const r = combined * v
|
|
273
|
+
closeTo(r.x, expected.x)
|
|
274
|
+
closeTo(r.y, expected.y)
|
|
275
|
+
})
|
|
276
|
+
})
|
|
277
|
+
})
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { describe, it } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import glmaths, { Mat2x3, mat2x3, Vec2 } from '../dist/esm/glmaths'
|
|
4
|
+
|
|
5
|
+
function closeTo(actual: number, expected: number, numDigits = 5) {
|
|
6
|
+
const pass = Math.abs(actual - expected) < Math.pow(10, -numDigits) / 2
|
|
7
|
+
assert.ok(pass, `expected ${actual} to be close to ${expected}`)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
describe('Mat2x3', () => {
|
|
11
|
+
describe('constructor', () => {
|
|
12
|
+
it('creates zero matrix by default', () => {
|
|
13
|
+
const m = new Mat2x3()
|
|
14
|
+
for (let i = 0; i < 6; i++) assert.strictEqual(m[i], 0)
|
|
15
|
+
})
|
|
16
|
+
it('creates with given values', () => {
|
|
17
|
+
const m = new Mat2x3(1, 2, 3, 4, 5, 6)
|
|
18
|
+
assert.strictEqual(m[0], 1)
|
|
19
|
+
assert.strictEqual(m[5], 6)
|
|
20
|
+
})
|
|
21
|
+
it('extends Float32Array with length 6', () => {
|
|
22
|
+
assert.ok(new Mat2x3() instanceof Float32Array)
|
|
23
|
+
assert.strictEqual(new Mat2x3().length, 6)
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
describe('identity', () => {
|
|
28
|
+
it('creates identity', () => {
|
|
29
|
+
const m = Mat2x3.identity
|
|
30
|
+
assert.strictEqual(m[0], 1)
|
|
31
|
+
assert.strictEqual(m[1], 0)
|
|
32
|
+
assert.strictEqual(m[2], 0)
|
|
33
|
+
assert.strictEqual(m[3], 1)
|
|
34
|
+
assert.strictEqual(m[4], 0)
|
|
35
|
+
assert.strictEqual(m[5], 0)
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
describe('determinant', () => {
|
|
40
|
+
it('identity determinant is 1', () => {
|
|
41
|
+
assert.strictEqual(Mat2x3.identity.determinant(), 1)
|
|
42
|
+
})
|
|
43
|
+
it('calculates determinant', () => {
|
|
44
|
+
const m = new Mat2x3(1, 2, 3, 4, 5, 6)
|
|
45
|
+
assert.strictEqual(m.determinant(), 1 * 4 - 2 * 3)
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
describe('invert', () => {
|
|
50
|
+
it('inverts identity to identity', () => {
|
|
51
|
+
const m = Mat2x3.identity
|
|
52
|
+
const out = new Mat2x3()
|
|
53
|
+
m.invert(out)
|
|
54
|
+
assert.strictEqual(out[0], 1)
|
|
55
|
+
assert.strictEqual(out[3], 1)
|
|
56
|
+
assert.strictEqual(out[4], 0)
|
|
57
|
+
assert.strictEqual(out[5], 0)
|
|
58
|
+
})
|
|
59
|
+
it('returns null for singular matrix', () => {
|
|
60
|
+
const m = new Mat2x3(1, 2, 2, 4, 0, 0)
|
|
61
|
+
assert.strictEqual(m.invert(new Mat2x3()), null)
|
|
62
|
+
})
|
|
63
|
+
it('inverse * original = identity (for the 2x2 part)', () => {
|
|
64
|
+
const m = new Mat2x3(2, 1, 1, 3, 5, 7)
|
|
65
|
+
const inv = new Mat2x3()
|
|
66
|
+
m.invert(inv)
|
|
67
|
+
const result = new Mat2x3()
|
|
68
|
+
Mat2x3.identity.multiply.call(m, inv!, result)
|
|
69
|
+
closeTo(result[0], 1)
|
|
70
|
+
closeTo(result[1], 0)
|
|
71
|
+
closeTo(result[2], 0)
|
|
72
|
+
closeTo(result[3], 1)
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
describe('rotate', () => {
|
|
77
|
+
it('rotates identity by PI/2', () => {
|
|
78
|
+
const m = Mat2x3.identity
|
|
79
|
+
const r = m.rotate(Math.PI / 2)
|
|
80
|
+
closeTo(r[0], 0)
|
|
81
|
+
closeTo(r[1], 1)
|
|
82
|
+
closeTo(r[2], -1)
|
|
83
|
+
closeTo(r[3], 0)
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
describe('scale', () => {
|
|
88
|
+
it('scales identity', () => {
|
|
89
|
+
const m = Mat2x3.identity
|
|
90
|
+
const r = m.scale(new Vec2(2, 3))
|
|
91
|
+
assert.strictEqual(r[0], 2)
|
|
92
|
+
assert.strictEqual(r[3], 3)
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
describe('translate', () => {
|
|
97
|
+
it('translates identity', () => {
|
|
98
|
+
const m = Mat2x3.identity
|
|
99
|
+
const r = m.translate(new Vec2(5, 10))
|
|
100
|
+
assert.strictEqual(r[4], 5)
|
|
101
|
+
assert.strictEqual(r[5], 10)
|
|
102
|
+
})
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
describe('static fromRotation', () => {
|
|
106
|
+
it('creates rotation matrix', () => {
|
|
107
|
+
const m = Mat2x3.fromRotation(Math.PI / 2)
|
|
108
|
+
closeTo(m[0], 0)
|
|
109
|
+
closeTo(m[1], 1)
|
|
110
|
+
assert.strictEqual(m[4], 0)
|
|
111
|
+
assert.strictEqual(m[5], 0)
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
describe('static fromScaling', () => {
|
|
116
|
+
it('creates scaling matrix', () => {
|
|
117
|
+
const m = Mat2x3.fromScaling(new Vec2(2, 3))
|
|
118
|
+
assert.strictEqual(m[0], 2)
|
|
119
|
+
assert.strictEqual(m[3], 3)
|
|
120
|
+
})
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
describe('static fromTranslation', () => {
|
|
124
|
+
it('creates translation matrix', () => {
|
|
125
|
+
const m = Mat2x3.fromTranslation(new Vec2(5, 10))
|
|
126
|
+
assert.strictEqual(m[0], 1)
|
|
127
|
+
assert.strictEqual(m[3], 1)
|
|
128
|
+
assert.strictEqual(m[4], 5)
|
|
129
|
+
assert.strictEqual(m[5], 10)
|
|
130
|
+
})
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
describe('multiply', () => {
|
|
134
|
+
it('identity * A = A', () => {
|
|
135
|
+
const a = new Mat2x3(1, 2, 3, 4, 5, 6)
|
|
136
|
+
const out = new Mat2x3()
|
|
137
|
+
Mat2x3.identity.multiply(a, out)
|
|
138
|
+
for (let i = 0; i < 6; i++) assert.strictEqual(out[i], a[i])
|
|
139
|
+
})
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
describe('plus / minus', () => {
|
|
143
|
+
it('adds', () => {
|
|
144
|
+
const a = new Mat2x3(1, 2, 3, 4, 5, 6)
|
|
145
|
+
const b = new Mat2x3(6, 5, 4, 3, 2, 1)
|
|
146
|
+
const out = new Mat2x3()
|
|
147
|
+
a.plus(b, out)
|
|
148
|
+
assert.strictEqual(out[0], 7)
|
|
149
|
+
assert.strictEqual(out[5], 7)
|
|
150
|
+
})
|
|
151
|
+
it('subtracts', () => {
|
|
152
|
+
const a = new Mat2x3(6, 5, 4, 3, 2, 1)
|
|
153
|
+
const b = new Mat2x3(1, 2, 3, 4, 5, 6)
|
|
154
|
+
const out = new Mat2x3()
|
|
155
|
+
a.minus(b, out)
|
|
156
|
+
assert.strictEqual(out[0], 5)
|
|
157
|
+
assert.strictEqual(out[5], -5)
|
|
158
|
+
})
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
describe('equals / exactEquals', () => {
|
|
162
|
+
it('exactEquals', () => {
|
|
163
|
+
const a = new Mat2x3(1, 2, 3, 4, 5, 6)
|
|
164
|
+
const b = new Mat2x3(1, 2, 3, 4, 5, 6)
|
|
165
|
+
assert.strictEqual(a.exactEquals(b), true)
|
|
166
|
+
})
|
|
167
|
+
it('equals with epsilon', () => {
|
|
168
|
+
const a = new Mat2x3(1, 2, 3, 4, 5, 6)
|
|
169
|
+
const b = new Mat2x3(1 + glmaths.EPSILON * 0.1, 2, 3, 4, 5, 6)
|
|
170
|
+
assert.strictEqual(a.equals(b), true)
|
|
171
|
+
})
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
describe('toString', () => {
|
|
175
|
+
it('returns string', () => {
|
|
176
|
+
const m = new Mat2x3(1, 0, 0, 1, 0, 0)
|
|
177
|
+
assert.ok(m.toString().includes('mat2x3'))
|
|
178
|
+
})
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
describe('frob', () => {
|
|
182
|
+
it('frobenius norm of identity', () => {
|
|
183
|
+
closeTo(Mat2x3.identity.frob(), Math.sqrt(3))
|
|
184
|
+
})
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
describe('factory function', () => {
|
|
188
|
+
it('creates Mat2x3', () => {
|
|
189
|
+
const m = mat2x3(1, 0, 0, 1, 0, 0)
|
|
190
|
+
assert.ok(m instanceof Mat2x3)
|
|
191
|
+
})
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
describe('mat * vec operators', () => {
|
|
195
|
+
it('Mat2x3 * Vec2 rotation + translation', () => {
|
|
196
|
+
const m = Mat2x3.fromRotation(Math.PI / 3)
|
|
197
|
+
m.translate(new Vec2(10, 20))
|
|
198
|
+
const v = new Vec2(4, -1)
|
|
199
|
+
const expected = v.transformMat2x3(m, new Vec2())
|
|
200
|
+
const r = m * v
|
|
201
|
+
assert.ok(r instanceof Vec2)
|
|
202
|
+
closeTo(r.x, expected.x)
|
|
203
|
+
closeTo(r.y, expected.y)
|
|
204
|
+
})
|
|
205
|
+
it('Mat2x3 * Vec2 scale + rotation + translation', () => {
|
|
206
|
+
const m = Mat2x3.identity
|
|
207
|
+
m.scale(new Vec2(2, 3))
|
|
208
|
+
m.rotate(Math.PI / 4)
|
|
209
|
+
m.translate(new Vec2(5, 10))
|
|
210
|
+
const v = new Vec2(3, 7)
|
|
211
|
+
const expected = v.transformMat2x3(m, new Vec2())
|
|
212
|
+
const r = m * v
|
|
213
|
+
closeTo(r.x, expected.x)
|
|
214
|
+
closeTo(r.y, expected.y)
|
|
215
|
+
})
|
|
216
|
+
})
|
|
217
|
+
})
|