view include/Matrix.h @ 11:398894c52b69

Changed mind. Sticking with current design. Matrix22<T> is done.
author Eris Caffee <discordia@eldalin.com>
date Fri, 07 Oct 2011 13:33:48 -0500
parents 81d2aa42a860
children 1d2b25d4517f
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 // getstring() 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> class Matrix22
54 {
55 public:
56 T m[4];
58 // Constructors
59 Matrix22() {}
60 explicit Matrix22(T a) { m[0] = m[1] = m[2] = m[3] = a; }
61 Matrix22(T a0, T a1, T a2, T a3)
62 {
63 m[0] = a0; m[2] = a2;
64 m[1] = a1; m[3] = a3;
65 }
67 // Array indexing
68 // Remember: column major order is used.
69 inline T& operator[](unsigned int i)
70 { assert (i<4); return m[i]; }
71 inline T operator[](unsigned int i) const
72 { assert (i<4); return m[i]; }
74 // Assignment
75 inline Matrix22<T>& operator=(const Matrix22<T>& m2)
76 {
77 m[0] = m2[0]; m[2] = m2[2];
78 m[1] = m2[1]; m[3] = m2[3];
79 return *this;
80 }
81 inline Matrix22<T>& assign(T a0, T a1, T a2, T a3)
82 {
83 m[0] = a0; m[2] = a2;
84 m[1] = a1; m[3] = a3;
85 return *this;
86 }
88 // Comparison
89 inline bool operator==(Matrix22<T>& m2) const
90 {
91 return
92 m[0] == m2[0] && m[2] == m2[2] &&
93 m[1] == m2[1] && m[3] == m2[3];
94 }
95 inline bool operator!=(Matrix22<T>& m2) const
96 { return ! (*this == m2); }
98 // Matrix addition
99 inline Matrix22<T>& operator+=(const Matrix22<T>& m2)
100 {
101 m[0] += m2[0]; m[2] += m2[2];
102 m[1] += m2[1]; m[3] += m2[3];
103 return *this;
104 }
105 inline Matrix22<T> operator+(const Matrix22<T>& m2) const
106 { return Matrix22<T>(*this) += m2; }
108 // Matrix subtraction
109 inline Matrix22<T>& operator-=(const Matrix22<T>& m2)
110 {
111 m[0] -= m2[0]; m[2] -= m2[2];
112 m[1] -= m2[1]; m[3] -= m2[3];
113 return *this;
114 }
115 inline Matrix22<T> operator-(const Matrix22<T>& m2) const
116 { return Matrix22<T>(*this) -= m2; }
118 // Scalar multiplication
119 inline Matrix22<T>& operator*=(const int a)
120 {
121 m[0] *= a; m[2] *= a;
122 m[1] *= a; m[3] *= a;
123 return *this;
124 }
125 inline Matrix22<T>& operator*=(const float a)
126 {
127 m[0] *= a; m[2] *= a;
128 m[1] *= a; m[3] *= a;
129 return *this;
130 }
131 inline Matrix22<T>& operator*=(const double a)
132 {
133 m[0] *= a; m[2] *= a;
134 m[1] *= a; m[3] *= a;
135 return *this;
136 }
138 // Scalar division
139 inline Matrix22<T>& operator/=(const int a)
140 {
141 assert(a!=0);
142 m[0] /= a; m[2] /= a;
143 m[1] /= a; m[3] /= a;
144 return *this;
145 }
146 inline Matrix22<T>& operator/=(const float a)
147 {
148 assert(a!=0);
149 m[0] /= a; m[2] /= a;
150 m[1] /= a; m[3] /= a;
151 return *this;
152 }
153 inline Matrix22<T>& operator/=(const double a)
154 {
155 assert(a!=0);
156 m[0] /= a; m[2] /= a;
157 m[1] /= a; m[3] /= a;
158 return *this;
159 }
160 inline Matrix22<T> operator/(const int a)
161 { return Matrix22<T>(*this) /= a; }
162 inline Matrix22<T> operator/(const float a)
163 { return Matrix22<T>(*this) /= a; }
164 inline Matrix22<T> operator/(const double a)
165 { return Matrix22<T>(*this) /= a; }
167 // Matrix multiplication
168 // Not sure if this should be inlined at all. Sure the compiler will
169 // probably ignore the inline request here, but maybe it won't and maybe
170 // that would be bad. Needs real testing.
171 inline Matrix22<T>& operator*=(Matrix22<T> m2)
172 {
173 const int size=2;
174 Matrix22<T> mres(0);
175 int i, j, k;
176 for (i=0; i<size; ++i)
177 for (j=0; j<size; ++j)
178 for (k=0; k<size; ++k)
179 mres[size*i+j] += (*this)[size*k+j] * m2[size*i+k];
180 *this = mres;
181 return *this;
182 }
183 inline Matrix22<T> operator*(Matrix22<T> m2) const
184 { return Matrix22<T>(*this) *= m2; }
187 inline Vector2<T> getcol(const unsigned int i) const
188 {
189 assert(i<2);
190 const int size=2;
191 return Vector2<T>(m[i*size], m[i*size+1]);
192 }
194 inline Vector2<T> getrow(const unsigned int i) const
195 {
196 assert(i<2);
197 const int size=2;
198 return Vector2<T>(m[i], m[i+size]);
199 }
201 inline Matrix22<T>& setcol(const unsigned int i, const Vector2<T>& v)
202 {
203 assert(i<2);
204 const int size=2;
205 m[i*size] = v[0];
206 m[i*size+1] = v[1];
207 return *this;
208 }
210 inline Matrix22<T>& setcol(const unsigned int i, const T a, const T b)
211 {
212 assert(i<2);
213 const int size=2;
214 m[i*size] = a;
215 m[i*size+1] = b;
216 return *this;
217 }
219 inline Matrix22<T>& setrow(const unsigned int i, const Vector2<T>& v)
220 {
221 assert(i<2);
222 const int size=2;
223 m[i] = v[0];
224 m[i+size] = v[1];
225 return *this;
226 }
228 inline Matrix22<T>& setrow(const unsigned int i, const T a, const T b)
229 {
230 assert(i<2);
231 const int size=2;
232 m[i] = a;
233 m[i+size] = b;
234 return *this;
235 }
237 std::string & getstring(std::string & s) const;
239 inline Matrix22<T>& setidentity()
240 {
241 memset(m, 0, sizeof(m));
242 m[0] = m[3] = 1;
243 return *this;
244 }
246 };
248 // Scalar multiplication continued
249 template <typename T> inline Matrix22<T> operator*(const Matrix22<T>& m, const int a)
250 { return Matrix22<T>(m) *= a; }
251 template <typename T> inline Matrix22<T> operator*(const int a, const Matrix22<T>& m)
252 { return Matrix22<T>(m) *= a; }
253 template <typename T> inline Matrix22<T> operator*(const Matrix22<T>& m, const float a)
254 { return Matrix22<T>(m) *= a; }
255 template <typename T> inline Matrix22<T> operator*(const float a, const Matrix22<T>& m)
256 { return Matrix22<T>(m) *= a; }
257 template <typename T> inline Matrix22<T> operator*(const Matrix22<T>& m, const double a)
258 { return Matrix22<T>(m) *= a; }
259 template <typename T> inline Matrix22<T> operator*(const double a, const Matrix22<T>& m)
260 { return Matrix22<T>(m) *= a; }
265 //////////////////////////////////////////////////////////////////////////
266 typedef Matrix22<int> Matrix22i;
267 typedef Matrix22<float> Matrix22f;
268 typedef Matrix22<double> Matrix22d;
270 #ifdef NOTHING
271 typedef Matrix33<int> Matrix33i;
272 typedef Matrix33<float> Matrix33f;
273 typedef Matrix33<double> Matrix33d;
275 typedef Matrix44<int> Matrix44i;
276 typedef Matrix44<float> Matrix44f;
277 typedef Matrix44<double> Matrix44d;
279 #endif
283 //////////////////////////////////////////////////////////////////////////
284 // Matrix functions
286 template <typename T> inline double det(const Matrix22<T> m)
287 { return (double) (m[0] * m[3]) - (double) (m[1] * m[2]); }
289 template <typename T> inline Matrix22<T> transpose(const Matrix22<T>& m)
290 {
291 const int size=2;
292 Matrix22<T> mres(0);
293 int i, j;
294 for (i=0; i<size; ++i)
295 for (j=0; j<size; j++)
296 mres[size*i+j] = m[size*j+i];
297 return mres;
298 }
300 } // namespace Math
301 } // namespace arda
304 ////////////////////////////////////////////////////////////////////////////////
305 // Matrix methods
307 template <typename T> std::string & arda::Math::Matrix22<T>::getstring(std::string & s) const
308 {
309 s.clear();
310 std::stringstream ss;
311 ss << "[ "
312 "[ " << m[0] << ", " << m[1] << " ], "
313 "[ " << m[2] << ", " << m[3] << " ] ]";
314 s = ss.str();
315 return s;
316 }
329 #ifdef NOTHING
330 //////////////////////////////////////////////////////////////////////////
331 // det*(Matrix m)
332 // Computer the determinant of a matrix.
333 // Returns the determinant.
335 inline double det3(Matrix3i m)
336 { return m[0] * ( m[4] * m[8]
337 - m[5] * m[7])
338 - m[3] * ( m[1] * m[8]
339 - m[2] * m[7])
340 + m[6] * ( m[1] * m[5]
341 - m[2] * m[4]); }
343 inline double det4(Matrix4i m)
344 { return m[0] * (m[5] * (m[10] * m[15] -
345 m[11] * m[14]) -
346 m[9] * (m[6] * m[15] -
347 m[7] * m[14]) +
348 m[13] * (m[6] * m[11] -
349 m[7] * m[10])) -
350 m[4] * (m[1] * (m[10] * m[15] -
351 m[11] * m[14]) -
352 m[9] * (m[2] * m[15] -
353 m[3] * m[14]) +
354 m[13] * (m[2] * m[11] -
355 m[3] * m[10])) +
356 m[8] * (m[1] * (m[6] * m[15] -
357 m[7] * m[14]) -
358 m[5] * (m[2] * m[15] -
359 m[3] * m[14]) +
360 m[13] * (m[2] * m[7] -
361 m[3] * m[6])) +
362 m[12] * (m[1] * (m[6] * m[11] -
363 m[7] * m[10]) -
364 m[5] * (m[2] * m[11] -
365 m[3] * m[10]) +
366 m[9] * (m[2] * m[7] -
367 m[3] * m[6])); }
369 ////////////////////////////////////////////////////////////////////////////////
370 int * arda::Matrix::multvec3mv(Matrix3i m, Vector3i v, Vector3i vres)
371 {
372 vres[0] = m[0]*v[0] + m[3]*v[1] + m[6]*v[2];
373 vres[1] = m[1]*v[0] + m[4]*v[1] + m[7]*v[2];
374 vres[2] = m[2]*v[0] + m[5]*v[1] + m[8]*v[2];
375 return vres;
376 }
379 ////////////////////////////////////////////////////////////////////////////////
380 int * arda::Matrix::multvec4mv(Matrix4i m, Vector4i v, Vector4i vres)
381 {
382 vres[0] = m[0]*v[0] + m[4]*v[1] + m[8] *v[2] + m[12]*v[3];
383 vres[1] = m[1]*v[0] + m[5]*v[1] + m[9]*v[2] + m[13]*v[3];
384 vres[2] = m[2]*v[0] + m[6]*v[1] + m[10]*v[2] + m[14]*v[3];
385 vres[3] = m[3]*v[0] + m[7]*v[1] + m[11]*v[2] + m[15]*v[3];
386 return vres;
387 }
389 ////////////////////////////////////////////////////////////////////////////////
390 int * arda::Matrix::multvec3vm(Vector3i v, Matrix3i m, Vector3i vres)
391 {
392 vres[0] = v[0]*m[0] + v[1]*m[1] + v[2]*m[2];
393 vres[1] = v[0]*m[3] + v[1]*m[4] + v[2]*m[5];
394 vres[2] = v[0]*m[6] + v[1]*m[7] + v[2]*m[8];
395 return vres;
396 }
398 ////////////////////////////////////////////////////////////////////////////////
399 float * arda::Matrix::multvec4vm(Vector4f v, Matrix4f m, Vector4f vres)
400 {
401 vres[0] = v[0]*m[0] + v[1]*m[1] + v[2]*m[2] + v[3]*m[3];
402 vres[1] = v[0]*m[4] + v[1]*m[5] + v[2]*m[6] + v[3]*m[7];
403 vres[2] = v[0]*m[8] + v[1]*m[9] + v[2]*m[10] + v[3]*m[11];
404 vres[3] = v[0]*m[12] + v[1]*m[13] + v[2]*m[14] + v[3]*m[15];
405 return vres;
406 }
407 #endif
412 #endif // MATRIX_H_