• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

Matrix.h

Go to the documentation of this file.
00001 // GMTL is (C) Copyright 2001-2010 by Allen Bierbaum
00002 // Distributed under the GNU Lesser General Public License 2.1 with an
00003 // addendum covering inlined code. (See accompanying files LICENSE and
00004 // LICENSE.addendum or http://www.gnu.org/copyleft/lesser.txt)
00005 
00006 #ifndef _GMTL_MATRIX_H_
00007 #define _GMTL_MATRIX_H_
00008 
00009 #include <gmtl/Defines.h>
00010 #include <gmtl/Math.h>
00011 #include <gmtl/Util/Assert.h>
00012 #include <gmtl/Util/StaticAssert.h>
00013 
00014 namespace gmtl
00015 {
00016 
00106 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00107 class Matrix
00108 {
00109 public:
00110    // This is a hack to work around a bug with GCC 3.3 on Mac OS X where
00111    // boost::is_polymorphic returns a false positive.  The details can be
00112    // found in the Boost.Python FAQ:
00113    //    http://www.boost.org/libs/python/doc/v2/faq.html#macosx
00114 #if defined(__MACH__) && defined(__APPLE_CC__) && defined(__GNUC__) && \
00115     __GNUC__ == 3 && __GNUC_MINOR__ == 3
00116    bool dummy_;
00117 #endif
00118 
00121    typedef DATA_TYPE DataType;
00122    enum Params
00123    {
00124       Rows = ROWS, Cols = COLS
00125    };
00126 
00131    class RowAccessor
00132    {
00133    public:
00134       typedef DATA_TYPE DataType;
00135 
00136       RowAccessor(Matrix<DATA_TYPE,ROWS,COLS>* mat, const unsigned row)
00137          : mMat(mat), mRow(row)
00138       {
00139          gmtlASSERT(row < ROWS);
00140          gmtlASSERT(NULL != mat);
00141       }
00142 
00143       DATA_TYPE& operator[](const unsigned column)
00144       {
00145          gmtlASSERT(column < COLS);
00146          return (*mMat)(mRow,column);
00147       }
00148 
00149       Matrix<DATA_TYPE,ROWS,COLS>*  mMat;
00150       unsigned                      mRow;    
00151    };
00152 
00157    class ConstRowAccessor
00158    {
00159    public:
00160       typedef DATA_TYPE DataType;
00161 
00162       ConstRowAccessor( const Matrix<DATA_TYPE,ROWS,COLS>* mat,
00163                         const unsigned row )
00164          : mMat( mat ), mRow( row )
00165       {
00166          gmtlASSERT( row < ROWS );
00167          gmtlASSERT( NULL != mat );
00168       }
00169 
00170       const DATA_TYPE& operator[](const unsigned column) const
00171       {
00172          gmtlASSERT(column < COLS);
00173          return (*mMat)(mRow,column);
00174       }
00175 
00176       const Matrix<DATA_TYPE,ROWS,COLS>*  mMat;
00177       unsigned                      mRow;    
00178    };
00179 
00181    enum XformState
00182    {
00183       // identity matrix.
00184       IDENTITY = 1,
00185 
00186       // only translation, can simply negate that column
00187       TRANS = 2,
00188 
00189       // able to tranpose to get the inverse.  only rotation component is set
00190       ORTHOGONAL = 4,
00191 
00192       // orthogonal, and normalized axes.
00193       //ORTHONORMAL = 8,
00194 
00195       // leaves the homogeneous coordinate unchanged - that is, in which the last column is (0,0,0,s).
00196       // can include rotation, uniform scale, and translation, but no shearing or nonuniform scaling
00197       // This can optionally be combined with the NON_UNISCALE state to indicate there is also non-uniform scale
00198       AFFINE = 16,
00199 
00200       // AFFINE matrix with non-uniform scale, a matrix cannot
00201       // have this state without also having AFFINE (must be or'd together).
00202       NON_UNISCALE = 32,
00203 
00204       // fully set matrix containing more information than the above, or state is unknown,
00205       // or unclassifiable in terms of the above.
00206       FULL = 64,
00207 
00208       // error bit
00209       XFORM_ERROR = 128
00210    };
00211 
00213    Matrix()
00214    {
00216       for (unsigned int r = 0; r < ROWS; ++r)
00217       {
00218          for (unsigned int c = 0; c < COLS; ++c)
00219          {   this->operator()( r, c ) = (DATA_TYPE)0.0; }
00220       }
00221 
00223       for (unsigned int x = 0; x < Math::Min( COLS, ROWS ); ++x)
00224       {  this->operator()( x, x ) = (DATA_TYPE)1.0; }
00225 
00227       mState = IDENTITY;
00228    }
00229 
00231    Matrix( const Matrix<DATA_TYPE, ROWS, COLS>& matrix )
00232    {
00233       this->set( matrix.getData() );
00234       mState = matrix.mState;
00235    }
00236 
00241    void set( DATA_TYPE v00, DATA_TYPE v01,
00242              DATA_TYPE v10, DATA_TYPE v11 )
00243    {
00244       GMTL_STATIC_ASSERT( (ROWS == 2 && COLS == 2), Set_called_when_Matrix_not_of_size_2_2 );
00245       mData[0] = v00;
00246       mData[1] = v10;
00247       mData[2] = v01;
00248       mData[3] = v11;
00249       mState = FULL;
00250    }
00251 
00255    void set( DATA_TYPE v00, DATA_TYPE v01, DATA_TYPE v02,
00256              DATA_TYPE v10, DATA_TYPE v11, DATA_TYPE v12  )
00257    {
00258       GMTL_STATIC_ASSERT( (ROWS == 2 && COLS == 3), Set_called_when_Matrix_not_of_size_2_3 );
00259       mData[0] = v00;
00260       mData[1] = v10;
00261       mData[2] = v01;
00262       mData[3] = v11;
00263       mData[4] = v02;
00264       mData[5] = v12;
00265       mState = FULL;
00266    }
00267 
00271    void set( DATA_TYPE v00, DATA_TYPE v01, DATA_TYPE v02,
00272              DATA_TYPE v10, DATA_TYPE v11, DATA_TYPE v12,
00273              DATA_TYPE v20, DATA_TYPE v21, DATA_TYPE v22)
00274    {
00275       GMTL_STATIC_ASSERT( (ROWS == 3 && COLS == 3), Set_called_when_Matrix_not_of_size_3_3 );
00276       mData[0] = v00;
00277       mData[1] = v10;
00278       mData[2] = v20;
00279 
00280       mData[3] = v01;
00281       mData[4] = v11;
00282       mData[5] = v21;
00283 
00284       mData[6] = v02;
00285       mData[7] = v12;
00286       mData[8] = v22;
00287       mState = FULL;
00288    }
00289 
00293    void set( DATA_TYPE v00, DATA_TYPE v01, DATA_TYPE v02, DATA_TYPE v03,
00294              DATA_TYPE v10, DATA_TYPE v11, DATA_TYPE v12, DATA_TYPE v13,
00295              DATA_TYPE v20, DATA_TYPE v21, DATA_TYPE v22, DATA_TYPE v23)
00296    {
00297       GMTL_STATIC_ASSERT( (ROWS == 3 && COLS == 4), Set_called_when_Matrix_not_of_size_3_4 );
00298       mData[0] = v00;
00299       mData[1] = v10;
00300       mData[2] = v20;
00301       mData[3] = v01;
00302       mData[4] = v11;
00303       mData[5] = v21;
00304       mData[6] = v02;
00305       mData[7] = v12;
00306       mData[8] = v22;
00307 
00308       // right row
00309       mData[9]  = v03;
00310       mData[10] = v13;
00311       mData[11] = v23;
00312       mState = FULL;
00313    }
00314 
00318    void set( DATA_TYPE v00, DATA_TYPE v01, DATA_TYPE v02, DATA_TYPE v03,
00319              DATA_TYPE v10, DATA_TYPE v11, DATA_TYPE v12, DATA_TYPE v13,
00320              DATA_TYPE v20, DATA_TYPE v21, DATA_TYPE v22, DATA_TYPE v23,
00321              DATA_TYPE v30, DATA_TYPE v31, DATA_TYPE v32, DATA_TYPE v33 )
00322    {
00323       GMTL_STATIC_ASSERT( (ROWS == 4 && COLS == 4), Set_called_when_Matrix_not_of_size_4_4 );
00324       mData[0]  = v00;
00325       mData[1]  = v10;
00326       mData[2]  = v20;
00327       mData[4]  = v01;
00328       mData[5]  = v11;
00329       mData[6]  = v21;
00330       mData[8]  = v02;
00331       mData[9]  = v12;
00332       mData[10] = v22;
00333 
00334       // right row
00335       mData[12] = v03;
00336       mData[13] = v13;
00337       mData[14] = v23;
00338 
00339       // bottom row
00340       mData[3]  = v30;
00341       mData[7]  = v31;
00342       mData[11] = v32;
00343       mData[15] = v33;
00344       mState = FULL;
00345    }
00346 
00350    //void operator,()( DATA_TYPE b ) {}
00351 
00370    void set( const DATA_TYPE* data )
00371    {
00373       for (unsigned int x = 0; x < ROWS * COLS; ++x)
00374          mData[x] = data[x];
00375       mState = FULL;
00376    }
00377 
00400    void setTranspose( const DATA_TYPE* data )
00401    {
00403       for (unsigned int r = 0; r < ROWS; ++r)
00404       for (unsigned int c = 0; c < COLS; ++c)
00405          this->operator()( r, c ) = data[(r * COLS) + c];
00406       mState = FULL;
00407    }
00408 
00417    DATA_TYPE& operator()( const unsigned row, const unsigned column )
00418    {
00419       gmtlASSERT( (row < ROWS) && (column < COLS) );
00420       return mData[column*ROWS + row];
00421    }
00422 
00424    const DATA_TYPE&  operator()( const unsigned row, const unsigned column ) const
00425    {
00426       gmtlASSERT( (row < ROWS) && (column < COLS) );
00427       return mData[column*ROWS + row];
00428    }
00429 
00438    RowAccessor operator[]( const unsigned row )
00439    {
00440       return RowAccessor(this, row);
00441    }
00442 
00444    ConstRowAccessor operator[]( const unsigned row ) const
00445    {
00446       return ConstRowAccessor( this, row );
00447    }
00448 
00449    /*
00450    // bracket operator
00451    const DATA_TYPE& operator[]( const unsigned i ) const
00452    {
00453       gmtlASSERT( i < (ROWS*COLS) );
00454       return mData[i];
00455    }
00456    */
00457 
00461    const DATA_TYPE*  getData() const { return (DATA_TYPE*)mData; }
00462 
00463    bool isError()
00464    {
00465       return mState & XFORM_ERROR;
00466    }
00467    void setError()
00468    {
00469       mState |= XFORM_ERROR;
00470    }
00471 
00472    void setState(int state)
00473    { mState = state; }
00474 
00475 public:
00485    DATA_TYPE mData[COLS*ROWS];
00486 
00488    int mState;
00489 };
00490 
00491 typedef Matrix<float, 2, 2> Matrix22f;
00492 typedef Matrix<double, 2, 2> Matrix22d;
00493 typedef Matrix<float, 2, 3> Matrix23f;
00494 typedef Matrix<double, 2, 3> Matrix23d;
00495 typedef Matrix<float, 3, 3> Matrix33f;
00496 typedef Matrix<double, 3, 3> Matrix33d;
00497 typedef Matrix<float, 3, 4> Matrix34f;
00498 typedef Matrix<double, 3, 4> Matrix34d;
00499 typedef Matrix<float, 4, 4> Matrix44f;
00500 typedef Matrix<double, 4, 4> Matrix44d;
00501 
00503 const Matrix22f MAT_IDENTITY22F = Matrix22f();
00504 
00506 const Matrix22d MAT_IDENTITY22D = Matrix22d();
00507 
00509 const Matrix23f MAT_IDENTITY23F = Matrix23f();
00510 
00512 const Matrix23d MAT_IDENTITY23D = Matrix23d();
00513 
00515 const Matrix33f MAT_IDENTITY33F = Matrix33f();
00516 
00518 const Matrix33d MAT_IDENTITY33D = Matrix33d();
00519 
00521 const Matrix34f MAT_IDENTITY34F = Matrix34f();
00522 
00524 const Matrix34d MAT_IDENTITY34D = Matrix34d();
00525 
00527 const Matrix44f MAT_IDENTITY44F = Matrix44f();
00528 
00530 const Matrix44d MAT_IDENTITY44D = Matrix44d();
00531 
00536 inline int combineMatrixStates( int state1, int state2 )
00537 {
00538    switch (state1)
00539    {
00540    case Matrix44f::IDENTITY:
00541       switch (state2)
00542       {
00543       case Matrix44f::XFORM_ERROR: return state2;
00544       case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
00545       default: return state2;
00546       }
00547    case Matrix44f::TRANS:
00548       switch (state2)
00549       {
00550       case Matrix44f::IDENTITY: return state1;
00551       case Matrix44f::ORTHOGONAL: return Matrix44f::AFFINE;
00552       case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
00553       default: return state2;
00554       }
00555    case Matrix44f::ORTHOGONAL:
00556       switch (state2)
00557       {
00558       case Matrix44f::IDENTITY: return state1;
00559       case Matrix44f::TRANS: return Matrix44f::AFFINE;
00560       case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
00561       default: return state2;
00562       }
00563    case Matrix44f::AFFINE:
00564       switch (state2)
00565       {
00566       case Matrix44f::IDENTITY:
00567       case Matrix44f::TRANS:
00568       case Matrix44f::ORTHOGONAL:  return state1;
00569       case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
00570       case Matrix44f::AFFINE | Matrix44f::NON_UNISCALE:
00571       default: return state2;
00572       }
00573    case Matrix44f::AFFINE | Matrix44f::NON_UNISCALE:
00574       switch (state2)
00575       {
00576       case Matrix44f::IDENTITY:
00577       case Matrix44f::TRANS:
00578       case Matrix44f::ORTHOGONAL:
00579       case Matrix44f::AFFINE:  return state1;
00580       case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
00581       default: return state2;
00582       }
00583    case Matrix44f::FULL:
00584       switch (state2)
00585       {
00586       case Matrix44f::XFORM_ERROR: return state2;
00587       case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
00588       default: return state1;
00589       }
00590       break;
00591    default:
00592       return Matrix44f::XFORM_ERROR;
00593    }
00594 }
00595 
00596 } // end namespace gmtl
00597 
00598 
00599 
00600 #endif

Generated on Sun Sep 19 2010 14:35:14 for GenericMathTemplateLibrary by  doxygen 1.7.1