view include/Matrix.h @ 13:e00321d11fe1

to_string simplified. Added Vector constructors from smaller vectors. Added rotation and transform matrix calculation functions.
author Eris Caffee <discordia@eldalin.com>
date Wed, 08 May 2013 22:50:09 -0500
parents 1d2b25d4517f
children ea32c94fc495
line source
1 #ifndef MATRIX_H_
2 #define MATRIX_H_
4 #include "Vector.h"
6 #include <cmath>
7 #include <cstring>
8 #include <string>
9 #include <sstream>
11 namespace arda
12 {
13 namespace Math
14 {
15 //////////////////////////////////////////////////////////////////////////
16 // Maxtrices
17 //
18 // Supported operations on matrices
19 //
20 // []
21 // If you have a Matrix named m you can access it's member elements as
22 // m[0], m[1], m[2], etc. The indexing is COLUMN MAJOR. So for a 2x2
23 // matrix, m[0] and m[1] are the elements of the first column, not the
24 // first row.
25 // == != + += - -=
26 // Defined for operations on two matrices of the same type.
27 // * *= / /=
28 // Defined for scalar multiplication/division with int, float, and double.
29 // * is defined as a standalone template operator for the scalar * Matrix
30 // form.
31 // * *=
32 // Also defined for Matrix * Matrix
33 //
34 // assign() Assign the value of one matrix to another.
35 // getcol() Returns the vector that is column n of the matrix.
36 // to_string() Returns a printable string representation of the matrix.
37 // setcol() Set the vector that is column n of the matrix.
38 // Overloaded so that you can set from a vector or from
39 // specific values.
40 // setidentity() Sets a matrix to the identity matrix.
41 //
42 //
43 //
44 // The following are functions, not class methods. This is because I think
45 // that the notation det(m) and transpose(m), for example, is more natural
46 // to write and read than m.det() and m.transpose(). Using functional
47 // notation just more naturally mimics the standard mathematical notation.
48 //
49 // det() Calculates the determinant of a matrix.
50 // transpose() Returns the transpose of a matrix.
52 //////////////////////////////////////////////////////////////////////////
53 template <typename T>
54 class Matrix22
55 {
56 public:
57 T m[4];
59 // Constructors
60 Matrix22() {}
61 explicit Matrix22(T a) { m[0] = m[1] = m[2] = m[3] = a; }
62 Matrix22(T a0, T a1, T a2, T a3)
63 {
64 m[0] = a0; m[2] = a2;
65 m[1] = a1; m[3] = a3;
66 }
68 // Array indexing
69 // Remember: column major order is used.
70 inline T& operator[](unsigned int const i)
71 { assert (i<4); return m[i]; }
72 inline T operator[](unsigned int const i) const
73 { assert (i<4); return m[i]; }
75 // Assignment
76 inline Matrix22<T>& operator=(Matrix22<T> const & m2)
77 {
78 m[0] = m2[0]; m[2] = m2[2];
79 m[1] = m2[1]; m[3] = m2[3];
80 return *this;
81 }
82 inline Matrix22<T>& assign(T const a0, T const a1,
83 T const a2, T const a3)
84 {
85 m[0] = a0; m[2] = a2;
86 m[1] = a1; m[3] = a3;
87 return *this;
88 }
90 // Comparison
91 inline bool operator==(Matrix22<T> const & m2) const
92 {
93 return
94 m[0] == m2[0] && m[2] == m2[2] &&
95 m[1] == m2[1] && m[3] == m2[3];
96 }
97 inline bool operator!=(Matrix22<T> const & m2) const
98 { return ! (*this == m2); }
100 // Matrix addition
101 inline Matrix22<T>& operator+=(Matrix22<T> const & m2)
102 {
103 m[0] += m2[0]; m[2] += m2[2];
104 m[1] += m2[1]; m[3] += m2[3];
105 return *this;
106 }
107 inline Matrix22<T> operator+(Matrix22<T> const & m2) const
108 { return Matrix22<T>(*this) += m2; }
110 // Matrix subtraction
111 inline Matrix22<T>& operator-=(Matrix22<T> const & m2)
112 {
113 m[0] -= m2[0]; m[2] -= m2[2];
114 m[1] -= m2[1]; m[3] -= m2[3];
115 return *this;
116 }
117 inline Matrix22<T> operator-(Matrix22<T> const & m2) const
118 { return Matrix22<T>(*this) -= m2; }
120 // Scalar multiplication
121 inline Matrix22<T>& operator*=(int const a)
122 {
123 m[0] *= a; m[2] *= a;
124 m[1] *= a; m[3] *= a;
125 return *this;
126 }
127 inline Matrix22<T>& operator*=(float const a)
128 {
129 m[0] *= a; m[2] *= a;
130 m[1] *= a; m[3] *= a;
131 return *this;
132 }
133 inline Matrix22<T>& operator*=(double const a)
134 {
135 m[0] *= a; m[2] *= a;
136 m[1] *= a; m[3] *= a;
137 return *this;
138 }
140 // Scalar division
141 inline Matrix22<T>& operator/=(int const a)
142 {
143 assert(a!=0);
144 m[0] /= a; m[2] /= a;
145 m[1] /= a; m[3] /= a;
146 return *this;
147 }
148 inline Matrix22<T>& operator/=(float const a)
149 {
150 assert(a!=0);
151 m[0] /= a; m[2] /= a;
152 m[1] /= a; m[3] /= a;
153 return *this;
154 }
155 inline Matrix22<T>& operator/=(double const a)
156 {
157 assert(a!=0);
158 m[0] /= a; m[2] /= a;
159 m[1] /= a; m[3] /= a;
160 return *this;
161 }
162 inline Matrix22<T> operator/(int const a)
163 { return Matrix22<T>(*this) /= a; }
164 inline Matrix22<T> operator/(float const a)
165 { return Matrix22<T>(*this) /= a; }
166 inline Matrix22<T> operator/(double const a)
167 { return Matrix22<T>(*this) /= a; }
169 // Matrix multiplication
170 // Not sure if this should be inlined at all. Sure the compiler will
171 // probably ignore the inline request here, but maybe it won't and maybe
172 // that would be bad. Needs real testing.
173 inline Matrix22<T>& operator*=(Matrix22<T> const & m2)
174 {
175 const int size=2;
176 Matrix22<T> mres(0);
177 int i, j, k;
178 for (i=0; i<size; ++i)
179 for (j=0; j<size; ++j)
180 for (k=0; k<size; ++k)
181 mres[size*i+j] += (*this)[size*k+j] * m2[size*i+k];
182 *this = mres;
183 return *this;
184 }
185 inline Matrix22<T> operator*(Matrix22<T> const & m2) const
186 { return Matrix22<T>(*this) *= m2; }
189 inline Vector2<T> getcol(unsigned int const i) const
190 {
191 assert(i<2);
192 int const size=2;
193 return Vector2<T>(m[i*size], m[i*size+1]);
194 }
196 inline Vector2<T> getrow(unsigned int const i) const
197 {
198 assert(i<2);
199 int const size=2;
200 return Vector2<T>(m[i], m[i+size]);
201 }
203 inline Matrix22<T>& setcol(unsigned int const i, Vector2<T> const & v)
204 {
205 assert(i<2);
206 int const size=2;
207 m[i*size] = v[0];
208 m[i*size+1] = v[1];
209 return *this;
210 }
212 inline Matrix22<T>& setcol(unsigned int const i, T const a, T const b)
213 {
214 assert(i<2);
215 const int size=2;
216 m[i*size] = a;
217 m[i*size+1] = b;
218 return *this;
219 }
221 inline Matrix22<T>& setrow(unsigned int const i, Vector2<T> const & v)
222 {
223 assert(i<2);
224 int const size=2;
225 m[i] = v[0];
226 m[i+size] = v[1];
227 return *this;
228 }
230 inline Matrix22<T>& setrow(unsigned int const i, T const a, T const b)
231 {
232 assert(i<2);
233 int const size=2;
234 m[i] = a;
235 m[i+size] = b;
236 return *this;
237 }
239 std::string to_string(void) const;
241 inline Matrix22<T>& setidentity()
242 {
243 memset(m, 0, sizeof(m));
244 m[0] = m[3] = 1;
245 return *this;
246 }
248 };
250 // Scalar multiplication continued
251 template <typename T>
252 inline Matrix22<T> operator*(Matrix22<T> const & m, int const a)
253 { return Matrix22<T>(m) *= a; }
255 template <typename T>
256 inline Matrix22<T> operator*(int const a, Matrix22<T> const & m)
257 { return Matrix22<T>(m) *= a; }
259 template <typename T>
260 inline Matrix22<T> operator*(Matrix22<T> const & m, float const a)
261 { return Matrix22<T>(m) *= a; }
263 template <typename T>
264 inline Matrix22<T> operator*(float const a, Matrix22<T> const & m)
265 { return Matrix22<T>(m) *= a; }
267 template <typename T>
268 inline Matrix22<T> operator*(Matrix22<T> const & m, double const a)
269 { return Matrix22<T>(m) *= a; }
271 template <typename T>
272 inline Matrix22<T> operator*(double const a, Matrix22<T> const & m)
273 { return Matrix22<T>(m) *= a; }
278 //////////////////////////////////////////////////////////////////////////
279 template <typename T>
280 class Matrix33
281 {
282 public:
283 T m[9];
285 // Constructors
286 Matrix33() {}
287 explicit Matrix33(T a)
288 {
289 // TODO: Is this really more efficient than memset?
290 m[0] = m[1] = m[2] = m[3] = m[4] = m[5] = m[6] = m[7] = m[8] = a;
291 }
292 Matrix33(T a0, T a1, T a2,
293 T a3, T a4, T a5,
294 T a6, T a7, T a8)
295 {
296 m[0] = a0; m[3] = a3; m[6] = a6;
297 m[1] = a1; m[4] = a4; m[7] = a7;
298 m[2] = a2; m[5] = a5; m[8] = a8;
299 }
301 // Array indexing
302 // Remember: column major order is used.
303 inline T& operator[](unsigned int const i)
304 { assert (i<9); return m[i]; }
305 inline T operator[](unsigned int const i) const
306 { assert (i<9); return m[i]; }
308 // Assignment
309 inline Matrix33<T>& operator=(Matrix33<T> const & m2)
310 {
311 m[0] = m2[0]; m[3] = m2[3]; m[6] = m2[6];
312 m[1] = m2[1]; m[4] = m2[4]; m[7] = m2[7];
313 m[2] = m2[2]; m[5] = m2[5]; m[8] = m2[8];
314 return *this;
315 }
316 inline Matrix33<T>& assign(T const a0, T const a1, T const a2,
317 T const a3, T const a4, T const a5,
318 T const a6, T const a7, T const a8)
319 {
320 m[0] = a0; m[3] = a3; m[6] = a6;
321 m[1] = a1; m[4] = a4; m[7] = a7;
322 m[2] = a2; m[5] = a5; m[8] = a8;
323 return *this;
324 }
326 // Comparison
327 inline bool operator==(Matrix33<T> const & m2) const
328 {
329 return
330 m[0] == m2[0] && m[3] == m2[3] && m[6] == m2[6] &&
331 m[1] == m2[1] && m[4] == m2[4] && m[7] == m2[7] &&
332 m[2] == m2[2] && m[5] == m2[5] && m[8] == m2[8];
333 }
334 inline bool operator!=(Matrix33<T> const & m2) const
335 { return ! (*this == m2); }
337 // Matrix addition
338 inline Matrix33<T>& operator+=(Matrix33<T> const & m2)
339 {
340 m[0] += m2[0]; m[3] += m2[3]; m[6] += m2[6];
341 m[1] += m2[1]; m[4] += m2[4]; m[7] += m2[7];
342 m[2] += m2[2]; m[5] += m2[5]; m[8] += m2[8];
343 return *this;
344 }
345 inline Matrix33<T> operator+(Matrix33<T> const & m2) const
346 { return Matrix33<T>(*this) += m2; }
348 // Matrix subtraction
349 inline Matrix33<T>& operator-=(Matrix33<T> const & m2)
350 {
351 m[0] -= m2[0]; m[3] -= m2[3]; m[6] -= m2[6];
352 m[1] -= m2[1]; m[4] -= m2[4]; m[7] -= m2[7];
353 m[2] -= m2[2]; m[5] -= m2[5]; m[8] -= m2[8];
354 return *this;
355 }
356 inline Matrix33<T> operator-(Matrix33<T> const & m2) const
357 { return Matrix33<T>(*this) -= m2; }
359 // Scalar multiplication
360 inline Matrix33<T>& operator*=(int const a)
361 {
362 m[0] *= a; m[3] *= a; m[6] *= a;
363 m[1] *= a; m[4] *= a; m[7] *= a;
364 m[2] *= a; m[5] *= a; m[8] *= a;
365 return *this;
366 }
367 inline Matrix33<T>& operator*=(float const a)
368 {
369 m[0] *= a; m[3] *= a; m[6] *= a;
370 m[1] *= a; m[4] *= a; m[7] *= a;
371 m[2] *= a; m[5] *= a; m[8] *= a;
372 return *this;
373 }
374 inline Matrix33<T>& operator*=(double const a)
375 {
376 m[0] *= a; m[3] *= a; m[6] *= a;
377 m[1] *= a; m[4] *= a; m[7] *= a;
378 m[2] *= a; m[5] *= a; m[8] *= a;
379 return *this;
380 }
382 // Scalar division
383 inline Matrix33<T>& operator/=(int const a)
384 {
385 assert(a!=0);
386 m[0] /= a; m[3] /= a; m[6] /= a;
387 m[1] /= a; m[4] /= a; m[7] /= a;
388 m[2] /= a; m[5] /= a; m[8] /= a;
389 return *this;
390 }
391 inline Matrix33<T>& operator/=(float const a)
392 {
393 assert(a!=0);
394 m[0] /= a; m[3] /= a; m[6] /= a;
395 m[1] /= a; m[4] /= a; m[7] /= a;
396 m[2] /= a; m[5] /= a; m[8] /= a;
397 return *this;
398 }
399 inline Matrix33<T>& operator/=(double const a)
400 {
401 assert(a!=0);
402 m[0] /= a; m[3] /= a; m[6] /= a;
403 m[1] /= a; m[4] /= a; m[7] /= a;
404 m[2] /= a; m[5] /= a; m[8] /= a;
405 return *this;
406 }
407 inline Matrix33<T> operator/(int const a)
408 { return Matrix33<T>(*this) /= a; }
409 inline Matrix33<T> operator/(float const a)
410 { return Matrix33<T>(*this) /= a; }
411 inline Matrix33<T> operator/(double const a)
412 { return Matrix33<T>(*this) /= a; }
414 // Matrix multiplication
415 // Not sure if this should be inlined at all. Sure the compiler will
416 // probably ignore the inline request here, but maybe it won't and maybe
417 // that would be bad. Needs real testing.
418 inline Matrix33<T>& operator*=(Matrix33<T> const & m2)
419 {
420 const int size=3;
421 Matrix33<T> mres(0);
422 int i, j, k;
423 for (i=0; i<size; ++i)
424 for (j=0; j<size; ++j)
425 for (k=0; k<size; ++k)
426 mres[size*i+j] += (*this)[size*k+j] * m2[size*i+k];
427 *this = mres;
428 return *this;
429 }
430 inline Matrix33<T> operator*(Matrix33<T> const & m2) const
431 { return Matrix33<T>(*this) *= m2; }
434 inline Vector3<T> getcol(unsigned int const i) const
435 {
436 assert(i<3);
437 const int size=3;
438 return Vector3<T>(m[i*size], m[i*size+1], m[i*size+2]);
439 }
441 inline Vector3<T> getrow(unsigned int const i) const
442 {
443 assert(i<3);
444 const int size=3;
445 return Vector3<T>(m[i], m[i+size], m[i+2*size]);
446 }
448 inline Matrix33<T>& setcol(unsigned int const i, Vector3<T> const & v)
449 {
450 assert(i<3);
451 const int size=3;
452 m[i*size] = v[0];
453 m[i*size+1] = v[1];
454 m[i*size+2] = v[2];
455 return *this;
456 }
458 inline Matrix33<T>& setcol(unsigned int const i,
459 T const a0, T const a1, T const a2)
460 {
461 assert(i<3);
462 const int size=3;
463 m[i*size] = a0;
464 m[i*size+1] = a1;
465 m[i*size+2] = a2;
466 return *this;
467 }
469 inline Matrix33<T>& setrow(unsigned int const i, Vector3<T> const & v)
470 {
471 assert(i<3);
472 const int size=3;
473 m[i] = v[0];
474 m[i+size] = v[1];
475 m[i+2*size] = v[2];
476 return *this;
477 }
479 inline Matrix33<T>& setrow(unsigned int const i,
480 T const a0, T const a1, T const a2)
481 {
482 assert(i<3);
483 const int size=3;
484 m[i] = a0;
485 m[i+size] = a1;
486 m[i+2*size] = a2;
487 return *this;
488 }
490 std::string to_string(void) const;
492 inline Matrix33<T>& setidentity()
493 {
494 memset(m, 0, sizeof(m));
495 m[0] = m[4] = m[8] = 1;
496 return *this;
497 }
499 };
501 // Scalar multiplication continued
502 template <typename T>
503 inline Matrix33<T> operator*(Matrix33<T> const & m, int const a)
504 { return Matrix33<T>(m) *= a; }
506 template <typename T>
507 inline Matrix33<T> operator*(int const a, Matrix33<T> const & m)
508 { return Matrix33<T>(m) *= a; }
510 template <typename T>
511 inline Matrix33<T> operator*(Matrix33<T> const & m, float const a)
512 { return Matrix33<T>(m) *= a; }
514 template <typename T>
515 inline Matrix33<T> operator*(float const a, Matrix33<T> const & m)
516 { return Matrix33<T>(m) *= a; }
518 template <typename T>
519 inline Matrix33<T> operator*(Matrix33<T> const & m, double const a)
520 { return Matrix33<T>(m) *= a; }
522 template <typename T>
523 inline Matrix33<T> operator*(double const a, Matrix33<T> const & m)
524 { return Matrix33<T>(m) *= a; }
529 //////////////////////////////////////////////////////////////////////////
530 template <typename T>
531 class Matrix44
532 {
533 public:
534 T m[16];
536 // Constructors
537 Matrix44() {}
538 explicit Matrix44(T a)
539 {
540 // TODO: Is this really more efficient than memset?
541 m[0] = m[1] = m[2] = m[3] = m[4] = m[5] = m[6] = m[7] = m[8] =
542 m[9] = m[10] = m[11] = m[12] = m[13] = m[14] = m[15] = a;
543 }
544 Matrix44(T a0, T a1, T a2, T a3,
545 T a4, T a5, T a6, T a7,
546 T a8, T a9, T a10, T a11,
547 T a12, T a13, T a14, T a15)
548 {
549 m[0] = a0; m[4] = a4; m[8] = a8; m[12] = a12;
550 m[1] = a1; m[5] = a5; m[9] = a9; m[13] = a13;
551 m[2] = a2; m[6] = a6; m[10] = a10; m[14] = a14;
552 m[3] = a3; m[7] = a7; m[11] = a11; m[15] = a15;
553 }
555 // Array indexing
556 // Remember: column major order is used.
557 inline T& operator[](unsigned int const i)
558 { assert (i<16); return m[i]; }
559 inline T operator[](unsigned int const i) const
560 { assert (i<16); return m[i]; }
562 // Assignment
563 inline Matrix44<T>& operator=(Matrix44<T> const & m2)
564 {
565 m[0] = m2[0]; m[4] = m2[4]; m[8] = m2[8]; m[12] = m2[12];
566 m[1] = m2[1]; m[5] = m2[5]; m[9] = m2[9]; m[13] = m2[13];
567 m[2] = m2[2]; m[6] = m2[6]; m[10] = m2[10]; m[14] = m2[14];
568 m[3] = m2[3]; m[7] = m2[7]; m[11] = m2[11]; m[15] = m2[15];
569 return *this;
570 }
571 inline Matrix44<T>& assign(T const a0, T const a1, T const a2, T const a3,
572 T const a4, T const a5, T const a6, T const a7,
573 T const a8, T const a9, T const a10, T const a11,
574 T const a12, T const a13, T const a14, T const a15)
575 {
576 m[0] = a0; m[4] = a4; m[8] = a8; m[12] = a12;
577 m[1] = a1; m[5] = a5; m[9] = a9; m[13] = a13;
578 m[2] = a2; m[6] = a6; m[10] = a10; m[14] = a14;
579 m[3] = a3; m[7] = a7; m[11] = a11; m[15] = a15;
580 return *this;
581 }
583 // Comparison
584 inline bool operator==(Matrix44<T> const & m2) const
585 {
586 // TODO: Should this use memcmp?
587 return
588 m[0] == m2[0] && m[4] == m2[4] && m[8] == m2[8] && m[12] == m2[12] &&
589 m[1] == m2[1] && m[5] == m2[5] && m[9] == m2[9] && m[13] == m2[13] &&
590 m[2] == m2[2] && m[6] == m2[6] && m[10] == m2[10] && m[14] == m2[14] &&
591 m[3] == m2[3] && m[7] == m2[7] && m[11] == m2[11] && m[15] == m2[15];
592 }
593 inline bool operator!=(Matrix44<T> const & m2) const
594 { return ! (*this == m2); }
596 // Matrix addition
597 inline Matrix44<T>& operator+=(Matrix44<T> const & m2)
598 {
599 m[0] += m2[0]; m[4] += m2[4]; m[8] += m2[8]; m[12] += m2[12];
600 m[1] += m2[1]; m[5] += m2[5]; m[9] += m2[9]; m[13] += m2[13];
601 m[2] += m2[2]; m[6] += m2[6]; m[10] += m2[10]; m[14] += m2[14];
602 m[3] += m2[3]; m[7] += m2[7]; m[11] += m2[11]; m[15] += m2[15];
603 return *this;
604 }
605 inline Matrix44<T> operator+(Matrix44<T> const & m2) const
606 { return Matrix44<T>(*this) += m2; }
608 // Matrix subtraction
609 inline Matrix44<T>& operator-=(Matrix44<T> const & m2)
610 {
611 m[0] -= m2[0]; m[4] -= m2[4]; m[8] -= m2[8]; m[12] -= m2[12];
612 m[1] -= m2[1]; m[5] -= m2[5]; m[9] -= m2[9]; m[13] -= m2[13];
613 m[2] -= m2[2]; m[6] -= m2[6]; m[10] -= m2[10]; m[14] -= m2[14];
614 m[3] -= m2[3]; m[7] -= m2[7]; m[11] -= m2[11]; m[15] -= m2[15];
615 return *this;
616 }
617 inline Matrix44<T> operator-(Matrix44<T> const & m2) const
618 { return Matrix44<T>(*this) -= m2; }
620 // Scalar multiplication
621 inline Matrix44<T>& operator*=(int const a)
622 {
623 m[0] *= a; m[4] *= a; m[8] *= a; m[12] *= a;
624 m[1] *= a; m[5] *= a; m[9] *= a; m[13] *= a;
625 m[2] *= a; m[6] *= a; m[10] *= a; m[14] *= a;
626 m[3] *= a; m[7] *= a; m[11] *= a; m[15] *= a;
627 return *this;
628 }
629 inline Matrix44<T>& operator*=(float const a)
630 {
631 m[0] *= a; m[4] *= a; m[8] *= a; m[12] *= a;
632 m[1] *= a; m[5] *= a; m[9] *= a; m[13] *= a;
633 m[2] *= a; m[6] *= a; m[10] *= a; m[14] *= a;
634 m[3] *= a; m[7] *= a; m[11] *= a; m[15] *= a;
635 return *this;
636 }
637 inline Matrix44<T>& operator*=(double const a)
638 {
639 m[0] *= a; m[4] *= a; m[8] *= a; m[12] *= a;
640 m[1] *= a; m[5] *= a; m[9] *= a; m[13] *= a;
641 m[2] *= a; m[6] *= a; m[10] *= a; m[14] *= a;
642 m[3] *= a; m[7] *= a; m[11] *= a; m[15] *= a;
643 return *this;
644 }
646 // Scalar division
647 inline Matrix44<T>& operator/=(int const a)
648 {
649 assert(a!=0);
650 m[0] /= a; m[4] /= a; m[8] /= a; m[12] /= a;
651 m[1] /= a; m[5] /= a; m[9] /= a; m[13] /= a;
652 m[2] /= a; m[6] /= a; m[10] /= a; m[14] /= a;
653 m[3] /= a; m[7] /= a; m[11] /= a; m[15] /= a;
654 return *this;
655 }
656 inline Matrix44<T>& operator/=(float const a)
657 {
658 assert(a!=0);
659 m[0] /= a; m[4] /= a; m[8] /= a; m[12] /= a;
660 m[1] /= a; m[5] /= a; m[9] /= a; m[13] /= a;
661 m[2] /= a; m[6] /= a; m[10] /= a; m[14] /= a;
662 m[3] /= a; m[7] /= a; m[11] /= a; m[15] /= a;
663 return *this;
664 }
665 inline Matrix44<T>& operator/=(double const a)
666 {
667 assert(a!=0);
668 m[0] /= a; m[4] /= a; m[8] /= a; m[12] /= a;
669 m[1] /= a; m[5] /= a; m[9] /= a; m[13] /= a;
670 m[2] /= a; m[6] /= a; m[10] /= a; m[14] /= a;
671 m[3] /= a; m[7] /= a; m[11] /= a; m[15] /= a;
672 return *this;
673 }
674 inline Matrix44<T> operator/(int const a)
675 { return Matrix44<T>(*this) /= a; }
676 inline Matrix44<T> operator/(float const a)
677 { return Matrix44<T>(*this) /= a; }
678 inline Matrix44<T> operator/(double const a)
679 { return Matrix44<T>(*this) /= a; }
681 // Matrix multiplication
682 // Not sure if this should be inlined at all. Sure the compiler will
683 // probably ignore the inline request here, but maybe it won't and maybe
684 // that would be bad. Needs real testing.
685 inline Matrix44<T>& operator*=(Matrix44<T> const & m2)
686 {
687 const int size=4;
688 Matrix44<T> mres(0);
689 int i, j, k;
690 for (i=0; i<size; ++i)
691 for (j=0; j<size; ++j)
692 for (k=0; k<size; ++k)
693 mres[size*i+j] += (*this)[size*k+j] * m2[size*i+k];
694 *this = mres;
695 return *this;
696 }
697 inline Matrix44<T> operator*(Matrix44<T> const & m2) const
698 { return Matrix44<T>(*this) *= m2; }
701 inline Vector4<T> getcol(unsigned int const i) const
702 {
703 assert(i<4);
704 const int size=4;
705 return Vector4<T>(m[i*size], m[i*size+1], m[i*size+2], m[i*size+3]);
706 }
708 inline Vector4<T> getrow(unsigned int const i) const
709 {
710 assert(i<4);
711 const int size=4;
712 return Vector4<T>(m[i], m[i+size], m[i+2*size], m[i+3*size]);
713 }
715 inline Matrix44<T>& setcol(unsigned int const i, Vector4<T> const & v)
716 {
717 assert(i<4);
718 const int size=4;
719 m[i*size] = v[0];
720 m[i*size+1] = v[1];
721 m[i*size+2] = v[2];
722 m[i*size+3] = v[3];
723 return *this;
724 }
726 inline Matrix44<T>& setcol(unsigned int const i,
727 T const a0, T const a1, T const a2, T const a3)
728 {
729 assert(i<4);
730 const int size=4;
731 m[i*size] = a0;
732 m[i*size+1] = a1;
733 m[i*size+2] = a2;
734 m[i*size+3] = a3;
735 return *this;
736 }
738 inline Matrix44<T>& setrow(unsigned int const i, Vector4<T> const & v)
739 {
740 assert(i<4);
741 const int size=4;
742 m[i] = v[0];
743 m[i+size] = v[1];
744 m[i+2*size] = v[2];
745 m[i+3*size] = v[3];
746 return *this;
747 }
749 inline Matrix44<T>& setrow(unsigned int const i,
750 T const a0, T const a1, T const a2, T const a3)
751 {
752 assert(i<4);
753 const int size=4;
754 m[i] = a0;
755 m[i+size] = a1;
756 m[i+2*size] = a2;
757 m[i+3*size] = a3;
758 return *this;
759 }
761 std::string to_string(void) const;
763 inline Matrix44<T>& setidentity()
764 {
765 memset(m, 0, sizeof(m));
766 m[0] = m[5] = m[10] = m[15] = 1;
767 return *this;
768 }
770 };
772 // Scalar multiplication continued
773 template <typename T>
774 inline Matrix44<T> operator*(Matrix44<T> const & m, int const a)
775 { return Matrix44<T>(m) *= a; }
777 template <typename T>
778 inline Matrix44<T> operator*(int const a, Matrix44<T> const & m)
779 { return Matrix44<T>(m) *= a; }
781 template <typename T>
782 inline Matrix44<T> operator*(Matrix44<T> const & m, float const a)
783 { return Matrix44<T>(m) *= a; }
785 template <typename T>
786 inline Matrix44<T> operator*(float const a, Matrix44<T> const & m)
787 { return Matrix44<T>(m) *= a; }
789 template <typename T>
790 inline Matrix44<T> operator*(Matrix44<T> const & m, double const a)
791 { return Matrix44<T>(m) *= a; }
793 template <typename T>
794 inline Matrix44<T> operator*(double const a, Matrix44<T> const & m)
795 { return Matrix44<T>(m) *= a; }
800 //////////////////////////////////////////////////////////////////////////
801 typedef Matrix22<int> Matrix22i;
802 typedef Matrix22<float> Matrix22f;
803 typedef Matrix22<double> Matrix22d;
805 typedef Matrix33<int> Matrix33i;
806 typedef Matrix33<float> Matrix33f;
807 typedef Matrix33<double> Matrix33d;
809 typedef Matrix44<int> Matrix44i;
810 typedef Matrix44<float> Matrix44f;
811 typedef Matrix44<double> Matrix44d;
814 //////////////////////////////////////////////////////////////////////////
815 // Matrix functions
816 // TODO: The determinant functions suffer from some bad round off error.
817 // If it significant? I don't know. None of the other game engines
818 // I've checked bother to do anything to calculate det more accurately.
819 // So maybe it just doesn't matter enough for game purposes.
821 template <typename T>
822 inline double det(Matrix22<T> const & m)
823 {
824 return (double) (m[0] * m[3]) - (double) (m[1] * m[2]);
825 }
827 template <typename T>
828 inline Matrix22<T> transpose(Matrix22<T> const & m)
829 {
830 const int size=2;
831 Matrix22<T> mres(0);
832 int i, j;
833 for (i=0; i<size; ++i)
834 for (j=0; j<size; j++)
835 mres[size*i+j] = m[size*j+i];
836 return mres;
837 }
839 template <typename T>
840 inline double det(Matrix33<T> const & m)
841 {
842 return m[0] * ( (double) m[4] * m[8] - (double) m[5] * m[7])
843 - m[3] * ( (double) m[1] * m[8] - (double) m[2] * m[7])
844 + m[6] * ( (double) m[1] * m[5] - (double) m[2] * m[4]);
845 }
846 template <typename T>
847 inline Matrix33<T> transpose(Matrix33<T> const & m)
848 {
849 const int size=3;
850 Matrix33<T> mres(0);
851 int i, j;
852 for (i=0; i<size; ++i)
853 for (j=0; j<size; j++)
854 mres[size*i+j] = m[size*j+i];
855 return mres;
856 }
858 template <typename T>
859 inline double det(Matrix44<T> const & m)
860 {
861 return m[0] * ( m[5] * (m[10] * m[15] - m[11] * m[14])
862 - m[9] * (m[6] * m[15] - m[7] * m[14])
863 + m[13] * (m[6] * m[11] - m[7] * m[10]))
864 - m[4] * ( m[1] * (m[10] * m[15] - m[11] * m[14])
865 - m[9] * (m[2] * m[15] - m[3] * m[14])
866 + m[13] * (m[2] * m[11] - m[3] * m[10]))
867 + m[8] * ( m[1] * (m[6] * m[15] - m[7] * m[14])
868 - m[5] * (m[2] * m[15] - m[3] * m[14])
869 + m[13] * (m[2] * m[7] - m[3] * m[6]))
870 + m[12] * ( m[1] * (m[6] * m[11] - m[7] * m[10])
871 - m[5] * (m[2] * m[11] - m[3] * m[10])
872 + m[9] * (m[2] * m[7] - m[3] * m[6]));
873 }
874 template <typename T>
875 inline Matrix44<T> transpose(Matrix44<T> const & m)
876 {
877 const int size=4;
878 Matrix44<T> mres(0);
879 int i, j;
880 for (i=0; i<size; ++i)
881 for (j=0; j<size; j++)
882 mres[size*i+j] = m[size*j+i];
883 return mres;
884 }
886 } // namespace Math
887 } // namespace arda
890 ////////////////////////////////////////////////////////////////////////////////
891 // Matrix methods
893 template <typename T>
894 std::string arda::Math::Matrix22<T>::to_string(void) const
895 {
896 std::stringstream ss;
897 ss << "[ "
898 "[ " << m[0] << ", " << m[1] << " ], "
899 "[ " << m[2] << ", " << m[3] << " ] ]";
900 return ss.str();
901 }
903 template <typename T>
904 std::string arda::Math::Matrix33<T>::to_string(void) const
905 {
906 std::stringstream ss;
907 ss << "[ "
908 "[ " << m[0] << ", " << m[1] << ", " << m[2] << " ], "
909 "[ " << m[3] << ", " << m[4] << ", " << m[5] << " ], "
910 "[ " << m[6] << ", " << m[7] << ", " << m[8] << " ], ""]";
911 return ss.str();
912 }
915 template <typename T>
916 std::string arda::Math::Matrix44<T>::to_string(void) const
917 {
918 std::stringstream ss;
919 ss << "[ "
920 "[ " << m[0] << ", " << m[1] << ", " << m[2] << ", " << m[3] << " ], "
921 "[ " << m[4] << ", " << m[5] << ", " << m[6] << ", " << m[7] << " ], "
922 "[ " << m[8] << ", " << m[9] << ", " << m[10] << ", " << m[11] << " ], "
923 "[ " << m[12] << ", " << m[13] << ", " << m[14] << ", " << m[15] << " ], ""]";
924 return ss.str();
925 }
927 #endif // MATRIX_H_