00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef __SGL_MAT2_HPP
00026 #define __SGL_MAT2_HPP
00027
00028 #include <sgl.h>
00029 #include <string.h>
00030 #include <sglVector.hpp>
00031 #include <sglVec2.hpp>
00032
00033
00034
00035 template <class T>
00036 class sglMat2
00037 {
00038 public:
00039
00040 sglMat2() {};
00041
00042 sglMat2(T m00, T m01, T m10, T m11) { set(m00, m01, m10, m11); }
00043
00044 template <class S>
00045 sglMat2(const sglMat2<S>& mat)
00046 {
00047 set(mat[0][0], mat[0][1], mat[1][0], mat[1][1]);
00048 }
00049
00050 template <class S>
00051 sglMat2(S mat[2][2])
00052 {
00053 set(mat[0][0], mat[0][1], mat[1][0], mat[1][1]);
00054 }
00055
00056
00057 ~sglMat2() {};
00058
00059 inline T *getPtr() const { return (T *)m_matrix; }
00060
00061
00062 inline sglVec2<T>& operator[](unsigned int i)
00063 {
00064 return *(sglVec2<T> *) m_matrix[i];
00065 }
00066 inline const sglVec2<T>& operator[](unsigned int i) const
00067 {
00068 return *(sglVec2<T> *) m_matrix[i];
00069 }
00070
00071
00072 template <class S>
00073 inline void set(S m00, S m01, S m10, S m11)
00074 {
00075 m_matrix[0][0] = (T)m00; m_matrix[0][1] = (T)m01;
00076 m_matrix[1][0] = (T)m10; m_matrix[1][1] = (T)m11;
00077 }
00078
00079 template <class S>
00080 inline void setRow(const sglVec2<S>& v, unsigned int i)
00081 {
00082 m_matrix[i][0] = (T)v[0]; m_matrix[i][1] = (T)v[1];
00083 }
00084
00085 template <class S>
00086 inline void setCol(const sglVec2<S>& v, unsigned int i)
00087 {
00088 m_matrix[0][i] = (T)v[0]; m_matrix[1][i] = (T)v[1];
00089 }
00090
00091 template <class S>
00092 inline void getRow(sglVec2<S>& v, unsigned int i)
00093 {
00094 v[0] = (S)m_matrix[i][0]; v[1] = (S)m_matrix[i][1];
00095 }
00096
00097 template <class S>
00098 inline void getCol(sglVec2<S>& v, unsigned int i)
00099 {
00100 v[0] = (S)m_matrix[0][i]; v[1] = (S)m_matrix[1][i];
00101 }
00102
00103
00104 template <class S>
00105 inline sglMat2 &operator=(const sglMat2<S>& mat)
00106 {
00107 set(mat[0][0], mat[0][1], mat[1][0], mat[1][1]);
00108 return *this;
00109 }
00110
00111
00112 template <class S>
00113 inline bool almostEqual(const sglMat2<S>& mat, double eps) const
00114 {
00115 return ((*this)[0].almostEqual(mat[0], eps) &&
00116 (*this)[1].almostEqual(mat[1], eps));
00117 }
00118
00119 template <class S>
00120 inline bool operator==(const sglMat2<S>& mat) const
00121 {
00122 return (*this)[0] == mat[0] && (*this)[1] == mat[1];
00123 }
00124
00125 template <class S>
00126 inline bool operator!=(const sglMat2<S>& mat) const
00127 {
00128 return (*this)[0] != mat[0] || (*this)[1] != mat[1];
00129 }
00130
00131
00132 template <class S>
00133 inline sglMat2& operator+=(const sglMat2<S>& mat)
00134 {
00135 (*this)[0] += mat[0], (*this)[1] += mat[1]; return *this;
00136 }
00137 template <class S>
00138 inline sglMat2& operator-=(const sglMat2<S>& mat)
00139 {
00140 (*this)[0] -= mat[0], (*this)[1] -= mat[1]; return *this;
00141 }
00142 template <class S>
00143 inline sglMat2& operator*=(const sglMat2<S>& mat)
00144 {
00145 mul(*this, mat); return *this;
00146 }
00147 inline sglMat2& operator*=(const T s)
00148 {
00149 scale(*this, s, s); return *this;
00150 }
00151
00152 template <class S>
00153 inline const sglMat2<T> operator+(const sglMat2<S> &rhs) const
00154 {
00155 return sglMat2(m_matrix[0][0] + rhs[0][0],
00156 m_matrix[0][1] + rhs[0][1],
00157 m_matrix[1][0] + rhs[1][0],
00158 m_matrix[1][1] + rhs[1][1]);
00159 }
00160 template <class S>
00161 inline const sglMat2<T> operator-(const sglMat2<S> &rhs) const
00162 {
00163 return sglMat2(m_matrix[0][0] - rhs[0][0],
00164 m_matrix[0][1] - rhs[0][1],
00165 m_matrix[1][0] - rhs[1][0],
00166 m_matrix[1][1] - rhs[1][1]);
00167 }
00168 template <class S>
00169 inline const sglMat2<T> operator*(const sglMat2<S> &rhs) const
00170 {
00171 return sglMat2(m_matrix[0][0]*rhs[0][0] + m_matrix[0][1]*rhs[1][0],
00172 m_matrix[0][0]*rhs[0][1] + m_matrix[0][1]*rhs[1][1],
00173 m_matrix[1][0]*rhs[0][0] + m_matrix[1][1]*rhs[1][0],
00174 m_matrix[1][0]*rhs[0][1] + m_matrix[1][1]*rhs[1][1]);
00175 }
00176 inline const sglMat2<T> operator*(T scalar) const
00177 {
00178 return sglMat2(m_matrix[0][0]*scalar,
00179 m_matrix[0][1]*scalar,
00180 m_matrix[1][0]*scalar,
00181 m_matrix[1][1]*scalar);
00182 }
00183
00184
00185 template <class S1, class S2>
00186 inline void add(const sglMat2<S1>& mat1, const sglMat2<S2>& mat2)
00187 {
00188 (*this)[0].add(mat1[0],mat2[0]);
00189 (*this)[1].add(mat1[1],mat2[1]);
00190 }
00191 template <class S1, class S2>
00192 inline void sub(const sglMat2<S1>& mat1, const sglMat2<S2>& mat2)
00193 {
00194 (*this)[0].sub(mat1[0],mat2[0]);
00195 (*this)[1].sub(mat1[1],mat2[1]);
00196 }
00197 template <class S>
00198 inline void scale(const sglMat2<S>& mat, T sx, T sy)
00199 {
00200 (*this)[0].scale(mat[0],sx);
00201 (*this)[1].scale(mat[1],sy);
00202 }
00203
00204 template <class S1, class S2>
00205 inline void mul(const sglMat2<S1>& mat1, const sglMat2<S2>& mat2)
00206 {
00207 T t[2][2];
00208 t[0][0] = mat1[0][0]*mat2[0][0] + mat1[0][1]*mat2[1][0];
00209 t[0][1] = mat1[0][0]*mat2[0][1] + mat1[0][1]*mat2[1][1];
00210 t[1][0] = mat1[1][0]*mat2[0][0] + mat1[1][1]*mat2[1][0];
00211 t[1][1] = mat1[1][0]*mat2[0][1] + mat1[1][1]*mat2[1][1];
00212 memcpy(m_matrix, t, sizeof(m_matrix));
00213 }
00214
00215
00216 inline void buildIdentity()
00217 {
00218 set(1, 0, 0, 1);
00219 }
00220
00221 inline void buildRotation(double angle)
00222 {
00223 T s = (T) sin(angle);
00224 T c = (T) cos(angle);
00225 m_matrix[0][0] = c; m_matrix[0][1] = s;
00226 m_matrix[1][0] = -s; m_matrix[1][1] = c;
00227 }
00228
00229 inline void buildScale(T sx, T sy)
00230 {
00231 m_matrix[0][0] = sx; m_matrix[0][1] = 0;
00232 m_matrix[1][0] = 0; m_matrix[1][1] = sy;
00233 }
00234
00235
00236
00237 inline void transpose()
00238 {
00239
00240 T tmp = m_matrix[0][1];
00241 m_matrix[0][1] = m_matrix[1][0];
00242 m_matrix[1][0] = tmp;
00243 }
00244
00245 template <class S>
00246 inline void transpose(const sglMat2<S>& mat)
00247 {
00248 m_matrix[0][0] = mat[0][0]; m_matrix[1][1] = mat[1][1];
00249
00250
00251 T tmp = mat[0][1]; m_matrix[0][1] = mat[1][0]; m_matrix[1][0] = tmp;
00252 }
00253
00254
00255 inline T cofactor(unsigned int r, unsigned int c) const
00256 {
00257 return (((r+c)&1) ? -1:1) * m_matrix[(r ? 0:1)][(c ? 0:1)];
00258 }
00259
00260 inline T det() const
00261 {
00262 return m_matrix[0][0]*cofactor(0,0) + m_matrix[0][1]*cofactor(0,1);
00263 }
00264
00265 template <class S>
00266 inline void adjoint(const sglMat2<S>& mat)
00267 {
00268 T t[2][2];
00269 t[0][0] = mat.cofactor(0,0);
00270 t[0][1] = mat.cofactor(1,0);
00271 t[1][0] = mat.cofactor(0,1);
00272 t[1][1] = mat.cofactor(1,1);
00273 set(t[0][0], t[0][1], t[1][0], t[1][1]);
00274 }
00275
00276 template <class S>
00277 inline bool inverse(const sglMat2<S>& mat)
00278 {
00279 T d = mat.det();
00280 if (SGL_ABS(d) < FLT_MIN) return false;
00281 adjoint(mat);
00282 *this *= (T)(1.0/d);
00283 return true;
00284 }
00285
00286
00287 #if defined(TEMPLATE_OSTREAM_HACK)
00288 template <class S>
00289 friend ostream& operator<<(ostream& ostrm, const sglMat2<S>& mat);
00290
00291 template <class S>
00292 friend istream& operator>>(istream& istrm, sglMat2<S>& mat);
00293 #else
00294 friend ostream& operator<<(ostream& ostrm, const sglMat2<T>& mat)
00295 {
00296 ostrm << '(';
00297 for (unsigned int i=0; i<2; i++)
00298 ostrm << '(' << mat[i][0] << ',' << mat[i][1] << ')';
00299 return (ostrm << ')');
00300 }
00301
00302 friend istream& operator>>(istream& istrm, sglMat2<T>& mat)
00303 {
00304 return (istrm >> mat[0][0] >> mat[0][1] >> mat[1][0] >> mat[1][1]);
00305 }
00306 #endif
00307
00308 private:
00309 T m_matrix[2][2];
00310 };
00311
00312
00313 #if defined(TEMPLATE_OSTREAM_HACK)
00314 template <class T>
00315 inline ostream& operator<<(ostream& ostrm, const sglMat2<T>& mat)
00316 {
00317 return (ostrm << '(' << mat[0] << ", " << mat[1] << ')');
00318 }
00319
00320 template <class T>
00321 inline istream& operator>>(istream& istrm, sglMat2<T>& mat)
00322 {
00323 return (istrm >> mat[0][0] >> mat[0][1] >> mat[1][0] >> mat[1][1]);
00324 }
00325 #endif
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 template <class S, class T>
00337 inline void mul(sglVec2<T>& vec, const sglMat2<S>& mat)
00338 {
00339 T x = (T)(vec[0]*mat[0][0] + vec[1]*mat[1][0]);
00340 vec[1] = (T)(vec[0]*mat[0][1] + vec[1]*mat[1][1]);
00341 vec[0] = x;
00342 }
00343
00344
00345
00346
00347
00348 template <class R, class S, class T>
00349 inline void mul(const sglVec2<R>& vec, const sglMat2<S>& mat,
00350 sglVec2<T>& dest)
00351 {
00352 T x = (T)(vec[0]*mat[0][0] + vec[1]*mat[1][0]);
00353 dest[1] = (T)(vec[0]*mat[0][1] + vec[1]*mat[1][1]);
00354 dest[0] = x;
00355 }
00356
00357
00358
00359
00360
00361 template <class S, class T>
00362 inline void mulTranspose(sglVec2<T>& vec, const sglMat2<S>& mat)
00363 {
00364 T x = (T)(vec[0]*mat[0][0] + vec[1]*mat[0][1]);
00365 vec[1] = (T)(vec[0]*mat[1][0] + vec[1]*mat[1][1]);
00366 vec[0] = x;
00367 }
00368
00369
00370
00371
00372 template <class R, class S, class T>
00373 inline void mulTranspose(const sglVec2<R>& vec, const sglMat2<S>& mat,
00374 sglVec2<T>& dest)
00375 {
00376 T x = (T)(vec[0]*mat[0][0] + vec[1]*mat[0][1]);
00377 dest[1] = (T)(vec[0]*mat[1][0] + vec[1]*mat[1][1]);
00378 dest[0] = x;
00379 }
00380
00381
00382 #endif