glc_matrix4x4.h

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  http://glc-lib.sourceforge.net
00006 
00007  GLC-lib is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU Lesser General Public License as published by
00009  the Free Software Foundation; either version 3 of the License, or
00010  (at your option) any later version.
00011 
00012  GLC-lib is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU Lesser General Public License for more details.
00016 
00017  You should have received a copy of the GNU Lesser General Public License
00018  along with GLC-lib; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 *****************************************************************************/
00022 
00024 
00025 #ifndef GLC_MATRIX4X4_H_
00026 #define GLC_MATRIX4X4_H_
00027 
00028 #include <QVector>
00029 #include "glc_vector3d.h"
00030 
00031 #include "../glc_config.h"
00032 
00035 
00040 
00041 class GLC_LIB_EXPORT GLC_Matrix4x4
00042 {
00043         friend class GLC_Vector3d;
00044 public:
00046         enum
00047         {
00048                 General= 0x0000,
00049                 Direct= 0x0001,
00050                 Indirect= 0x0002,
00051                 Identity= 0x0003
00052         };
00053 
00055 // Constructor
00057 public:
00059 
00060 
00061         inline GLC_Matrix4x4();
00062 
00064         inline GLC_Matrix4x4(const GLC_Matrix4x4 &matrix)
00065         :m_Type(matrix.m_Type)
00066         {
00067                 memcpy(m_Matrix, matrix.m_Matrix, sizeof(double) * 16);
00068         }
00069 
00071         inline GLC_Matrix4x4(const double *pArray)
00072         : m_Type(General)
00073         {
00074                 memcpy(m_Matrix, pArray, sizeof(double) * 16);
00075         }
00076 
00078         inline GLC_Matrix4x4(const float *);
00079 
00081         inline GLC_Matrix4x4(const GLC_Vector3d &Vect, const double &dAngleRad);
00082 
00084         inline GLC_Matrix4x4(const GLC_Vector3d &Vect1, const GLC_Vector3d &Vect2);
00085 
00087         inline GLC_Matrix4x4(const GLC_Vector3d &Vect)
00088         {setMatTranslate(Vect);}
00089 
00091         inline GLC_Matrix4x4(const double Tx, const double Ty, const double Tz)
00092         {setMatTranslate(Tx, Ty, Tz);}
00094 
00096 
00098 
00099 public:
00101         inline GLC_Matrix4x4& operator = (const GLC_Matrix4x4 &matrix);
00102 
00104         inline GLC_Matrix4x4 operator * (const GLC_Matrix4x4 &Mat) const;
00105 
00107         inline GLC_Vector3d operator * (const GLC_Vector3d &Vect) const;
00108 
00110         inline bool operator==(const GLC_Matrix4x4& mat) const;
00111 
00113         inline bool operator!=(const GLC_Matrix4x4& mat) const
00114         {return !operator==(mat);}
00115 
00117 
00119 
00121 
00122 public:
00124         inline double determinant(void) const;
00125 
00127 
00128         inline const double* getData(void)
00129         {return m_Matrix;}
00130 
00132         inline const double* getData(void) const
00133         {return m_Matrix;}
00134 
00136         inline double* setData(void)
00137         {
00138                 m_Type= General;
00139                 return m_Matrix;
00140         }
00141 
00143         QVector<double> toEuler(void) const;
00144 
00146         QString toString() const;
00147 
00149         inline GLC_Matrix4x4 rotationMatrix() const;
00150 
00152         inline GLC_Matrix4x4 isometricMatrix() const;
00153 
00155         inline double scalingX() const
00156         {return GLC_Vector3d(m_Matrix[0], m_Matrix[1], m_Matrix[2]).length();}
00157 
00159         inline double scalingY() const
00160         {return GLC_Vector3d(m_Matrix[4], m_Matrix[5], m_Matrix[6]).length();}
00161 
00163         inline double scalingZ() const
00164         {return GLC_Vector3d(m_Matrix[8], m_Matrix[9], m_Matrix[10]).length();}
00165 
00167         inline GLC_Matrix4x4 inverted() const
00168         {return GLC_Matrix4x4(*this).invert();}
00169 
00171         inline int type() const
00172         {
00173                 return m_Type;
00174         }
00175 
00177         inline bool isDirect() const
00178         {return (m_Type & Direct);}
00179 
00181 
00183 
00185 
00186 public:
00188         inline GLC_Matrix4x4& setMatRot(const GLC_Vector3d &, const double &);
00189 
00191         inline GLC_Matrix4x4& setMatRot(const GLC_Vector3d &, const GLC_Vector3d &);
00192 
00194         inline GLC_Matrix4x4& setMatTranslate(const GLC_Vector3d &);
00195 
00197         inline GLC_Matrix4x4& setMatTranslate(const double, const double, const double);
00198 
00200         inline GLC_Matrix4x4& setMatScaling(const double, const double, const double);
00201 
00203         inline GLC_Matrix4x4& invert(void);
00204 
00206         inline GLC_Matrix4x4& setToIdentity();
00207 
00209         inline GLC_Matrix4x4& transpose(void);
00210 
00212         GLC_Matrix4x4& fromEuler(const double, const double, const double);
00213 
00215         GLC_Matrix4x4& setColumn(int index, const GLC_Vector3d& vector);
00216 
00218         inline GLC_Matrix4x4& optimise(bool force= false);
00219 
00221 
00225 private:
00226 
00228         inline bool isInDiagonal(const int index) const
00229         {
00230                 if ((index == 0) || (index == 5) || (index == 10) || (index == 15))
00231                         return true;
00232                 else
00233                         return false;
00234         }
00235 
00237         inline double getDeterminantLC(const int, const int) const;
00238 
00240         inline void getSubMat(const int, const int, double *) const;
00241 
00243         inline GLC_Matrix4x4 getTranspose(void) const;
00244 
00246         inline GLC_Matrix4x4 getCoMat4x4(void) const;
00247 
00248 
00249 
00251 // Private members
00253 private:
00254 
00256         enum {TAILLEMAT4X4 = 16};
00257 
00259         enum {DIMMAT4X4 = 4};
00260 
00262         double m_Matrix[TAILLEMAT4X4];
00263 
00265         int m_Type;
00266 
00267 /*
00268 the matrix :
00269                                         a[00] a[04] a[08] a[12]
00270 
00271                                         a[01] a[05] a[09] a[13]
00272 
00273                                         a[02] a[06] a[10] a[14]
00274 
00275                                         a[03] a[07] a[11] a[15]
00276  */
00277 //                                      Tx = 12,        Ty = 13,        Tz = 14
00278 
00279 };
00280 
00282 inline double getDeterminant3x3(const double *Mat3x3)
00283 {
00284         double Determinant;
00285 
00286         Determinant= Mat3x3[0] * ( Mat3x3[4] * Mat3x3[8] - Mat3x3[7] * Mat3x3[5]);
00287         Determinant+= - Mat3x3[3] * ( Mat3x3[1] * Mat3x3[8] - Mat3x3[7] * Mat3x3[2]);
00288         Determinant+= Mat3x3[6] * ( Mat3x3[1] * Mat3x3[5] - Mat3x3[4] * Mat3x3[2]);
00289 
00290         return Determinant;
00291 }
00292 
00294 // Constructor/Destructor
00296 
00297 GLC_Matrix4x4::GLC_Matrix4x4()
00298 : m_Type(Identity)
00299 {
00300         setToIdentity();
00301 }
00302 
00303 GLC_Matrix4x4::GLC_Matrix4x4(const float *Tableau)
00304 : m_Type(General)
00305 {
00306 
00307         for (int i=0; i < TAILLEMAT4X4; i++)
00308         {
00309                 m_Matrix[i]= static_cast<double>(Tableau[i]);
00310         }
00311 }
00312 GLC_Matrix4x4::GLC_Matrix4x4(const GLC_Vector3d &Vect, const double &dAngleRad)
00313 : m_Type(Direct)
00314 {
00315         setToIdentity();
00316         setMatRot(Vect, dAngleRad);
00317 }
00318 
00319 GLC_Matrix4x4::GLC_Matrix4x4(const GLC_Vector3d &Vect1, const GLC_Vector3d &Vect2)
00320 : m_Type(Direct)
00321 {
00322         setToIdentity();
00323         setMatRot(Vect1, Vect2);
00324 }
00325 
00326 GLC_Matrix4x4 GLC_Matrix4x4::operator * (const GLC_Matrix4x4 &Mat) const
00327 {
00328         if (m_Type == Identity)
00329         {
00330                 return Mat;
00331         }
00332         else if (Mat.m_Type == Identity)
00333         {
00334                 return *this;
00335         }
00336 
00337         int Colonne;
00338         int Ligne;
00339         int i;
00340         double ValInt;
00341 
00342         int IndexInt;
00343 
00344         GLC_Matrix4x4 MatResult;
00345         for (Ligne= 0; Ligne < DIMMAT4X4; Ligne++)
00346         {
00347                 for (Colonne=0; Colonne < DIMMAT4X4; Colonne++)
00348                 {
00349                         ValInt= 0.0;
00350                         IndexInt= Colonne * DIMMAT4X4;
00351 
00352                         for (i= 0; i < DIMMAT4X4; i++)
00353                         {
00354                                 ValInt+= m_Matrix[ (i * DIMMAT4X4) + Ligne] * Mat.m_Matrix[ IndexInt + i];
00355                         }
00356                         MatResult.m_Matrix[ IndexInt + Ligne]= ValInt;
00357                 }
00358         }
00359         if ((m_Type == Indirect) || (Mat.m_Type == Indirect))
00360         {
00361                 MatResult.m_Type= Indirect;
00362         }
00363         else
00364         {
00365                 MatResult.m_Type= m_Type & Mat.m_Type;
00366         }
00367 
00368         return MatResult;
00369 }
00370 
00371 GLC_Matrix4x4& GLC_Matrix4x4::operator = (const GLC_Matrix4x4 &matrix)
00372 {
00373         m_Type= matrix.m_Type;
00374         memcpy(m_Matrix, matrix.m_Matrix, sizeof(double) * 16);
00375 
00376         return *this;
00377 }
00378 
00379 GLC_Vector3d GLC_Matrix4x4::operator * (const GLC_Vector3d &Vect) const
00380 {
00381         double ValInt;
00382         int i;
00383         GLC_Vector3d VectResult;
00384         double mat[4];
00385 
00386         for (int Index= 0; Index < DIMMAT4X4; Index++)
00387         {
00388                 ValInt= 0.0;
00389                 for (i= 0; i < DIMMAT4X4 - 1; i++)
00390                 {
00391                         ValInt+= m_Matrix[(i * DIMMAT4X4) + Index] * Vect.m_Vector[i];
00392                 }
00393                 ValInt+= m_Matrix[(3 * DIMMAT4X4) + Index];
00394                 mat[Index]= ValInt;
00395         }
00396 
00397         double invW= 1.0;
00398         if (fabs(mat[3]) > 0.00001)
00399         {
00400                 invW/= mat[3];
00401         }
00402         VectResult.m_Vector[0]= mat[0] * invW;
00403         VectResult.m_Vector[1]= mat[1] * invW;
00404         VectResult.m_Vector[2]= mat[2] * invW;
00405 
00406 
00407         return VectResult;
00408 }
00409 
00410 bool GLC_Matrix4x4::operator==(const GLC_Matrix4x4& mat) const
00411 {
00412         bool result= true;
00413         int i= 0;
00414         while (result && (i < TAILLEMAT4X4))
00415         {
00416                 result= (qFuzzyCompare(m_Matrix[i], mat.m_Matrix[i]));
00417                 ++i;
00418         }
00419         return result;
00420 }
00421 
00422 GLC_Matrix4x4 GLC_Matrix4x4::rotationMatrix() const
00423 {
00424         GLC_Matrix4x4 result(*this);
00425         const double invScaleX= 1.0 / scalingX();
00426         const double invScaleY= 1.0 / scalingY();
00427         const double invScaleZ= 1.0 / scalingZ();
00428         result.m_Matrix[0]= result.m_Matrix[0] * invScaleX;
00429         result.m_Matrix[1]= result.m_Matrix[1] * invScaleX;
00430         result.m_Matrix[2]= result.m_Matrix[2] * invScaleX;
00431 
00432         result.m_Matrix[4]= result.m_Matrix[4] * invScaleY;
00433         result.m_Matrix[5]= result.m_Matrix[5] * invScaleY;
00434         result.m_Matrix[6]= result.m_Matrix[6] * invScaleY;
00435 
00436         result.m_Matrix[8]= result.m_Matrix[8] * invScaleZ;
00437         result.m_Matrix[9]= result.m_Matrix[9] * invScaleZ;
00438         result.m_Matrix[10]= result.m_Matrix[10] * invScaleZ;
00439 
00440         result.m_Matrix[12]= 0.0; result.m_Matrix[13]= 0.0; result.m_Matrix[14]= 0.0;
00441         result.m_Matrix[3]= 0.0; result.m_Matrix[7]= 0.0; result.m_Matrix[11]= 0.0;
00442         result.m_Matrix[15]= 1.0;
00443 
00444         result.m_Type= General;
00445 
00446         return result;
00447 }
00448 
00449 GLC_Matrix4x4 GLC_Matrix4x4::isometricMatrix() const
00450 {
00451         GLC_Matrix4x4 result(*this);
00452         const double invScaleX= 1.0 / scalingX();
00453         const double invScaleY= 1.0 / scalingY();
00454         const double invScaleZ= 1.0 / scalingZ();
00455         result.m_Matrix[0]= result.m_Matrix[0] * invScaleX;
00456         result.m_Matrix[1]= result.m_Matrix[1] * invScaleX;
00457         result.m_Matrix[2]= result.m_Matrix[2] * invScaleX;
00458 
00459         result.m_Matrix[4]= result.m_Matrix[4] * invScaleY;
00460         result.m_Matrix[5]= result.m_Matrix[5] * invScaleY;
00461         result.m_Matrix[6]= result.m_Matrix[6] * invScaleY;
00462 
00463         result.m_Matrix[8]= result.m_Matrix[8] * invScaleZ;
00464         result.m_Matrix[9]= result.m_Matrix[9] * invScaleZ;
00465         result.m_Matrix[10]= result.m_Matrix[10] * invScaleZ;
00466 
00467         result.m_Type= General;
00468 
00469         return result;
00470 }
00471 
00472 GLC_Matrix4x4& GLC_Matrix4x4::setMatRot(const GLC_Vector3d &Vect, const double &dAngleRad)
00473 {
00474         // Normalize the vector
00475         GLC_Vector3d VectRot(Vect);
00476         VectRot.normalize();
00477 
00478         // Code optimisation
00479         const double SinAngleSur2= sin(dAngleRad / 2.0);
00480 
00481         // Quaternion computation
00482         const double q0= cos(dAngleRad / 2);
00483         const double q1= VectRot.m_Vector[0] * SinAngleSur2;
00484         const double q2= VectRot.m_Vector[1] * SinAngleSur2;
00485         const double q3= VectRot.m_Vector[2] * SinAngleSur2;
00486 
00487         // Code optimisation
00488         const double q0Carre= (q0 * q0);
00489         const double q1Carre= (q1 * q1);
00490         const double q2Carre= (q2 * q2);
00491         const double q3Carre= (q3 * q3);
00492 
00493         m_Matrix[0]= q0Carre + q1Carre - q2Carre - q3Carre;
00494         m_Matrix[1]= 2.0 * (q1 *q2 + q0 * q3);
00495         m_Matrix[2]= 2.0 * (q1 * q3 - q0 * q2);
00496         m_Matrix[3]= 0.0;
00497         m_Matrix[4]= 2.0 * (q1 * q2 - q0 * q3);
00498         m_Matrix[5]= q0Carre + q2Carre - q3Carre - q1Carre;
00499         m_Matrix[6]= 2.0 * (q2 * q3 + q0 * q1);
00500         m_Matrix[7]= 0.0;
00501         m_Matrix[8]= 2.0 * (q1 * q3 + q0 * q2);
00502         m_Matrix[9]= 2.0 * (q2 * q3 - q0 * q1);
00503         m_Matrix[10]= q0Carre + q3Carre - q1Carre - q2Carre;
00504         m_Matrix[11]= 0.0;
00505 
00506         m_Matrix[12]= 0.0;      //TX
00507         m_Matrix[13]= 0.0;      //TY
00508         m_Matrix[14]= 0.0;      //TZ
00509         m_Matrix[15]= 1.0;
00510 
00511         m_Type= Direct;
00512 
00513         return *this;
00514 }
00515 
00516 GLC_Matrix4x4& GLC_Matrix4x4::setMatRot(const GLC_Vector3d &Vect1, const GLC_Vector3d &Vect2)
00517 {
00518 
00519         // Compute rotation matrix
00520         const GLC_Vector3d VectAxeRot(Vect1 ^ Vect2);
00521         // Check if rotation vector axis is not null
00522         if (!VectAxeRot.isNull())
00523         {  // Ok, vector not null
00524                 const double Angle= acos(Vect1 * Vect2);
00525                 setMatRot(VectAxeRot, Angle);
00526         }
00527 
00528         return *this;
00529 }
00530 
00531 GLC_Matrix4x4& GLC_Matrix4x4::setMatTranslate(const GLC_Vector3d &Vect)
00532 {
00533         m_Matrix[0]= 1.0; m_Matrix[4]= 0.0; m_Matrix[8]=  0.0; m_Matrix[12]= Vect.m_Vector[0];
00534         m_Matrix[1]= 0.0; m_Matrix[5]= 1.0; m_Matrix[9]=  0.0; m_Matrix[13]= Vect.m_Vector[1];
00535         m_Matrix[2]= 0.0; m_Matrix[6]= 0.0; m_Matrix[10]= 1.0; m_Matrix[14]= Vect.m_Vector[2];
00536         m_Matrix[3]= 0.0; m_Matrix[7]= 0.0; m_Matrix[11]= 0.0; m_Matrix[15]= 1.0;
00537 
00538         m_Type= Direct;
00539 
00540         return *this;
00541 }
00542 
00543 GLC_Matrix4x4& GLC_Matrix4x4::setMatTranslate(const double Tx, const double Ty, const double Tz)
00544 {
00545         m_Matrix[0]= 1.0; m_Matrix[4]= 0.0; m_Matrix[8]=  0.0; m_Matrix[12]= Tx;
00546         m_Matrix[1]= 0.0; m_Matrix[5]= 1.0; m_Matrix[9]=  0.0; m_Matrix[13]= Ty;
00547         m_Matrix[2]= 0.0; m_Matrix[6]= 0.0; m_Matrix[10]= 1.0; m_Matrix[14]= Tz;
00548         m_Matrix[3]= 0.0; m_Matrix[7]= 0.0; m_Matrix[11]= 0.0; m_Matrix[15]= 1.0;
00549 
00550         m_Type= Direct;
00551 
00552         return *this;
00553 }
00554 
00555 GLC_Matrix4x4& GLC_Matrix4x4::setMatScaling(const double sX, const double sY, const double sZ)
00556 {
00557         m_Matrix[0]= sX; m_Matrix[4]= 0.0; m_Matrix[8]=  0.0; m_Matrix[12]= 0.0;
00558         m_Matrix[1]= 0.0; m_Matrix[5]= sY; m_Matrix[9]=  0.0; m_Matrix[13]= 0.0;
00559         m_Matrix[2]= 0.0; m_Matrix[6]= 0.0; m_Matrix[10]= sZ; m_Matrix[14]= 0.0;
00560         m_Matrix[3]= 0.0; m_Matrix[7]= 0.0; m_Matrix[11]= 0.0; m_Matrix[15]= 1.0;
00561 
00562         m_Type= General;
00563 
00564         return *this;
00565 }
00566 
00567 
00568 GLC_Matrix4x4& GLC_Matrix4x4::invert(void)
00569 {
00570         const double det= determinant();
00571 
00572         // Test if the inverion is possible
00573         if (det == 0.0f) return *this;
00574 
00575         const double invDet = 1.0 / det;
00576         GLC_Matrix4x4 TCoMat= getCoMat4x4().getTranspose();
00577 
00578         for (int i= 0; i < TAILLEMAT4X4; i++)
00579         {
00580                 m_Matrix[i]= TCoMat.m_Matrix[i] * invDet;
00581         }
00582 
00583         return *this;
00584 }
00585 
00586 GLC_Matrix4x4& GLC_Matrix4x4::setToIdentity()
00587 {
00588         m_Matrix[0]= 1.0; m_Matrix[4]= 0.0; m_Matrix[8]=  0.0; m_Matrix[12]= 0.0;
00589         m_Matrix[1]= 0.0; m_Matrix[5]= 1.0; m_Matrix[9]=  0.0; m_Matrix[13]= 0.0;
00590         m_Matrix[2]= 0.0; m_Matrix[6]= 0.0; m_Matrix[10]= 1.0; m_Matrix[14]= 0.0;
00591         m_Matrix[3]= 0.0; m_Matrix[7]= 0.0; m_Matrix[11]= 0.0; m_Matrix[15]= 1.0;
00592 
00593         m_Type= Identity;
00594 
00595         return *this;
00596 }
00597 
00598 GLC_Matrix4x4& GLC_Matrix4x4::transpose(void)
00599 {
00600         GLC_Matrix4x4 MatT(m_Matrix);
00601         int IndexOrigine;
00602         int IndexTrans;
00603         for (int Colonne= 0; Colonne < DIMMAT4X4; Colonne++)
00604         {
00605                 for (int Ligne=0 ; Ligne < DIMMAT4X4; Ligne++)
00606                 {
00607                         IndexOrigine= (Colonne * DIMMAT4X4) + Ligne;
00608                         IndexTrans= (Ligne * DIMMAT4X4) + Colonne;
00609 
00610                         MatT.m_Matrix[IndexTrans]= m_Matrix[IndexOrigine];
00611                 }
00612         }
00613 
00614         // Load the transposed matrix in this matrix
00615         memcpy(m_Matrix, MatT.m_Matrix, sizeof(double) * 16);
00616 
00617         return *this;
00618 }
00619 
00620 GLC_Matrix4x4& GLC_Matrix4x4::optimise(bool force)
00621 {
00622         if (force || (m_Type == General))
00623         {
00624                 bool identityVal= (m_Matrix[0] == 1.0f) && (m_Matrix[4] == 0.0f) && (m_Matrix[8] ==  0.0f) && (m_Matrix[12] == 0.0f);
00625                 identityVal= identityVal && (m_Matrix[1] == 0.0f) && (m_Matrix[5] == 1.0f) && (m_Matrix[9] ==  0.0f) && (m_Matrix[13] == 0.0);
00626                 identityVal= identityVal && (m_Matrix[2] == 0.0f) && (m_Matrix[6] == 0.0f) && (m_Matrix[10] == 1.0f) && (m_Matrix[14] == 0.0);
00627                 identityVal= identityVal && (m_Matrix[3] == 0.0f) && (m_Matrix[7] == 0.0f) && (m_Matrix[11] == 0.0f) && (m_Matrix[15] == 1.0f);
00628                 if (identityVal)
00629                 {
00630                         m_Type= Identity;
00631                 }
00632                 else
00633                 {
00634                         if (determinant() > 0)
00635                         {
00636                                 m_Type= Direct;
00637                         }
00638                         else
00639                         {
00640                                 m_Type= Indirect;
00641                         }
00642                 }
00643         }
00644         return *this;
00645 }
00646 
00647 double GLC_Matrix4x4::determinant(void) const
00648 {
00649         double Determinant= 0.0;
00650         double SubMat3x3[9];
00651         int Signe= 1;
00652 
00653         for (int Colonne= 0; Colonne < DIMMAT4X4; Colonne++, Signe*= -1)
00654         {
00655                 getSubMat(0, Colonne, SubMat3x3);
00656                 Determinant+= Signe * m_Matrix[Colonne * DIMMAT4X4] * getDeterminant3x3(SubMat3x3);
00657         }
00658 
00659         return Determinant;
00660 
00661 }
00662 
00663 double GLC_Matrix4x4::getDeterminantLC(const int Ligne, const int Colonne) const
00664 {
00665         double Mat3x3[9];
00666         double Determinant;
00667 
00668         getSubMat(Ligne, Colonne, Mat3x3);
00669 
00670         if ( 0 == ((Ligne + Colonne) % 2)) // Even number
00671                 Determinant= m_Matrix[(Colonne + DIMMAT4X4) + Ligne] * getDeterminant3x3(Mat3x3);
00672         else
00673                 Determinant= - m_Matrix[(Colonne + DIMMAT4X4) + Ligne] * getDeterminant3x3(Mat3x3);
00674 
00675         return Determinant;
00676 }
00677 
00678 void GLC_Matrix4x4::getSubMat(const int Ligne, const int Colonne, double *ResultMat) const
00679 {
00680 
00681         int LigneResult;
00682         int ColonneResult;
00683         int IndexOrigine;
00684         int IndexResult;
00685 
00686         for (int ColonneOrigine= 0; ColonneOrigine < DIMMAT4X4; ColonneOrigine++)
00687         {
00688                 if (ColonneOrigine != Colonne)
00689                 {
00690                         if (ColonneOrigine < Colonne)
00691                                 ColonneResult= ColonneOrigine;
00692                         else
00693                                 ColonneResult= ColonneOrigine - 1;
00694 
00695                         for (int LigneOrigine= 0; LigneOrigine < DIMMAT4X4; LigneOrigine++)
00696                         {
00697                                 if (LigneOrigine != Ligne)
00698                                 {
00699                                         if (LigneOrigine < Ligne)
00700                                                 LigneResult= LigneOrigine;
00701                                         else
00702                                                 LigneResult= LigneOrigine - 1;
00703                                         IndexOrigine= (ColonneOrigine * DIMMAT4X4) + LigneOrigine;
00704                                         IndexResult= (ColonneResult * (DIMMAT4X4 - 1)) + LigneResult;
00705 
00706                                         ResultMat[IndexResult]= m_Matrix[IndexOrigine];
00707                                 }
00708                         }
00709                 }
00710         }
00711 }
00712 
00713 GLC_Matrix4x4 GLC_Matrix4x4::getTranspose(void) const
00714 {
00715         GLC_Matrix4x4 MatT(m_Matrix);
00716         int IndexOrigine;
00717         int IndexTrans;
00718         for (int Colonne= 0; Colonne < DIMMAT4X4; Colonne++)
00719         {
00720                 for (int Ligne=0 ; Ligne < DIMMAT4X4; Ligne++)
00721                 {
00722                         IndexOrigine= (Colonne * DIMMAT4X4) + Ligne;
00723                         IndexTrans= (Ligne * DIMMAT4X4) + Colonne;
00724 
00725                         MatT.m_Matrix[IndexTrans]= m_Matrix[IndexOrigine];
00726                 }
00727         }
00728 
00729         MatT.m_Type= m_Type;
00730         return MatT;
00731 }
00732 
00733 GLC_Matrix4x4 GLC_Matrix4x4::getCoMat4x4(void) const
00734 {
00735         GLC_Matrix4x4 CoMat(m_Matrix);
00736         double SubMat3x3[9];
00737         int Index;
00738 
00739         for (int Colonne= 0; Colonne < DIMMAT4X4; Colonne++)
00740         {
00741                 for (int Ligne=0 ; Ligne < DIMMAT4X4; Ligne++)
00742                 {
00743                         getSubMat(Ligne, Colonne, SubMat3x3);
00744                         Index= (Colonne * DIMMAT4X4) + Ligne;
00745                         if (((Colonne + Ligne + 2) % 2) == 0) // Even Number
00746                                 CoMat.m_Matrix[Index]= getDeterminant3x3(SubMat3x3);
00747                         else
00748                                 CoMat.m_Matrix[Index]= -getDeterminant3x3(SubMat3x3);
00749                 }
00750         }
00751 
00752 
00753         CoMat.m_Type= General;
00754         return CoMat;
00755 }
00756 
00757 
00758 #endif /*GLC_MATRIX4X4_H_*/

SourceForge.net Logo

©2005-2011 Laurent Ribon