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/src/mat2x3.ts ADDED
@@ -0,0 +1,328 @@
1
+ import glm from '.'
2
+ import { equals } from './internalUtils'
3
+ import { Vec2 } from './vec2'
4
+
5
+ /** 2x3 Affine transformation matrix for 2D operations
6
+ * @extends Float32Array
7
+ */
8
+ export class Mat2x3 extends Float32Array {
9
+
10
+ static get identity() { return new Mat2x3(1, 0, 0, 1, 0, 0) }
11
+ static get Identity() { return new Mat2x3(1, 0, 0, 1, 0, 0) }
12
+ static get IDENTITY() { return new Mat2x3(1, 0, 0, 1, 0, 0) }
13
+
14
+ /**
15
+ * Creates a new Mat2x3
16
+ *
17
+ * @param {Number} a component at index 0
18
+ * @param {Number} b component at index 1
19
+ * @param {Number} c component at index 2
20
+ * @param {Number} d component at index 3
21
+ * @param {Number} tx component at index 4
22
+ * @param {Number} ty component at index 5
23
+ */
24
+ constructor(a = 0, b = 0, c = 0, d = 0, tx = 0, ty = 0) {
25
+ super(6)
26
+ this[0] = a
27
+ this[1] = b
28
+ this[2] = c
29
+ this[3] = d
30
+ this[4] = tx
31
+ this[5] = ty
32
+ }
33
+
34
+ /**
35
+ * Inverts a mat2x3
36
+ *
37
+ * @param {Mat2x3} out the receiving matrix, defaults to this
38
+ * @returns {Mat2x3} out or null if the matrix is not invertible
39
+ */
40
+ invert(out = glm.ALWAYS_COPY ? new Mat2x3() : this) {
41
+ const aa = this[0], ab = this[1], ac = this[2], ad = this[3]
42
+ const atx = this[4], aty = this[5]
43
+ let det = aa * ad - ab * ac
44
+ if (!det) return null
45
+ det = 1.0 / det
46
+ out[0] = ad * det
47
+ out[1] = -ab * det
48
+ out[2] = -ac * det
49
+ out[3] = aa * det
50
+ out[4] = (ac * aty - ad * atx) * det
51
+ out[5] = (ab * atx - aa * aty) * det
52
+ return out;
53
+ }
54
+
55
+ /**
56
+ * Calculates the determinant of a mat2x3
57
+ *
58
+ * @returns {Number} determinant of a mat2x3
59
+ */
60
+ determinant() {
61
+ return this[0] * this[3] - this[1] * this[2]
62
+ }
63
+
64
+ /**
65
+ * Rotates a mat2x3 by the given angle
66
+ *
67
+ * @param {Number} rad the angle to rotate the matrix by
68
+ * @param {Mat2x3} out the receiving matrix, defaults to this
69
+ * @returns {Mat2x3} out
70
+ */
71
+ rotate(rad: number, out = glm.ALWAYS_COPY ? new Mat2x3() : this) {
72
+ const a0 = this[0], a1 = this[1], a2 = this[2], a3 = this[3], a4 = this[4], a5 = this[5];
73
+ const s = Math.sin(rad)
74
+ const c = Math.cos(rad)
75
+ out[0] = a0 * c + a2 * s
76
+ out[1] = a1 * c + a3 * s
77
+ out[2] = a0 * -s + a2 * c
78
+ out[3] = a1 * -s + a3 * c
79
+ out[4] = a4
80
+ out[5] = a5
81
+ return out
82
+ }
83
+
84
+ /**
85
+ * Scales a mat2x3 by the dimensions in the given Vec2
86
+ *
87
+ * @param {Vec2} v the Vec2 to scale the matrix by
88
+ * @param {Mat2x3} out the receiving matrix, defaults to this
89
+ * @returns {Mat2x3} out
90
+ */
91
+ scale(v: Vec2, out = glm.ALWAYS_COPY ? new Mat2x3() : this) {
92
+ const a0 = this[0], a1 = this[1], a2 = this[2], a3 = this[3], a4 = this[4], a5 = this[5]
93
+ const v0 = v[0], v1 = v[1]
94
+ out[0] = a0 * v0
95
+ out[1] = a1 * v0
96
+ out[2] = a2 * v1
97
+ out[3] = a3 * v1
98
+ out[4] = a4
99
+ out[5] = a5
100
+ return out
101
+ }
102
+
103
+ /**
104
+ * Translates a mat2x3 by the dimensions in the given Vec2
105
+ *
106
+ * @param {Vec2} v the Vec2 to translate the matrix by
107
+ * @param {Mat2x3} out the receiving matrix, defaults to this
108
+ * @returns {Mat2x3} out
109
+ */
110
+ translate(v: Vec2, out = glm.ALWAYS_COPY ? new Mat2x3() : this) {
111
+ const a0 = this[0], a1 = this[1], a2 = this[2], a3 = this[3], a4 = this[4], a5 = this[5]
112
+ const v0 = v[0], v1 = v[1]
113
+ out[0] = a0
114
+ out[1] = a1
115
+ out[2] = a2
116
+ out[3] = a3
117
+ out[4] = a0 * v0 + a2 * v1 + a4
118
+ out[5] = a1 * v0 + a3 * v1 + a5
119
+ return out
120
+ }
121
+
122
+ /**
123
+ * Creates a Mat2x3 from a given angle
124
+ *
125
+ * @param {Number} rad the angle to rotate the matrix by
126
+ * @param {Mat2x3} out the receiving matrix, defaults to new Mat2x3()
127
+ * @returns {Mat2x3} out
128
+ */
129
+ static fromRotation(rad: number, out = new Mat2x3()) {
130
+ const s = Math.sin(rad), c = Math.cos(rad)
131
+ out[0] = c
132
+ out[1] = s
133
+ out[2] = -s
134
+ out[3] = c
135
+ out[4] = out[5] = 0
136
+ return out
137
+ }
138
+
139
+ /**
140
+ * Creates a Mat2x3 from a scaling vector
141
+ *
142
+ * @param {Vec2} v scaling vector
143
+ * @param {Mat2x3} out the receiving matrix, defaults to new Mat2x3()
144
+ * @returns {Mat2x3} out
145
+ */
146
+ static fromScaling(v: Vec2, out = new Mat2x3()) {
147
+ out[0] = v[0]
148
+ out[1] = out[2] = 0
149
+ out[3] = v[1]
150
+ out[4] = out[5] = 0
151
+ return out
152
+ }
153
+
154
+ /**
155
+ * Creates a Mat2x3 from a translation vector
156
+ *
157
+ * @param {Vec2} v translation vector
158
+ * @param {Mat2x3} out the receiving matrix, defaults to new Mat2x3()
159
+ * @returns {Mat2x3} out
160
+ */
161
+ static fromTranslation(v: Vec2, out = new Mat2x3()) {
162
+ out[0] = out[3] = 1
163
+ out[1] = out[2] = 0
164
+ out[4] = v[0]
165
+ out[5] = v[1]
166
+ return out
167
+ }
168
+
169
+ /**
170
+ * Returns a string representation of a mat2x3
171
+ *
172
+ * @returns {String} string representation of the matrix
173
+ */
174
+ toString() {
175
+ return `mat2x3(${this[0]}, ${this[1]},\t${this[2]}, ${this[3]},\t${this[4]}, ${this[5]})`
176
+ }
177
+
178
+ /**
179
+ * Returns Frobenius norm of a mat2x3
180
+ *
181
+ * @returns {Number} Frobenius norm
182
+ */
183
+ frob() {
184
+ return Math.sqrt(this[0] * this[0] + this[1] * this[1] + this[2] * this[2] + this[3] * this[3] + this[4] * this[4] + this[5] * this[5] + 1)
185
+ }
186
+
187
+ /**
188
+ * Adds two Mat2x3's
189
+ *
190
+ * @param {Mat2x3} b the second operand
191
+ * @param {Mat2x3} out the receiving matrix, defaults to this
192
+ * @returns {Mat2x3} out
193
+ */
194
+ plus(b: Mat2x3, out = glm.ALWAYS_COPY ? new Mat2x3() : this) {
195
+ out[0] = this[0] + b[0]
196
+ out[1] = this[1] + b[1]
197
+ out[2] = this[2] + b[2]
198
+ out[3] = this[3] + b[3]
199
+ out[4] = this[4] + b[4]
200
+ out[5] = this[5] + b[5]
201
+ return out
202
+ }
203
+
204
+ /**
205
+ * Subtracts matrix b from a mat2x3
206
+ *
207
+ * @param {Mat2x3} b the second operand
208
+ * @param {Mat2x3} out the receiving matrix, defaults to this
209
+ * @returns {Mat2x3} out
210
+ */
211
+ minus(b: Mat2x3, out = glm.ALWAYS_COPY ? new Mat2x3() : this) {
212
+ out[0] = this[0] - b[0]
213
+ out[1] = this[1] - b[1]
214
+ out[2] = this[2] - b[2]
215
+ out[3] = this[3] - b[3]
216
+ out[4] = this[4] - b[4]
217
+ out[5] = this[5] - b[5]
218
+ return out
219
+ }
220
+
221
+ /**
222
+ * Multiplies a mat2x3 by another Mat2x3
223
+ *
224
+ * @param {Mat2x3} b the second operand
225
+ * @param {Mat2x3} out the receiving matrix, defaults to this
226
+ * @returns {Mat2x3} out
227
+ */
228
+ multiply(b: Vec2): Vec2
229
+ multiply(b: Mat2x3, out?: Mat2x3): Mat2x3
230
+ multiply(b: Mat2x3 | Vec2, out = glm.ALWAYS_COPY ? new Mat2x3() : this) {
231
+ if (b instanceof Vec2)
232
+ return b.transformMat2x3(this)
233
+
234
+ const a0 = this[0], a1 = this[1], a2 = this[2], a3 = this[3], a4 = this[4], a5 = this[5]
235
+ const b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5]
236
+ out[0] = a0 * b0 + a2 * b1
237
+ out[1] = a1 * b0 + a3 * b1
238
+ out[2] = a0 * b2 + a2 * b3
239
+ out[3] = a1 * b2 + a3 * b3
240
+ out[4] = a0 * b4 + a2 * b5 + a4
241
+ out[5] = a1 * b4 + a3 * b5 + a5
242
+ return out
243
+ }
244
+
245
+ /**
246
+ * Returns whether a mat2x3 and another Mat2x3 have approximately equal components
247
+ *
248
+ * @param {Mat2x3} b the matrix to compare against
249
+ * @returns {Boolean} true if the matrices are approximately equal
250
+ */
251
+ equals(b: Mat2x3) {
252
+ return (
253
+ equals(this[0], b[0]) && equals(this[1], b[1]) && equals(this[2], b[2]) &&
254
+ equals(this[3], b[3]) && equals(this[4], b[4]) && equals(this[5], b[5])
255
+ );
256
+ }
257
+ /**
258
+ * Returns whether a mat2x3 and another Mat2x3 have exactly equal components
259
+ *
260
+ * @param {Mat2x3} b the matrix to compare against
261
+ * @returns {Boolean} true if the matrices are exactly equal
262
+ */
263
+ exactEquals(b: Mat2x3) {
264
+ return (
265
+ this[0] === b[0] && this[1] === b[1] && this[2] === b[2] &&
266
+ this[3] === b[3] && this[4] === b[4] && this[5] === b[5]
267
+ )
268
+ }
269
+
270
+ /**
271
+ * Multiplies each element of a mat2x3 by a scalar value
272
+ *
273
+ * @param {Number} b amount to scale the matrix's elements by
274
+ * @param {Mat2x3} out the receiving matrix, defaults to this
275
+ * @returns {Mat2x3} out
276
+ */
277
+ scaleScalar(b: number, out = glm.ALWAYS_COPY ? new Mat2x3() : this) {
278
+ out[0] = this[0] * b
279
+ out[1] = this[1] * b
280
+ out[2] = this[2] * b
281
+ out[3] = this[3] * b
282
+ out[4] = this[4] * b
283
+ out[5] = this[5] * b
284
+ return out;
285
+ }
286
+
287
+ /**
288
+ * Creates a new Mat2x3 initialized with values from this matrix
289
+ *
290
+ * @returns {Mat2x3} a new Mat2x3
291
+ */
292
+ clone(): Mat2x3 {
293
+ return new Mat2x3(
294
+ this[0], this[1], this[2],
295
+ this[3], this[4], this[5]
296
+ )
297
+ }
298
+ }
299
+ export interface Mat2x3 {
300
+ add: (b: Mat2x3, out?: Mat2x3) => Mat2x3
301
+ sub: (b: Mat2x3, out?: Mat2x3) => Mat2x3
302
+ subtract: (b: Mat2x3, out?: Mat2x3) => Mat2x3
303
+ mul(b: Vec2): Vec2
304
+ mul(b: Mat2x3, out?: Mat2x3): Mat2x3
305
+ mult(b: Vec2): Vec2
306
+ mult(b: Mat2x3, out?: Mat2x3): Mat2x3
307
+ times(b: Vec2): Vec2
308
+ times(b: Mat2x3, out?: Mat2x3): Mat2x3
309
+ multiplyScalar: (b: number, out?: Mat2x3) => Mat2x3
310
+ str: () => string
311
+ }
312
+
313
+ // @aliases
314
+ Mat2x3.prototype.add = Mat2x3.prototype.plus
315
+ Mat2x3.prototype.sub = Mat2x3.prototype.minus
316
+ Mat2x3.prototype.subtract = Mat2x3.prototype.minus
317
+ Mat2x3.prototype.mul = Mat2x3.prototype.multiply
318
+ Mat2x3.prototype.mult = Mat2x3.prototype.multiply
319
+ Mat2x3.prototype.times = Mat2x3.prototype.multiply
320
+ Mat2x3.prototype.str = Mat2x3.prototype.toString
321
+ Mat2x3.prototype.multiplyScalar = Mat2x3.prototype.scaleScalar
322
+
323
+ export const mat2x3 = Object.assign(
324
+ (a = 0, b = 0, c = 0, d = 0, tx = 0, ty = 0) =>
325
+ new Mat2x3(a, b, c, d, tx, ty),
326
+ Mat2x3
327
+ )
328
+ export const mat2d = mat2x3