math/Matrix4x4.cpp

Go to the documentation of this file.
00001 //## begin module%36FE7C2C01F4.cm preserve=no
00002 //        %X% %Q% %Z% %W%
00003 //## end module%36FE7C2C01F4.cm
00004 
00005 //## begin module%36FE7C2C01F4.cp preserve=no
00006 //## end module%36FE7C2C01F4.cp
00007 
00008 //## Module: Matrix4x4%36FE7C2C01F4; Pseudo Package body
00009 //## Source file: C:\user\gipson\projects\mpk\code\geometry\Matrix4x4.cpp
00010 
00011 //## begin module%36FE7C2C01F4.additionalIncludes preserve=no
00012 //## end module%36FE7C2C01F4.additionalIncludes
00013 
00014 //## begin module%36FE7C2C01F4.includes preserve=yes
00015 #include "../additional/streams/mystreams.h"
00016 #include <assert.h>
00017 #include "math2.h"
00018 //## end module%36FE7C2C01F4.includes
00019 
00020 // Vector4
00021 #include "Vector4.h"
00022 // Matrix4x4
00023 #include "Matrix4x4.h"
00024 #include "Matrixmxn.h"
00025 //## begin module%36FE7C2C01F4.additionalDeclarations preserve=yes
00026 //## end module%36FE7C2C01F4.additionalDeclarations
00027 
00028 
00029 // Class Matrix4x4 
00030 
00031 
00032 //---------- Constants ----------------
00033 static const double DEFAULT_TOL = 0.1;
00034 
00035 
00036 
00037 
00038 Matrix4x4::Matrix4x4 ()
00039   //## begin Matrix4x4::Matrix4x4%925324837.hasinit preserve=no
00040   //## end Matrix4x4::Matrix4x4%925324837.hasinit
00041   //## begin Matrix4x4::Matrix4x4%925324837.initialization preserve=yes
00042   //## end Matrix4x4::Matrix4x4%925324837.initialization
00043 {
00044   //## begin Matrix4x4::Matrix4x4%925324837.body preserve=yes
00045         for( int row = 0 ; row < 4 ; row++ )
00046         {
00047                 for( int col = 0; col < 4; col++ ) 
00048                 {
00049                         if( row == col )
00050                         {
00051                                 values[ row ][ col ] = 1 ;
00052                         }
00053                         else
00054                         {
00055                                 values[ row ][ col ] = 0 ;
00056                         }
00057                 }
00058         }
00059   //## end Matrix4x4::Matrix4x4%925324837.body
00060 }
00061 
00062 
00063 Matrix4x4::~Matrix4x4()
00064 {
00065   //## begin Matrix4x4::~Matrix4x4%.body preserve=yes
00066   //## end Matrix4x4::~Matrix4x4%.body
00067 }
00068 
00069 
00070 
00071 //## Other Operations (implementation)
00072 Matrix4x4 Matrix4x4::operator * (const Matrix4x4& right) const
00073 {
00074   //## begin Matrix4x4::operator*%923255744.body preserve=yes
00075         //improve: unwind this loop
00076         Matrix4x4 returnMe ;
00077         for( int row = 0; row < 4; row++ )
00078         {
00079                 for( int col = 0; col < 4; col++ )
00080                 {
00081                         returnMe.values[ row ][ col ] = 0 ;
00082                         for( int index = 0; index < 4 ; index++ )
00083                         {
00084                                 returnMe.values[ row ][ col ] += values[ row ][ index ] * right.values[ index ][ col ] ;
00085                         }
00086                 }
00087         }
00088         return returnMe ;
00089         //IMPROVE: outguess the compiler by unwinding these loops?
00090   //## end Matrix4x4::operator*%923255744.body
00091 }
00092 
00093 Vector4 Matrix4x4::operator * (const Vector4& right) const
00094 {
00095         Vector4 returnMe( 0.0, 0.0, 0.0 ) ;
00096     int row;
00097     int col;
00098         for(  row = 2; row >= 0; --row )
00099         {
00100                 for( col = 2; col >= 0; --col )
00101                 {
00102                         returnMe[ row ] += values[ row ][ col ] * right[ col ] ;
00103                 }
00104         }
00105 
00106     for( row = 0; row < 3; row++ )
00107     {
00108         returnMe[ row ] += values[ row ][ 3 ];
00109     }
00110         return returnMe ;
00111 }
00112 
00113 Matrix4x4 Matrix4x4::Inverse () const
00114 {
00115   //## begin Matrix4x4::Inverse%925324833.body preserve=yes
00116         //IMPROVE: cache the inverse calculation for quicker computation
00117 
00118         Matrix4x4 J ;
00119         double a = values[ 0 ][ 0 ] ;
00120         double b = values[ 0 ][ 1 ] ;
00121         double c = values[ 0 ][ 2 ] ;
00122         double d = values[ 1 ][ 0 ] ;
00123         double e = values[ 1 ][ 1 ] ;
00124         double f = values[ 1 ][ 2 ] ;
00125         double g = values[ 2 ][ 0 ] ;
00126         double h = values[ 2 ][ 1 ] ;
00127         double i = values[ 2 ][ 2 ] ;
00128         double x = values[ 0 ][ 3 ] ;
00129         double y = values[ 1 ][ 3 ] ;
00130         double z = values[ 2 ][ 3 ] ;
00131         assert( values[ 3 ][ 0 ] == 0 );
00132         assert( values[ 3 ][ 1 ] == 0 );
00133         assert( values[ 3 ][ 2 ] == 0 );
00134         assert( values[ 3 ][ 3 ] == 1 );
00135 
00136         //this is SHANE output for the inverse of a 4x4 matrix of the form
00137         //
00138         //      abcx
00139         //  defy
00140         //      ghiz
00141         //      0001
00142 
00143       J( 0, 0 ) = a;
00144       J( 0, 1 ) = d;
00145       J( 0, 2 ) = g;
00146       J( 0, 3 ) = -a*x -d*y -g*z;       //x
00147       J( 1, 0 ) = b;
00148       J( 1, 1 ) = e;
00149       J( 1, 2 ) = h;
00150       J( 1, 3 ) = -b*x -e*y -h*z; //y
00151       J( 2, 0 ) = c;
00152       J( 2, 1 ) = f;
00153       J( 2, 2 ) = i;
00154       J( 2, 3 ) = -c*x -f*y -i*z;       //z
00155       J( 3, 0 ) = 0.0;
00156       J( 3, 1 ) = 0.0;
00157       J( 3, 2 ) = 0.0;
00158       J( 3, 3 ) = 1.0;
00159 
00160         return J ;
00161   //## end Matrix4x4::Inverse%925324833.body
00162 }
00163 
00164 Matrix4x4& Matrix4x4::operator *= (const Matrix4x4& right)
00165 {
00166   //## begin Matrix4x4::operator*=%925324834.body preserve=yes
00167         Matrix4x4 result ;
00168         result = ( *this ) * right ;    //IMPROVE: get rid of the temp storage
00169         ( *this ) = result ; //IMPROVE: put all this inline
00170         return *this ;
00171   //## end Matrix4x4::operator*=%925324834.body
00172 }
00173 
00174 //=============================================================================
00175 // GetValuesOpenGl 
00176 //
00177 // Description: Gets the matrix values in an openGlCompatible way
00178 //=============================================================================
00179 void Matrix4x4::GetValuesOpenGl ( double values[ 16 ] )
00180 {
00181         int i;
00182         int j;
00183         for( i = 0; i < 4; i++ )
00184         {
00185                 for( j = 0; j < 4; j++ )
00186                 {
00187                         values[ i + j * 4 ] = this->values[ i ][ j ];
00188                 }
00189         }
00190 }
00191 
00192 Matrix4x4 Matrix4x4::Identity ()
00193 {
00194   //## begin Matrix4x4::Identity%925324838.body preserve=yes
00195         Matrix4x4 returnMe ;
00196         for( int row = 0 ; row < 4 ; row++ )
00197         {
00198                 for( int col = 0; col < 4; col++ ) 
00199                 {
00200                         if( row == col )
00201                         {
00202                                 returnMe( row, col ) = 1 ;
00203                         }
00204                         else
00205                         {
00206                                 returnMe( row, col ) = 0 ;
00207                         }
00208                 }
00209         }
00210         return returnMe ;
00211   //## end Matrix4x4::Identity%925324838.body
00212 }
00213 
00214 void Matrix4x4::Scale (const double x, const double y, const double z)
00215 {
00216   //## begin Matrix4x4::Scale%927223872.body preserve=yes
00217         Matrix4x4 multiplyMe ;
00218         multiplyMe( 0, 0 ) = x ;
00219         multiplyMe( 1, 1 ) = y ;
00220         multiplyMe( 2, 2 ) = z ;
00221         *this = multiplyMe * ( *this ) ;                        //IMPROVE: verify the order of the multiplication
00222   //## end Matrix4x4::Scale%927223872.body
00223 }
00224 
00225 void Matrix4x4::Translate (const double x, const double y, const double z)
00226 {
00227   //## begin Matrix4x4::Translate%927223873.body preserve=yes
00228         Matrix4x4 multiplyMe ;
00229         multiplyMe( 0, 3 ) = x ;
00230         multiplyMe( 1, 3 ) = y ;
00231         multiplyMe( 2, 3 ) = z ;
00232         *this = multiplyMe * ( *this ) ;                        //IMPROVE: verify the order of the multiplication
00233   //## end Matrix4x4::Translate%927223873.body
00234 }
00235 
00236 void Matrix4x4::Rotate (const Vector4& axis, double angle)
00237 {
00238   //## begin Matrix4x4::Rotate%928263345.body preserve=yes
00239         Matrix4x4 multiplyMe ;
00240         const double& x = axis[ 0 ] ;
00241         const double& y = axis[ 1 ] ;
00242         const double& z = axis[ 2 ] ;
00243         double c = CosDeg( angle ) ;
00244         double s = SinDeg( angle ) ;
00245 
00246         multiplyMe( 0, 0 ) = x * x + ( 1 - x * x ) * c ;
00247         multiplyMe( 0, 1 ) = x * y * ( 1 - c ) + z * s ;
00248         multiplyMe( 0, 2 ) = z * x * ( 1 - c ) - y * s ;
00249 
00250         multiplyMe( 1, 0 ) = x * y * ( 1 - c ) - z * s ;
00251         multiplyMe( 1, 1 ) = y * y + ( 1 - y * y ) * c ;
00252         multiplyMe( 1, 2 ) = y * z * ( 1 - c ) + x * s ; 
00253 
00254         multiplyMe( 2, 0 ) = z * x * ( 1 - c ) + y * s ;
00255         multiplyMe( 2, 1 ) = y * z * ( 1 - c ) - x * s ;
00256         multiplyMe( 2, 2 ) = z * z + ( 1 - z * z ) * c ;
00257 
00258         *this = multiplyMe * ( *this ) ;                        //IMPROVE: verify the order of the multiplication
00259   //## end Matrix4x4::Rotate%928263345.body
00260 }
00261 
00262 void Matrix4x4::Rotate2 (const Vector4& axis, double angle)
00263 {
00264   //## begin Matrix4x4::Rotate%928263345.body preserve=yes
00265         Matrix4x4 multiplyMe ;
00266         const double& x = axis[ 0 ] ;
00267         const double& y = axis[ 1 ] ;
00268         const double& z = axis[ 2 ] ;
00269         double c = CosDeg( angle ) ;
00270         double s = SinDeg( angle ) ;
00271 
00272         multiplyMe( 0, 0 ) = x * x + ( 1 - x * x ) * c ;
00273         multiplyMe( 0, 1 ) = x * y * ( 1 - c ) - z * s ;
00274         multiplyMe( 0, 2 ) = z * x * ( 1 - c ) + y * s ;
00275 
00276         multiplyMe( 1, 0 ) = x * y * ( 1 - c ) + z * s ;
00277         multiplyMe( 1, 1 ) = y * y + ( 1 - y * y ) * c ;
00278         multiplyMe( 1, 2 ) = y * z * ( 1 - c ) - x * s ; 
00279 
00280         multiplyMe( 2, 0 ) = z * x * ( 1 - c ) - y * s ;
00281         multiplyMe( 2, 1 ) = y * z * ( 1 - c ) + x * s ;
00282         multiplyMe( 2, 2 ) = z * z + ( 1 - z * z ) * c ;
00283 
00284         *this = ( *this ) * multiplyMe;                 //IMPROVE: verify the order of the multiplication
00285   //## end Matrix4x4::Rotate%928263345.body
00286 }
00287 
00288 void Matrix4x4::Translate (const Vector4& offset)
00289 {
00290   //## begin Matrix4x4::Translate%936229637.body preserve=yes
00291         Translate( offset[ 0 ], offset[ 1 ], offset[ 2 ] ) ;    //IMPROVE: inefficient
00292   //## end Matrix4x4::Translate%936229637.body
00293 }
00294 
00295 Matrix4x4 Matrix4x4::Transpose () const
00296 {
00297   //## begin Matrix4x4::Transpose%945817286.body preserve=yes
00298         Matrix4x4 returnMe ;
00299         for( int i = 0; i < 4; i++ )
00300         {
00301                 for( int j = 0; j < 4; j++ )
00302                 {
00303                         returnMe( i, j ) = this->operator()( j, i ) ;
00304                 }
00305         }
00306         return returnMe ;
00307   //## end Matrix4x4::Transpose%945817286.body
00308 }
00309 
00310 void Matrix4x4::SetValues (const Matrix4x4& values)
00311 {
00312   //## begin Matrix4x4::SetValues%969569780.body preserve=yes
00313         for( int i = 0; i < 4; i++ )
00314         {
00315                 for( int j = 0; j < 4; j++ )
00316                 {
00317                         this->operator()( i, j ) = values( i, j );
00318                 }
00319         }
00320 
00321   //## end Matrix4x4::SetValues%969569780.body
00322 }
00323 
00324 //=============================================================================
00325 // SetValues
00326 //
00327 // Description: sets matrix values based on an array of doubles
00328 //=============================================================================
00329 void Matrix4x4::SetValues ( const double values[ 16 ] )
00330 {
00331         for( int i = 0; i < 4; i++ )            //row
00332         {
00333                 for( int j = 0; j < 4; j++ )    //column
00334                 {
00335                         int index = i + ( j * 4 );
00336                         double value = values[ index ];
00337                         this->operator()( j, i ) = value;
00338                 }
00339         }
00340 }
00341 
00342 // Additional Declarations
00343   //## begin Matrix4x4%36FE7C2C01F4.declarations preserve=yes
00344 bool Matrix4x4::operator < (const Matrix4x4& right) const
00345 {
00346         assert( false ) ;
00347         return false ;
00348 }
00349 
00350 bool Matrix4x4::operator ==(const Matrix4x4& right) const
00351 {
00352         return Compare( right, DEFAULT_TOL );
00353 }
00354 
00355 bool Matrix4x4::operator !=(const Matrix4x4& right) const
00356 {
00357         return !(Compare( right, DEFAULT_TOL ));
00358 }
00359 
00360 
00361   //## end Matrix4x4%36FE7C2C01F4.declarations
00362 //## begin module%36FE7C2C01F4.epilog preserve=yes
00363 //## end module%36FE7C2C01F4.epilog
00364 
00365 //=============================================================================
00366 // Compare 
00367 //
00368 // Description: compares if the given matrix is equal to the current matrix 
00369 //                              to within a given tolerance
00370 //=============================================================================
00371 bool Matrix4x4::Compare ( const Matrix4x4& right, const double& tol ) const
00372 {
00373         for ( int i = 0; i < 4; i++ )
00374         {
00375                 for ( int j = 0; j < 4; j++ )
00376                 {
00377                         double diff = values[i][j] - right.values[i][j];
00378                         if ( ( diff > tol ) || ( diff < -tol ) )
00379                         {
00380                                 return false;
00381                         }
00382                 }
00383         }
00384 
00385         // if still in function, then all terms in matrix are equal to within tol
00386         return true;
00387 }
00388 
00389 Matrix4x4::operator Matrixmxn() const
00390 {
00391         Matrixmxn matrix(4, 4);
00392         for (int i=0; i<4; i++)
00393                 for (int j=0; j<4; j++)
00394                         matrix(i, j) = values[i][j];
00395         return matrix;
00396 }
00397 
00398 std::ostream & operator<<( std::ostream &os, const Matrix4x4& m ) 
00399 {
00400         os << "[" 
00401                 << m(0, 0) << " , " << m(0, 1) << " , " << m(0, 2) << " , " << m(0, 3) << " , " 
00402                 << m(1, 0) << " , " << m(1, 1) << " , " << m(1, 2) << " , " << m(1, 3) << " , " 
00403                 << m(2, 0) << " , " << m(2, 1) << " , " << m(2, 2) << " , " << m(2, 3) << " , " 
00404                 << m(3, 0) << " , " << m(3, 1) << " , " << m(3, 2) << " , " << m(3, 3)
00405                 << "]" << endl;
00406         return os ;
00407 }
00408 
00409 std::istream & operator>>( std::istream &is, Matrix4x4& m )
00410 {
00411         eatwhite( is ) ;
00412         char leading = is.get() ;                       //get the leading '['
00413         assert( leading == '[' ) ;
00414 
00415         char delimiter;
00416         for( int i = 0; i < 4; i++ ) 
00417         {
00418                 for (int j = 0; j < 4; j++)
00419                 {
00420                         is >> m( i, j) ;
00421                         eatwhite( is ) ;
00422                         delimiter = is.get() ;
00423                         assert( ( delimiter == ',' ) || ( delimiter == ']' ) ) ;
00424                 }
00425         }
00426 
00427         return is ;
00428 }

Generated on Sat Apr 1 21:30:38 2006 for Motion Planning Kernel by  doxygen 1.4.6-NO