1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.numerics.math;
39
40
41
42
43
44
45
46
47
48 public final class MatrixMath {
49
50 private MatrixMath() {
51
52 }
53
54
55
56
57
58
59
60 public static double determinant3(double[][] m) {
61 return m[0][0] * m[1][1] * m[2][2]
62 - m[0][0] * m[1][2] * m[2][1]
63 + m[0][1] * m[1][2] * m[2][0]
64 - m[0][1] * m[1][0] * m[2][2]
65 + m[0][2] * m[1][0] * m[2][1]
66 - m[0][2] * m[1][1] * m[2][0];
67 }
68
69
70
71
72
73
74
75 public static double determinant3(double[] m) {
76 return m[0] * m[1] * m[2]
77 - m[0] * m[5] * m[5]
78 + m[3] * m[5] * m[4]
79 - m[3] * m[3] * m[2]
80 + m[4] * m[3] * m[5]
81 - m[4] * m[1] * m[4];
82 }
83
84
85
86
87
88
89
90 public static double[][] mat3Inverse(double[][] m) {
91 return mat3Inverse(m, new double[3][3]);
92 }
93
94
95
96
97
98
99
100
101 public static double[][] mat3Inverse(double[][] m, double[][] res) {
102 double det = determinant3(m);
103 res[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / det;
104 res[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) / det;
105 res[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / det;
106 res[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) / det;
107 res[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / det;
108 res[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / det;
109 res[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / det;
110 res[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / det;
111 res[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / det;
112 return res;
113 }
114
115
116
117
118
119
120
121
122 public static double[][] mat3Mat3(double[][] m1, double[][] m2) {
123 return mat3Mat3(m1, m2, new double[3][3]);
124 }
125
126
127
128
129
130
131
132
133
134 public static double[][] mat3Mat3(double[][] m1, double[][] m2, double[][] res) {
135 res[0][0] = m1[0][0] * m2[0][0] + m1[0][1] * m2[1][0] + m1[0][2] * m2[2][0];
136 res[0][1] = m1[0][0] * m2[0][1] + m1[0][1] * m2[1][1] + m1[0][2] * m2[2][1];
137 res[0][2] = m1[0][0] * m2[0][2] + m1[0][1] * m2[1][2] + m1[0][2] * m2[2][2];
138 res[1][0] = m1[1][0] * m2[0][0] + m1[1][1] * m2[1][0] + m1[1][2] * m2[2][0];
139 res[1][1] = m1[1][0] * m2[0][1] + m1[1][1] * m2[1][1] + m1[1][2] * m2[2][1];
140 res[1][2] = m1[1][0] * m2[0][2] + m1[1][1] * m2[1][2] + m1[1][2] * m2[2][2];
141 res[2][0] = m1[2][0] * m2[0][0] + m1[2][1] * m2[1][0] + m1[2][2] * m2[2][0];
142 res[2][1] = m1[2][0] * m2[0][1] + m1[2][1] * m2[1][1] + m1[2][2] * m2[2][1];
143 res[2][2] = m1[2][0] * m2[0][2] + m1[2][1] * m2[1][2] + m1[2][2] * m2[2][2];
144 return res;
145 }
146
147
148
149
150
151
152
153
154 public static double[][] mat4Mat4(double[][] m1, double[][] m2) {
155 return mat4Mat4(m1, m2, new double[4][4]);
156 }
157
158
159
160
161
162
163
164
165
166 public static double[][] mat4Mat4(double[][] m1, double[][] m2, double[][] res) {
167 assert (m1.length == 4);
168 assert (m1[0].length == 4);
169 assert (m2.length == 4);
170 assert (m2[0].length == 4);
171 assert (res.length == 4);
172 assert (res[0].length == 4);
173 res[0][0] =
174 m1[0][0] * m2[0][0] + m1[0][1] * m2[1][0] + m1[0][2] * m2[2][0] + m1[0][3] * m2[3][0];
175 res[0][1] =
176 m1[0][0] * m2[0][1] + m1[0][1] * m2[1][1] + m1[0][2] * m2[2][1] + m1[0][3] * m2[3][1];
177 res[0][2] =
178 m1[0][0] * m2[0][2] + m1[0][1] * m2[1][2] + m1[0][2] * m2[2][2] + m1[0][3] * m2[3][2];
179 res[0][3] =
180 m1[0][0] * m2[0][3] + m1[0][1] * m2[1][3] + m1[0][2] * m2[2][3] + m1[0][3] * m2[3][3];
181 res[1][0] =
182 m1[1][0] * m2[0][0] + m1[1][1] * m2[1][0] + m1[1][2] * m2[2][0] + m1[1][3] * m2[3][0];
183 res[1][1] =
184 m1[1][0] * m2[0][1] + m1[1][1] * m2[1][1] + m1[1][2] * m2[2][1] + m1[1][3] * m2[3][1];
185 res[1][2] =
186 m1[1][0] * m2[0][2] + m1[1][1] * m2[1][2] + m1[1][2] * m2[2][2] + m1[1][3] * m2[3][2];
187 res[1][3] =
188 m1[1][0] * m2[0][3] + m1[1][1] * m2[1][3] + m1[1][2] * m2[2][3] + m1[1][3] * m2[3][3];
189 res[2][0] =
190 m1[2][0] * m2[0][0] + m1[2][1] * m2[1][0] + m1[2][2] * m2[2][0] + m1[2][3] * m2[3][0];
191 res[2][1] =
192 m1[2][0] * m2[0][1] + m1[2][1] * m2[1][1] + m1[2][2] * m2[2][1] + m1[2][3] * m2[3][1];
193 res[2][2] =
194 m1[2][0] * m2[0][2] + m1[2][1] * m2[1][2] + m1[2][2] * m2[2][2] + m1[2][3] * m2[3][2];
195 res[2][3] =
196 m1[2][0] * m2[0][3] + m1[2][1] * m2[1][3] + m1[2][2] * m2[2][3] + m1[2][3] * m2[3][3];
197 res[3][0] =
198 m1[3][0] * m2[0][0] + m1[3][1] * m2[1][0] + m1[3][2] * m2[2][0] + m1[3][3] * m2[3][0];
199 res[3][1] =
200 m1[3][0] * m2[0][1] + m1[3][1] * m2[1][1] + m1[3][2] * m2[2][1] + m1[3][3] * m2[3][1];
201 res[3][2] =
202 m1[3][0] * m2[0][2] + m1[3][1] * m2[1][2] + m1[3][2] * m2[2][2] + m1[3][3] * m2[3][2];
203 res[3][3] =
204 m1[3][0] * m2[0][3] + m1[3][1] * m2[1][3] + m1[3][2] * m2[2][3] + m1[3][3] * m2[3][3];
205 return res;
206 }
207
208
209
210
211
212
213
214
215 public static double[][] mat3SymVec6(double[][] m, double[] v) {
216 return mat3SymVec6(m, v, new double[3][3]);
217 }
218
219
220
221
222
223
224
225
226
227 public static double[][] mat3SymVec6(double[][] m, double[] v, double[][] res) {
228 res[0][0] = m[0][0] * v[0] + m[0][1] * v[3] + m[0][2] * v[4];
229 res[0][1] = m[0][0] * v[3] + m[0][1] * v[1] + m[0][2] * v[5];
230 res[0][2] = m[0][0] * v[4] + m[0][1] * v[5] + m[0][2] * v[2];
231 res[1][0] = m[1][0] * v[0] + m[1][1] * v[3] + m[1][2] * v[4];
232 res[1][1] = m[1][0] * v[3] + m[1][1] * v[1] + m[1][2] * v[5];
233 res[1][2] = m[1][0] * v[4] + m[1][1] * v[5] + m[1][2] * v[2];
234 res[2][0] = m[2][0] * v[0] + m[2][1] * v[3] + m[2][2] * v[4];
235 res[2][1] = m[2][0] * v[3] + m[2][1] * v[1] + m[2][2] * v[5];
236 res[2][2] = m[2][0] * v[4] + m[2][1] * v[5] + m[2][2] * v[2];
237 return res;
238 }
239
240
241
242
243
244
245
246
247 public static double[] mat3Vec3(double[] v, double[][] m) {
248 return mat3Vec3(v, m, new double[3]);
249 }
250
251
252
253
254
255
256
257
258
259 public static double[] mat3Vec3(double[] v, double[][] m, double[] res) {
260 res[0] = m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2];
261 res[1] = m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2];
262 res[2] = m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2];
263 return res;
264 }
265
266
267
268
269
270
271
272
273
274 public static double[][] scalarMat3Mat3(double scalar, double[][] m1, double[][] m2) {
275 return scalarMat3Mat3(scalar, m1, m2, new double[3][3]);
276 }
277
278
279
280
281
282
283
284
285
286
287 public static double[][] scalarMat3Mat3(
288 double scalar, double[][] m1, double[][] m2, double[][] res) {
289 res[0][0] =
290 (scalar * m1[0][0]) * m2[0][0]
291 + (scalar * m1[0][1]) * m2[1][0]
292 + (scalar * m1[0][2]) * m2[2][0];
293 res[0][1] =
294 (scalar * m1[0][0]) * m2[0][1]
295 + (scalar * m1[0][1]) * m2[1][1]
296 + (scalar * m1[0][2]) * m2[2][1];
297 res[0][2] =
298 (scalar * m1[0][0]) * m2[0][2]
299 + (scalar * m1[0][1]) * m2[1][2]
300 + (scalar * m1[0][2]) * m2[2][2];
301 res[1][0] =
302 (scalar * m1[1][0]) * m2[0][0]
303 + (scalar * m1[1][1]) * m2[1][0]
304 + (scalar * m1[1][2]) * m2[2][0];
305 res[1][1] =
306 (scalar * m1[1][0]) * m2[0][1]
307 + (scalar * m1[1][1]) * m2[1][1]
308 + (scalar * m1[1][2]) * m2[2][1];
309 res[1][2] =
310 (scalar * m1[1][0]) * m2[0][2]
311 + (scalar * m1[1][1]) * m2[1][2]
312 + (scalar * m1[1][2]) * m2[2][2];
313 res[2][0] =
314 (scalar * m1[2][0]) * m2[0][0]
315 + (scalar * m1[2][1]) * m2[1][0]
316 + (scalar * m1[2][2]) * m2[2][0];
317 res[2][1] =
318 (scalar * m1[2][0]) * m2[0][1]
319 + (scalar * m1[2][1]) * m2[1][1]
320 + (scalar * m1[2][2]) * m2[2][1];
321 res[2][2] =
322 (scalar * m1[2][0]) * m2[0][2]
323 + (scalar * m1[2][1]) * m2[1][2]
324 + (scalar * m1[2][2]) * m2[2][2];
325 return res;
326 }
327
328
329
330
331
332
333
334
335 public static double[][] symVec6Mat3(double[] v, double[][] m) {
336 double[][] res = new double[3][3];
337 symVec6Mat3(v, m, res);
338 return res;
339 }
340
341
342
343
344
345
346
347
348
349 public static double[][] symVec6Mat3(double[] v, double[][] m, double[][] res) {
350 res[0][0] = v[0] * m[0][0] + v[3] * m[1][0] + v[4] * m[2][0];
351 res[0][1] = v[0] * m[0][1] + v[3] * m[1][1] + v[4] * m[2][1];
352 res[0][2] = v[0] * m[0][2] + v[3] * m[1][2] + v[4] * m[2][2];
353 res[1][0] = v[3] * m[0][0] + v[1] * m[1][0] + v[5] * m[2][0];
354 res[1][1] = v[3] * m[0][1] + v[1] * m[1][1] + v[5] * m[2][1];
355 res[1][2] = v[3] * m[0][2] + v[1] * m[1][2] + v[5] * m[2][2];
356 res[2][0] = v[4] * m[0][0] + v[5] * m[1][0] + v[2] * m[2][0];
357 res[2][1] = v[4] * m[0][1] + v[5] * m[1][1] + v[2] * m[2][1];
358 res[2][2] = v[4] * m[0][2] + v[5] * m[1][2] + v[2] * m[2][2];
359 return res;
360 }
361
362
363
364
365
366
367
368 public static double[][] transpose3(double[][] m) {
369 return transpose3(m, new double[3][3]);
370 }
371
372
373
374
375
376
377
378
379 public static double[][] transpose3(double[][] m, double[][] t) {
380 t[0][0] = m[0][0];
381 t[0][1] = m[1][0];
382 t[0][2] = m[2][0];
383 t[1][0] = m[0][1];
384 t[1][1] = m[1][1];
385 t[1][2] = m[2][1];
386 t[2][0] = m[0][2];
387 t[2][1] = m[1][2];
388 t[2][2] = m[2][2];
389 return t;
390 }
391
392
393
394
395
396
397
398
399 public static double[] vec3Mat3(double[] v, double[][] m) {
400 return vec3Mat3(v, m, new double[3]);
401 }
402
403
404
405
406
407
408
409
410
411 public static double[] vec3Mat3(double[] v, double[][] m, double[] res) {
412 res[0] = v[0] * m[0][0] + v[1] * m[1][0] + v[2] * m[2][0];
413 res[1] = v[0] * m[0][1] + v[1] * m[1][1] + v[2] * m[2][1];
414 res[2] = v[0] * m[0][2] + v[1] * m[1][2] + v[2] * m[2][2];
415 return res;
416 }
417
418
419
420
421
422
423
424
425 public static void applyMatrixTranspose(double[] in, double[] out, double[][] matrix) {
426 double xc = in[0];
427 double yc = in[1];
428 double zc = in[2];
429 out[0] = xc * matrix[0][0] + yc * matrix[1][0] + zc * matrix[2][0];
430 out[1] = xc * matrix[0][1] + yc * matrix[1][1] + zc * matrix[2][1];
431 out[2] = xc * matrix[0][2] + yc * matrix[1][2] + zc * matrix[2][2];
432 }
433 }