_Matrix3.h

Go to the documentation of this file.
00001 #ifndef __VECMATH_MATRIX3_HPP
00002 #define __VECMATH_MATRIX3_HPP
00003 
00004 #include <vecmath/Export>
00005 template <class Type> class VECMATH_EXPORT _Matrix3;
00006 
00007 #ifndef __VECMATH_VECTOR3_HPP
00008 #include <vecmath/_Vector3.h>
00009 #endif
00010 
00011 #ifndef __VECMATH_VECTOR4_HPP
00012 #include <vecmath/_Vector4.h>
00013 #endif
00014 
00015 #ifndef __VECMATH_QUAT4_HPP
00016 #include <vecmath/_Quat4.h>
00017 #endif
00018 
00019 //#ifndef __VECMATH_AXISANGLE4_HPP
00020 //#include <vecmath/_AxisAngle4.h>
00021 //#endif
00022 
00023 
00024 //#define DEBUGMATRIX3(d) d
00025 #define DEBUGMATRIX3(d)
00026 
00027 //template <class Type> ostream& operator <<(ostream& os, const _Matrix3<Type>& m);
00028 //template <class Type> ostream& operator <<(ostream& os, const _Matrix3<Type>* m);
00029 
00030 template <class Type> class VECMATH_EXPORT _Matrix3 {
00031 public:
00032         static const Type EPS;// = 1e-16;
00033     static const Type ERR_EPS;// = 1e-08;
00034 
00035         Type    m00, m01, m02,
00036             m10, m11, m12,
00037             m20, m21, m22;
00038 
00039     _Matrix3<Type>() {}
00040 
00041     _Matrix3<Type>(Type s) {
00042         set(s);
00043         DEBUGMATRIX3(cout << "_Matrix3 constructor scale " << endl << *this << endl);
00044     }
00045 
00046     // thinking about leaving the matrix unmodified for empty contructor
00047     // to safe couple of vasted cycles
00048     explicit _Matrix3<Type>(Type m00    , Type m01 = 0, Type m02 = 0,
00049                             Type m10 = 0, Type m11 = 0, Type m12 = 0,
00050                             Type m20 = 0, Type m21 = 0, Type m22 = 0) {
00051         set(m00, m01, m02,
00052             m10, m11, m12,
00053             m20, m21, m22);
00054         DEBUGMATRIX3(cout << "_Matrix3 constructor R9 " << endl << *this << endl);
00055     }
00056 
00057     _Matrix3<Type>(const _Matrix3<double>& m) {
00058         set(m);
00059         DEBUGMATRIX3(cout << "_Matrix3 constructor &double " << endl << *this << endl);
00060     }
00061 
00062     _Matrix3<Type>(const _Matrix3<float>& m) {
00063         set(m);
00064         DEBUGMATRIX3(cout << "_Matrix3 constructor &float " << endl << *this << endl);
00065     }
00066 
00067     _Matrix3<Type>(const Type v[9]) {
00068         set(v);
00069         DEBUGMATRIX3(cout << "_Matrix3 constructor t[9] " << endl << *this << endl);
00070     }
00071 
00072 #if 0
00073     //extension
00074     _Matrix3<Type>(const _AxisAngle4<double>& a) {
00075         set(a);
00076         DEBUGMATRIX3(cout << "_Matrix3 constructor &AxisAngle4d " << endl << *this << endl);
00077     }
00078     //extension
00079     _Matrix3<Type>(const _AxisAngle4<float>& a) {
00080         set(a);
00081         DEBUGMATRIX3(cout << "_Matrix3 constructor &AxisAngle4f " << endl << *this << endl);
00082     }
00083 #endif
00084 
00085     void add(Type d);
00086     void add(Type d, const _Matrix3<Type>& m);
00087     void add(const _Matrix3<Type>& m);
00088     void add(const _Matrix3<Type>& m, const _Matrix3<Type>& m1);
00089 
00090     static void compute_svd(double ad[], double ad1[], double ad2[], bool flag);
00091 
00092     Type determinant(void) const {
00093         return determinant3x3(m00, m01, m02, m10, m11, m12, m20, m21, m22);
00094     }
00095 
00096     bool epsilonEquals(const _Matrix3<Type>& m, Type d) const;
00097     bool equals(const _Matrix3<Type>& m) const;
00098     void getColumn(int column, _Vector3<Type>& v) const;
00099     void getColumn(int column, Type ad[]) const;
00100     Type getElement(int row, int column) const;
00101     void getRow(int row, _Vector3<Type>& v) const;
00102     void getRow(int row, Type ad[3]) const;
00103 
00104     void get(float ad[9]) const {
00105         ad[0] = m00;
00106         ad[1] = m01;
00107         ad[2] = m02;
00108         ad[3] = m10;
00109         ad[4] = m11;
00110         ad[5] = m12;
00111         ad[6] = m20;
00112         ad[7] = m21;
00113         ad[8] = m22;
00114     }
00115 
00116     void get(double ad[9]) const {
00117         ad[0] = m00;
00118         ad[1] = m01;
00119         ad[2] = m02;
00120         ad[3] = m10;
00121         ad[4] = m11;
00122         ad[5] = m12;
00123         ad[6] = m20;
00124         ad[7] = m21;
00125         ad[8] = m22;
00126     }
00127 
00128     Type getScale() const {
00129         double tmp_scale[3];
00130         double tmp_rot[9];
00131         getScaleRotate(tmp_scale, tmp_rot);
00132         return Math::max3(tmp_scale);
00133     }
00134 
00135     void getScaleRotate(double ad[3], double ad1[9]) const {
00136         double tmp[9];
00137 
00138         get(tmp);
00139         compute_svd(tmp, ad, ad1, false);
00140     }
00141 
00142     void invert() {
00143         invert(*this);
00144     }
00145 
00146     void invert(const _Matrix3<Type>& m);
00147 
00148     void mul(Type d);
00149     void mul(Type d, const _Matrix3<Type>& m);
00150 
00151     void mul(const _Matrix3<Type>& m) {
00152         mul(*this, m);
00153     }
00154 
00155     void mul(const _Matrix3<Type>& m, const _Matrix3<Type>& m1);
00156 
00157     void mulNormalize(const _Matrix3<Type>& m) {
00158         mulNormalize(*this, m);
00159     }
00160 
00161     void mulNormalize(const _Matrix3<Type>& m, const _Matrix3<Type>& m1);
00162     void mulTransposeBoth(const _Matrix3<Type> m, const _Matrix3<Type>& m1);
00163     void mulTransposeLeft(const _Matrix3<Type>& m, const _Matrix3<Type>& m1);
00164     void mulTransposeRight(const _Matrix3<Type>& m, const _Matrix3<Type>& m1);
00165 
00166     void negate() {
00167         negate(*this);
00168     }
00169 
00170     void negate(const _Matrix3<Type>& m);
00171     void normalize();
00172     void normalize(const _Matrix3<Type>& m);
00173 
00174     void normalizeCP() {
00175         normalizeCP(*this);
00176     }
00177 
00178     void normalizeCP(const _Matrix3<Type>& m);
00179     void rotX(Type angle);
00180     void rotY(Type angle);
00181     void rotZ(Type angle);
00182 
00183     void set(Type mm00, Type mm01, Type mm02,
00184              Type mm10, Type mm11, Type mm12,
00185              Type mm20, Type mm21, Type mm22) {
00186         m00 = mm00, m01 = mm01, m02 = mm02;
00187         m10 = mm10, m11 = mm11, m12 = mm12;
00188         m20 = mm20, m21 = mm21, m22 = mm22;
00189     }
00190 
00191     void set(Type d) {
00192         set(d  , 0.0, 0.0,
00193             0.0,   d, 0.0,
00194             0.0, 0.0,   d);
00195     }
00196 
00197 #if 0
00198     void set(const _AxisAngle4<double>& aa) {
00199         setAxisAngle(aa.x, aa.y, aa.z, aa.angle);
00200     }
00201 
00202     void set(const _AxisAngle4<float>& aa) {
00203         setAxisAngle(aa.x, aa.y, aa.z, aa.angle);
00204     }
00205 #endif
00206 
00207 public:
00208     void set(const _Matrix3<double>& m) {
00209         set(m.m00, m.m01, m.m02,
00210             m.m10, m.m11, m.m12,
00211             m.m20, m.m21, m.m22);
00212     }
00213 
00214     void set(const _Matrix3<float>& m) {
00215         set(m.m00, m.m01, m.m02,
00216             m.m10, m.m11, m.m12,
00217             m.m20, m.m21, m.m22);
00218     }
00219 
00220 #if 0
00221     // extension
00222     void set(const _Matrix4<double>& m) {
00223         set(m.m00, m.m01, m.m02,
00224             m.m10, m.m11, m.m12,
00225             m.m20, m.m21, m.m22);
00226     }
00227 
00228     // extension
00229     void set(const _Matrix4<float>& m) {
00230         set(m.m00, m.m01, m.m02,
00231             m.m10, m.m11, m.m12,
00232             m.m20, m.m21, m.m22);
00233     }
00234 #endif
00235 
00236     void set(const _Quat4<double>& q) {
00237         setQuat(q.x, q.y, q.z, q.w);
00238     }
00239 
00240     void set(const _Quat4<float>& q) {
00241         setQuat(q.x, q.y, q.z, q.w);
00242     }
00243 
00244     void set(const double at[9]) {
00245         set(at[0], at[1], at[2],
00246             at[3], at[4], at[5],
00247             at[6], at[7], at[8]);
00248     }
00249 
00250     void set(const float at[9]) {
00251         set(at[0], at[1], at[2],
00252             at[3], at[4], at[5],
00253             at[6], at[7], at[8]);
00254     }
00255 
00256     void setColumn(int column, Type x, Type y, Type z) {
00257         switch (column) {
00258         case 0:
00259             m00 = x;
00260             m10 = y;
00261             m20 = z;
00262             break;
00263         case 1:
00264             m01 = x;
00265             m11 = y;
00266             m21 = z;
00267             break;
00268         case 2:
00269             m02 = x;
00270             m12 = y;
00271             m22 = z;
00272             break;
00273         default:
00274             break;
00275         }
00276     }
00277 
00278     void setColumn(int column, const _Vector3<Type>& at) {
00279         switch(column) {
00280         case 0:
00281             m00 = at.x;
00282             m10 = at.y;
00283             m20 = at.z;
00284             break;
00285         case 1:
00286             m01 = at.x;
00287             m11 = at.y;
00288             m21 = at.z;
00289             break;
00290         case 2:
00291             m02 = at.x;
00292             m12 = at.y;
00293             m22 = at.z;
00294             break;
00295         default:
00296             break;
00297         }
00298     }
00299 
00300     void setColumn(int column, const Type v[3]) {
00301         switch(column) {
00302         case 0:
00303             m00 = v[0];
00304             m10 = v[1];
00305             m20 = v[2];
00306             break;
00307         case 1:
00308             m01 = v[0];
00309             m11 = v[1];
00310             m21 = v[2];
00311             break;
00312         case 2:
00313             m02 = v[0];
00314             m12 = v[1];
00315             m22 = v[2];
00316             break;
00317         default:
00318             break;
00319         }
00320     }
00321 
00322     void setElement(int row, int column, Type value) {
00323         switch(row) {
00324         case 0:
00325             switch(column) {
00326             case 0: m00 = value; break;
00327             case 1: m01 = value; break;
00328             case 2: m02 = value; break;
00329             }
00330             break;
00331         case 1:
00332             switch(column) {
00333             case 0: m10 = value; break;
00334             case 1: m11 = value; break;
00335             case 2: m12 = value; break;
00336             }
00337             break;
00338         case 2:
00339             switch(column) {
00340             case 0: m20 = value; break;
00341             case 1: m21 = value; break;
00342             case 2: m22 = value; break;
00343             }
00344             break;
00345         }
00346     }
00347 
00348     void setIdentity() {
00349         set(1.0);
00350     }
00351 
00352     void setRow(int row, Type x, Type y, Type z);
00353     void setRow(int row, const _Vector3<Type>& v);
00354     void setRow(int row, const Type v[]);
00355 
00356     void setScale(Type d) {
00357         double tmp_scale[3];
00358         double tmp_rot[9];
00359         getScaleRotate(tmp_scale, tmp_rot);
00360         set(tmp_rot[0] * d, tmp_rot[1] * d, tmp_rot[2] * d,
00361             tmp_rot[3] * d, tmp_rot[4] * d, tmp_rot[5] * d,
00362             tmp_rot[6] * d, tmp_rot[7] * d, tmp_rot[8] * d);
00363     }
00364 
00365     void setZero() {
00366         set(0.0);
00367     }
00368 
00369     void sub(const _Matrix3<Type>& m);
00370     void sub(const _Matrix3<Type>& m, const _Matrix3<Type>& m1);
00371 
00372     // extension
00373     void set(const _Vector3<Type>& v) {
00374         set(v.x, 0.0, 0.0,
00375             0.0, v.y, 0.0,
00376             0.0, 0.0, v.z);
00377     }
00378 
00379     // extension
00380     void swapRow(int row1, int row2) {
00381         if (row1 > row2)
00382             Math::swap(row1, row2);
00383         else if (row1 == row2)
00384             return;
00385 
00386         if (row1 < row2) {
00387             if (row1 == 0) {
00388                 if (row2 == 1) {
00389                     Math::swap(m00, m10);
00390                     Math::swap(m01, m11);
00391                     Math::swap(m02, m12);
00392                 } else {
00393                     Math::swap(m00, m20);
00394                     Math::swap(m01, m21);
00395                     Math::swap(m02, m22);
00396                 }
00397             } else {
00398                 Math::swap(m10, m20);
00399                 Math::swap(m11, m21);
00400                 Math::swap(m12, m22);
00401             }
00402         }
00403     }
00404 
00405     // extension
00406     void swapColumn(int col1, int col2) {
00407         if (col1 > col2)
00408             Math::swap(col1, col2);
00409         else if (col1 == col2)
00410             return;
00411 
00412         if (col1 < col2) {
00413             if (col1 == 0) {
00414                 if (col2 == 1) {
00415                     Math::swap(m00, m01);
00416                     Math::swap(m10, m11);
00417                     Math::swap(m20, m21);
00418                 } else {
00419                     Math::swap(m00, m02);
00420                     Math::swap(m10, m12);
00421                     Math::swap(m20, m22);
00422                 }
00423             } else {
00424                 Math::swap(m01, m02);
00425                 Math::swap(m11, m12);
00426                 Math::swap(m21, m22);
00427             }
00428         }
00429     }
00430 
00431 //      String& toString() {
00432 //          return m00 + ", " + m01 + ", " + m02 + "\n" + m10 + ", " + m11 + ", " + m12 + "\n" + m20 + ", " + m21 + ", " + m22 + "\n";
00433 //      }
00434 
00435     void transform(_Tuple3<Type>& t) const {
00436         transform(t, t);
00437     }
00438 
00439     void transform(const _Tuple3<Type>& t, _Tuple3<Type>& t1) const;
00440 
00441     void transpose(void) {
00442         Math::swap(m10, m01);
00443         Math::swap(m20, m02);
00444         Math::swap(m12, m21);
00445     }
00446 
00447     void transpose(const _Matrix3<Type>& m);
00448 
00449     operator const Type * () const {
00450         return &m00;
00451     }
00452 
00453     Type& operator ()(int row, int column) const {
00454         return (Type &)(*((operator const Type *()) + row * 3 + column));
00455         //return ((Type*)this)[row * 3 + column];
00456     }
00457 
00458 //    friend ostream & operator << <>(ostream &, const _Matrix3<Type>& );
00459 //    friend ostream & operator << <>(ostream &, const _Matrix3<Type>* );
00460 
00461     static Type determinant2x2(Type a, Type b, Type c, Type d) {
00462         return a * d - b * c;
00463     }
00464 
00465     static Type determinant3x3(Type a1, Type a2, Type a3,
00466                               Type b1, Type b2, Type b3,
00467                               Type c1, Type c2, Type c3) {
00468         return (a1 * determinant2x2(b2, b3, c2, c3) -
00469                 b1 * determinant2x2(a2, a3, c2, c3) +
00470                 c1 * determinant2x2(a2, a3, b2, b3));
00471     }
00472 
00473 private:
00474     void setAxisAngle(Type x, Type y, Type z, Type angle);
00475     void setQuat(Type x, Type y, Type z, Type w);
00476 };
00477 
00478 #endif

Generated on Thu Sep 29 13:39:44 2005 for vecmath by  doxygen 1.4.4