view include/Matrix.h @ 9:81d2aa42a860

Matrix22 working, but a few methods not yet written. I started thinking about refactoring again t omake things even cleaner in design, with less repetition.
author Eris Caffee <discordia@eldalin.com>
date Fri, 07 Oct 2011 11:08:38 -0500
parents 378862555189
children 398894c52b69
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 //////////////////////////////////////////////////////////////////////////
14 // Maxtrices
15 //
16 // Supported operations on matrices
17 //
18 // []
19 // If you have a Matrix named m you can access it's member elements as
20 // m[0], m[1], m[2], etc. The indexing is COLUMN MAJOR. So for a 2x2
21 // matrix, m[0] and m[1] are the elements of the first column, not the
22 // first row.
23 // == != + += - -=
24 // Defined for operations on two matrices of the same type.
25 // * *= / /=
26 // Defined for scalar multiplication/division with int, float, and double.
27 // * is defined as a standalone template operator for the scalar * Matrix form.
28 // * *=
29 // Also defined for Matrix * Matrix
30 //
31 // assign() Assign the value of one matrix to another.
32 // det() Calculates the determinant of a matrix.
33 // getstring() Returns a printable string representation of the matrix.
34 // transpose() Returns the transpose of a matrix.
35 // setidentity() Sets a matrix to the identity matrix.
37 // inverse() Returns the inverse of a non-singular matrix.
38 // getcol() Returns the vector that is column n of the matrix.
39 // setcol() Set the vector that is column n of the matrix.
41 //////////////////////////////////////////////////////////////////////////
42 template <typename T> class Matrix22
43 {
44 public:
45 T m[4];
47 // Constructors
48 Matrix22() {}
49 Matrix22(T a) { m[0] = m[1] = m[2] = m[3] = a; }
50 Matrix22(T a0, T a1, T a2, T a3)
51 {
52 m[0] = a0; m[2] = a2;
53 m[1] = a1; m[3] = a3;
54 }
56 // Array indexing
57 // Remember: column major order is used.
58 inline T& operator[](unsigned int i)
59 { assert (i<4); return m[i]; }
60 inline const T& operator[](unsigned int i) const
61 { assert (i<4); return m[i]; }
63 // Assignment
64 inline Matrix22<T>& operator=(const Matrix22<T>& m2)
65 {
66 m[0] = m2[0]; m[2] = m2[2];
67 m[1] = m2[1]; m[3] = m2[3];
68 return *this;
69 }
70 inline Matrix22<T>& assign(T a0, T a1, T a2, T a3)
71 {
72 m[0] = a0; m[2] = a2;
73 m[1] = a1; m[3] = a3;
74 return *this;
75 }
77 // Comparison
78 inline bool operator==(Matrix22<T>& m2) const
79 {
80 return
81 m[0] == m2[0] && m[2] == m2[2] &&
82 m[1] == m2[1] && m[3] == m2[3];
83 }
84 inline bool operator!=(Matrix22<T>& m2) const
85 { return ! (*this == m2); }
87 // Matrix addition
88 inline Matrix22<T>& operator+=(const Matrix22<T>& m2)
89 {
90 m[0] += m2[0]; m[2] += m2[2];
91 m[1] += m2[1]; m[3] += m2[3];
92 return *this;
93 }
94 inline Matrix22<T> operator+(const Matrix22<T>& m2) const
95 { return Matrix22<T>(*this) += m2; }
97 // Matrix subtraction
98 inline Matrix22<T>& operator-=(const Matrix22<T>& m2)
99 {
100 m[0] -= m2[0]; m[2] -= m2[2];
101 m[1] -= m2[1]; m[3] -= m2[3];
102 return *this;
103 }
104 inline Matrix22<T> operator-(const Matrix22<T>& m2) const
105 { return Matrix22<T>(*this) -= m2; }
107 // Scalar multiplication
108 inline Matrix22<T>& operator*=(const int a)
109 {
110 m[0] *= a; m[2] *= a;
111 m[1] *= a; m[3] *= a;
112 return *this;
113 }
114 inline Matrix22<T>& operator*=(const float a)
115 {
116 m[0] *= a; m[2] *= a;
117 m[1] *= a; m[3] *= a;
118 return *this;
119 }
120 inline Matrix22<T>& operator*=(const double a)
121 {
122 m[0] *= a; m[2] *= a;
123 m[1] *= a; m[3] *= a;
124 return *this;
125 }
127 // Scalar division
128 inline Matrix22<T>& operator/=(const int a)
129 {
130 assert(a!=0);
131 m[0] /= a; m[2] /= a;
132 m[1] /= a; m[3] /= a;
133 return *this;
134 }
135 inline Matrix22<T>& operator/=(const float a)
136 {
137 assert(a!=0);
138 m[0] /= a; m[2] /= a;
139 m[1] /= a; m[3] /= a;
140 return *this;
141 }
142 inline Matrix22<T>& operator/=(const double a)
143 {
144 assert(a!=0);
145 m[0] /= a; m[2] /= a;
146 m[1] /= a; m[3] /= a;
147 return *this;
148 }
149 inline Matrix22<T> operator/(const int a)
150 { return Matrix22<T>(*this) /= a; }
151 inline Matrix22<T> operator/(const float a)
152 { return Matrix22<T>(*this) /= a; }
153 inline Matrix22<T> operator/(const double a)
154 { return Matrix22<T>(*this) /= a; }
156 // Matrix multiplication
157 // Not sure if this should be inlined at all. Sure the compiler will
158 // probably ignoe the inline request here, but maybe it won't and maybe
159 // that would be bad. Needs real testing.
160 inline Matrix22<T>& operator*=(Matrix22<T> m2)
161 {
162 const int size=2;
163 Matrix22<T> mres(0);
164 int i, j, k;
165 for (i=0; i<size; ++i)
166 for (j=0; j<size; ++j)
167 for (k=0; k<size; ++k)
168 mres[size*i+j] += (*this)[size*k+j] * m2[size*i+k];
169 *this = mres;
170 return *this;
171 }
172 inline Matrix22<T> operator*(Matrix22<T> m2) const
173 { return Matrix22<T>(*this) *= m2; }
175 // methods
176 inline double det() const
177 { return (double) (m[0] * m[3]) - (double) (m[1] * m[2]); }
179 std::string & getstring(std::string & s) const;
181 inline Matrix22<T>& setidentity()
182 {
183 memset(m, 0, sizeof(m));
184 m[0] = m[3] = 1;
185 return *this;
186 }
188 inline Matrix22<T> transpose() const
189 {
190 const int size=2;
191 Matrix22<T> mres(0);
192 int i, j;
193 for (i=0; i<size; ++i)
194 for (j=0; j<size; j++)
195 mres[size*i+j] = m[size*j+i];
196 return mres;
197 }
198 };
200 // Scalar multiplication continued
201 template <typename T> inline Matrix22<T> operator*(const Matrix22<T>& m, const int a)
202 { return Matrix22<T>(m) *= a; }
203 template <typename T> inline Matrix22<T> operator*(const int a, const Matrix22<T>& m)
204 { return Matrix22<T>(m) *= a; }
205 template <typename T> inline Matrix22<T> operator*(const Matrix22<T>& m, const float a)
206 { return Matrix22<T>(m) *= a; }
207 template <typename T> inline Matrix22<T> operator*(const float a, const Matrix22<T>& m)
208 { return Matrix22<T>(m) *= a; }
209 template <typename T> inline Matrix22<T> operator*(const Matrix22<T>& m, const double a)
210 { return Matrix22<T>(m) *= a; }
211 template <typename T> inline Matrix22<T> operator*(const double a, const Matrix22<T>& m)
212 { return Matrix22<T>(m) *= a; }
217 //////////////////////////////////////////////////////////////////////////
218 typedef Matrix22<int> Matrix22i;
219 typedef Matrix22<float> Matrix22f;
220 typedef Matrix22<double> Matrix22d;
222 #ifdef NOTHING
223 typedef Matrix33<int> Matrix33i;
224 typedef Matrix33<float> Matrix33f;
225 typedef Matrix33<double> Matrix33d;
227 typedef Matrix44<int> Matrix44i;
228 typedef Matrix44<float> Matrix44f;
229 typedef Matrix44<double> Matrix44d;
231 #endif
232 } // namespace arda
234 ////////////////////////////////////////////////////////////////////////////////
235 template <typename T> std::string & arda::Matrix22<T>::getstring(std::string & s) const
236 {
237 s.clear();
238 std::stringstream ss;
239 ss << "[ "
240 "[ " << m[0] << ", " << m[1] << " ], "
241 "[ " << m[2] << ", " << m[3] << " ] ]";
242 s = ss.str();
243 return s;
244 }
257 #ifdef NOTHING
258 //////////////////////////////////////////////////////////////////////////
259 // det*(Matrix m)
260 // Computer the determinant of a matrix.
261 // Returns the determinant.
263 inline double det3(Matrix3i m)
264 { return m[0] * ( m[4] * m[8]
265 - m[5] * m[7])
266 - m[3] * ( m[1] * m[8]
267 - m[2] * m[7])
268 + m[6] * ( m[1] * m[5]
269 - m[2] * m[4]); }
271 inline double det4(Matrix4i m)
272 { return m[0] * (m[5] * (m[10] * m[15] -
273 m[11] * m[14]) -
274 m[9] * (m[6] * m[15] -
275 m[7] * m[14]) +
276 m[13] * (m[6] * m[11] -
277 m[7] * m[10])) -
278 m[4] * (m[1] * (m[10] * m[15] -
279 m[11] * m[14]) -
280 m[9] * (m[2] * m[15] -
281 m[3] * m[14]) +
282 m[13] * (m[2] * m[11] -
283 m[3] * m[10])) +
284 m[8] * (m[1] * (m[6] * m[15] -
285 m[7] * m[14]) -
286 m[5] * (m[2] * m[15] -
287 m[3] * m[14]) +
288 m[13] * (m[2] * m[7] -
289 m[3] * m[6])) +
290 m[12] * (m[1] * (m[6] * m[11] -
291 m[7] * m[10]) -
292 m[5] * (m[2] * m[11] -
293 m[3] * m[10]) +
294 m[9] * (m[2] * m[7] -
295 m[3] * m[6])); }
297 ////////////////////////////////////////////////////////////////////////////////
298 int * arda::Matrix::multvec3mv(Matrix3i m, Vector3i v, Vector3i vres)
299 {
300 vres[0] = m[0]*v[0] + m[3]*v[1] + m[6]*v[2];
301 vres[1] = m[1]*v[0] + m[4]*v[1] + m[7]*v[2];
302 vres[2] = m[2]*v[0] + m[5]*v[1] + m[8]*v[2];
303 return vres;
304 }
307 ////////////////////////////////////////////////////////////////////////////////
308 int * arda::Matrix::multvec4mv(Matrix4i m, Vector4i v, Vector4i vres)
309 {
310 vres[0] = m[0]*v[0] + m[4]*v[1] + m[8] *v[2] + m[12]*v[3];
311 vres[1] = m[1]*v[0] + m[5]*v[1] + m[9]*v[2] + m[13]*v[3];
312 vres[2] = m[2]*v[0] + m[6]*v[1] + m[10]*v[2] + m[14]*v[3];
313 vres[3] = m[3]*v[0] + m[7]*v[1] + m[11]*v[2] + m[15]*v[3];
314 return vres;
315 }
317 ////////////////////////////////////////////////////////////////////////////////
318 int * arda::Matrix::multvec3vm(Vector3i v, Matrix3i m, Vector3i vres)
319 {
320 vres[0] = v[0]*m[0] + v[1]*m[1] + v[2]*m[2];
321 vres[1] = v[0]*m[3] + v[1]*m[4] + v[2]*m[5];
322 vres[2] = v[0]*m[6] + v[1]*m[7] + v[2]*m[8];
323 return vres;
324 }
326 ////////////////////////////////////////////////////////////////////////////////
327 float * arda::Matrix::multvec4vm(Vector4f v, Matrix4f m, Vector4f vres)
328 {
329 vres[0] = v[0]*m[0] + v[1]*m[1] + v[2]*m[2] + v[3]*m[3];
330 vres[1] = v[0]*m[4] + v[1]*m[5] + v[2]*m[6] + v[3]*m[7];
331 vres[2] = v[0]*m[8] + v[1]*m[9] + v[2]*m[10] + v[3]*m[11];
332 vres[3] = v[0]*m[12] + v[1]*m[13] + v[2]*m[14] + v[3]*m[15];
333 return vres;
334 }
335 #endif
340 #endif // MATRIX_H_