TAPs 0.7.7.3
SPT_Matrix3x3.h
Go to the documentation of this file.
00001 /******************************************************************************
00002 SPT_Matrix3x3.h
00003 
00004 3-by-3 Matrix class and its operations
00005 
00006 Adapted from "Physics for Game Developers" by David M. Bourg (2002)
00007 
00008 Sukitti Punak   (11/12/2003)
00009 Latest Update   (11/20/2003)
00010 ******************************************************************************/
00011 
00012 #ifndef SPT_MATRIX3X3_H
00013 #define SPT_MATRIX3X3_H
00014 
00015 #include <iostream>
00016 using std::cout;
00017 using std::cerr;
00018 using std::endl;
00019 using std::ostream;
00020 
00021 #include <iomanip>
00022 using std::setw;
00023 
00024 //===============================================================================================
00025 // START Class:     SPtMatrix3x3        ***********************************************************
00026 template< typename T >
00027 class SPtMatrix3x3
00028 {
00029 // Data Members     -----------------------------------------------------------
00030 private:
00031     T   e[3][3];
00032 
00033 // Member Functions     -------------------------------------------------------
00034 public:
00035     // Constructors
00036     SPtMatrix3x3();                             // default constructor
00037     SPtMatrix3x3( SPtMatrix3x3< T > &M );       // copy constructor
00038     SPtMatrix3x3( T, T, T, T, T, T, T, T, T );  // typical constructor
00039 
00040     // Useful Functions
00041     void DisplayElements() const;       // display the matrix on the screen
00042     T       Get( int, int ) const;      // get an element
00043     void    Set( int, int, T );         // set an element
00044     void    SetAll( T, T, T, T, T, T, T, T, T );    // set all elements
00045     void    LoadIdentity();             // set to identity matrix
00046 
00047 
00048     // Operations
00049     SPtMatrix3x3< T > & Transpose();
00050     SPtMatrix3x3< T >   GetTranspose() const;
00051     T                   GetDeterminant() const;
00052     SPtMatrix3x3< T > & Inverse();
00053     SPtMatrix3x3< T >   GetInverse() const;
00054 
00055     // Unary Overloaded Operators
00056     SPtMatrix3x3< T > &operator+=( SPtMatrix3x3< T > &M );  // += with matrix
00057     SPtMatrix3x3< T > &operator-=( SPtMatrix3x3< T > &M );  // -= with matrix
00058     SPtMatrix3x3< T > &operator*=( SPtMatrix3x3< T > &M );  // *= with matrix
00059     SPtMatrix3x3< T > &operator*=( T s );               // *= with scalar
00060     SPtMatrix3x3< T > &operator/=( T s );               // /= with scalar
00061 
00062     // Binary Overloaded Operators
00063     SPtMatrix3x3< T > operator+( SPtMatrix3x3< T > &M ) const;  // + with matrix
00064     SPtMatrix3x3< T > operator-( SPtMatrix3x3< T > &M ) const;  // - with matrix
00065     SPtMatrix3x3< T > operator*( SPtMatrix3x3< T > &M ) const;  // * with matrix
00066     SPtMatrix3x3< T > operator*( T s ) const;               // * with scalar
00067     SPtMatrix3x3< T > operator/( T s ) const;               // / with scalar
00068 
00069     // Friend Overloaded Operators
00070     friend SPtMatrix3x3< T > operator*( double s, const SPtMatrix3x3< T > &M )      // scalar * matrix
00071     {
00072         return SPtMatrix3x3< T >(   M.e[0][0]*s,    M.e[0][1]*s,    M.e[0][2]*s,
00073                                     M.e[1][0]*s,    M.e[1][1]*s,    M.e[1][2]*s,
00074                                     M.e[2][0]*s,    M.e[2][1]*s,    M.e[2][2]*s );
00075     }
00076     friend SPtMatrix3x3< T > operator/( double s, const SPtMatrix3x3< T > &M )      // scalar / matrix
00077     {
00078         return SPtMatrix3x3< T >(   M.e[0][0]/s,    M.e[0][1]/s,    M.e[0][2]/s,
00079                                     M.e[1][0]/s,    M.e[1][1]/s,    M.e[1][2]/s,
00080                                     M.e[2][0]/s,    M.e[2][1]/s,    M.e[2][2]/s );
00081     }
00082     friend ostream &operator<<( ostream &output, const SPtMatrix3x3< T > &M )               // put it through ostream
00083     {
00084         output  << "3-by-3 matrix\n"
00085                 << "| " << setw(12) << M.e[0][0] << setw(12) << M.e[0][1] << setw(12) << M.e[0][2] << " |\n"
00086                 << "| " << setw(12) << M.e[1][0] << setw(12) << M.e[1][1] << setw(12) << M.e[1][2] << " |\n"
00087                 << "| " << setw(12) << M.e[2][0] << setw(12) << M.e[2][1] << setw(12) << M.e[2][2] << " |\n";
00088 
00089         return output;
00090     }
00091 
00092 }; // END Class:    SPtMatrix3x3
00093 //===============================================================================================
00094 
00095 //===============================================================================================
00096 // Member Fns Definition of class:  SPtMatrix3x3  *************************************************
00097 
00098 // Constructors     ***********************************************************
00099 //------------------------------------------------------------------------------------------------
00100 // Default Constructor
00101 template< typename T >
00102 SPtMatrix3x3< T >::SPtMatrix3x3()
00103 {
00104     e[0][0] = e[0][1] = e[0][2] = 
00105     e[1][0] = e[1][1] = e[1][2] =
00106     e[2][0] = e[2][1] = e[2][2] = T();
00107 }
00108 
00109 //------------------------------------------------------------------------------------------------
00110 template< typename T >
00111 SPtMatrix3x3< T >::SPtMatrix3x3( SPtMatrix3x3< T > &M )
00112 {
00113     e[0][0] = M.e[0][0];  e[0][1] = M.e[0][1];  e[0][2] = M.e[0][2];
00114     e[1][0] = M.e[1][0];  e[1][1] = M.e[1][1];  e[1][2] = M.e[1][2];
00115     e[2][0] = M.e[2][0];  e[2][1] = M.e[2][1];  e[2][2] = M.e[2][2];
00116 }
00117 
00118 //------------------------------------------------------------------------------------------------
00119 // Typical Constructor
00120 template< typename T >
00121 SPtMatrix3x3< T >::SPtMatrix3x3( T e00, T e01, T e02, 
00122                                  T e10, T e11, T e12,
00123                                  T e20, T e21, T e22 )
00124 {
00125     e[0][0] = e00;  e[0][1] = e01;  e[0][2] = e02;
00126     e[1][0] = e10;  e[1][1] = e11;  e[1][2] = e12;
00127     e[2][0] = e20;  e[2][1] = e21;  e[2][2] = e22;
00128 }
00129 
00130 
00131 //------------------------------------------------------------------------------------------------
00132 // Useful Functions     *******************************************************
00133 // Display The Matrix on Screen
00134 template< typename T >
00135 void SPtMatrix3x3< T >::DisplayElements() const
00136 {
00137     cout << "\n3-by-3 matrix is\n";
00138     cout << "| " << setw(12) << e[0][0] << setw(12) << e[0][1] << setw(12) << e[0][2] << " |\n";
00139     cout << "| " << setw(12) << e[1][0] << setw(12) << e[1][1] << setw(12) << e[1][2] << " |\n";
00140     cout << "| " << setw(12) << e[2][0] << setw(12) << e[2][1] << setw(12) << e[2][2] << " |\n";
00141 }
00142 
00143 //------------------------------------------------------------------------------------------------
00144 // Get an element
00145 template< typename T >
00146 T SPtMatrix3x3< T >::Get( int r, int c ) const
00147 {
00148     if ( 0 <= r && r < 3 && 0 <= c && c < 3 )   return e[r][c];
00149     else                                        return -777;
00150 }
00151 
00152 //------------------------------------------------------------------------------------------------
00153 // Set an element
00154 template< typename T >
00155 void SPtMatrix3x3< T >::Set( int r, int c, T value )
00156 {
00157     if ( 0 <= r && r < 3 && 0 <= c && c < 3 )   e[r][c] = value;
00158 }
00159 
00160 //------------------------------------------------------------------------------------------------
00161 // Set all elements
00162 template< typename T >
00163 void SPtMatrix3x3< T >::SetAll( T e00, T e01, T e02,
00164                                 T e10, T e11, T e12,
00165                                 T e20, T e21, T e22
00166                                )
00167 {
00168     e[0][0] = e00;  e[0][1] = e01;  e[0][2] = e02;
00169     e[1][0] = e10;  e[1][1] = e11;  e[1][2] = e12;
00170     e[2][0] = e20;  e[2][1] = e21;  e[2][2] = e22;
00171 }
00172 
00173 //------------------------------------------------------------------------------------------------
00174 // Set to identity matrix
00175 template< typename T >
00176 void SPtMatrix3x3< T >::LoadIdentity()
00177 {
00178     e[0][0] = 1;    e[0][1] = 0;    e[0][2] = 0;
00179     e[1][0] = 0;    e[1][1] = 1;    e[1][2] = 0;
00180     e[2][0] = 0;    e[2][1] = 0;    e[2][2] = 1;
00181 }
00182 
00183 //------------------------------------------------------------------------------------------------
00184 // Operations       ***********************************************************
00185 // Transpose the matrix
00186 template< typename T >
00187 SPtMatrix3x3< T > &SPtMatrix3x3< T >::Transpose()
00188 {
00189     T temp;
00190 
00191     temp = e[0][1];  e[0][1] = e[1][0];  e[1][0] = temp;
00192     temp = e[0][2];  e[0][2] = e[2][0];  e[2][0] = temp;
00193     temp = e[2][1];  e[2][1] = e[1][2];  e[1][2] = temp;
00194 
00195     return *this;
00196 }
00197 
00198 //------------------------------------------------------------------------------------------------
00199 // Get the matrix transpose
00200 template< typename T >
00201 SPtMatrix3x3< T > SPtMatrix3x3< T >::GetTranspose() const
00202 {
00203     return  SPtMatrix3x3< T >(  e[0][0], e[1][0], e[2][0],
00204                                 e[0][1], e[1][1], e[2][1],
00205                                 e[0][2], e[1][2], e[2][2] );
00206 }
00207 
00208 //------------------------------------------------------------------------------------------------
00209 // Find the determinant
00210 template< typename T >
00211 T SPtMatrix3x3< T >::GetDeterminant() const
00212 {
00213     return      e[0][0] * ( e[1][1]*e[2][2] - e[2][1]*e[1][2] ) 
00214             -   e[1][0] * ( e[0][1]*e[2][2] - e[2][1]*e[0][2] )
00215             +   e[2][0] * ( e[0][1]*e[1][2] - e[1][1]*e[0][2] );
00216 }
00217 
00218 //------------------------------------------------------------------------------------------------
00219 // Inverse the matrix
00220 template< typename T >
00221 SPtMatrix3x3< T > &SPtMatrix3x3< T >::Inverse()
00222 {
00223     *this = (*this).GetInverse();
00224 
00225     return *this;
00226 }
00227 
00228 //------------------------------------------------------------------------------------------------
00229 // Get the matrix inverse
00230 template< typename T >
00231 SPtMatrix3x3< T > SPtMatrix3x3< T >::GetInverse() const
00232 {
00233     T det = GetDeterminant();
00234 
00235     if ( -1E-20 < det && det < 1E-20 )  return SPtMatrix3x3();
00236 
00237     return SPtMatrix3x3< T >(    ( e[1][1]*e[2][2] - e[2][1]*e[1][2] ) / det,
00238                                 -( e[0][1]*e[2][2] - e[2][1]*e[0][2] ) / det,
00239                                  ( e[0][1]*e[1][2] - e[1][1]*e[0][2] ) / det,
00240                                 -( e[1][0]*e[2][2] - e[2][0]*e[1][2] ) / det,
00241                                  ( e[0][0]*e[2][2] - e[2][0]*e[0][2] ) / det,
00242                                 -( e[0][0]*e[1][2] - e[1][0]*e[0][2] ) / det,
00243                                  ( e[1][0]*e[2][1] - e[2][0]*e[1][1] ) / det,
00244                                 -( e[0][0]*e[2][1] - e[2][0]*e[0][1] ) / det,
00245                                  ( e[0][0]*e[1][1] - e[1][0]*e[0][1] ) / det    );
00246 }
00247 
00248 //------------------------------------------------------------------------------------------------
00249 // Unary Overloaded Operators       *******************************************
00250 // += with matrix
00251 template< typename T >
00252 SPtMatrix3x3< T > &SPtMatrix3x3< T >::operator+=( SPtMatrix3x3< T > &M )
00253 {
00254     e[0][0] += M.e[0][0];   e[0][1] += M.e[0][1];   e[0][2] += M.e[0][2];
00255     e[1][0] += M.e[1][0];   e[1][1] += M.e[1][1];   e[1][2] += M.e[1][2];
00256     e[2][0] += M.e[2][0];   e[2][1] += M.e[2][1];   e[2][2] += M.e[2][2];
00257 
00258     return *this;
00259 }
00260 
00261 //------------------------------------------------------------------------------------------------
00262 // += with matrix
00263 template< typename T >
00264 SPtMatrix3x3< T > &SPtMatrix3x3< T >::operator-=( SPtMatrix3x3< T > &M )
00265 {
00266     e[0][0] -= M.e[0][0];   e[0][1] -= M.e[0][1];   e[0][2] -= M.e[0][2];
00267     e[1][0] -= M.e[1][0];   e[1][1] -= M.e[1][1];   e[1][2] -= M.e[1][2];
00268     e[2][0] -= M.e[2][0];   e[2][1] -= M.e[2][1];   e[2][2] -= M.e[2][2];
00269 
00270     return *this;
00271 }
00272 
00273 //------------------------------------------------------------------------------------------------
00274 // *= with matrix
00275 template< typename T >
00276 SPtMatrix3x3< T > &SPtMatrix3x3< T >::operator*=( SPtMatrix3x3< T > &M )
00277 {
00278     *this = (*this) * M;
00279     return *this;
00280 }
00281 
00282 //------------------------------------------------------------------------------------------------
00283 // *= with scalar
00284 template< typename T >
00285 SPtMatrix3x3< T > &SPtMatrix3x3< T >::operator*=( T s )
00286 {
00287     e[0][0] *= s;   e[0][1] *= s;   e[0][2] *= s;
00288     e[1][0] *= s;   e[1][1] *= s;   e[1][2] *= s;
00289     e[2][0] *= s;   e[2][1] *= s;   e[2][2] *= s;
00290 
00291     return *this;
00292 }
00293 
00294 //------------------------------------------------------------------------------------------------
00295 // /= with scalar
00296 template< typename T >
00297 SPtMatrix3x3< T > &SPtMatrix3x3< T >::operator/=( T s )
00298 {
00299     e[0][0] /= s;   e[0][1] /= s;   e[0][2] /= s;
00300     e[1][0] /= s;   e[1][1] /= s;   e[1][2] /= s;
00301     e[2][0] /= s;   e[2][1] /= s;   e[2][2] /= s;
00302 
00303     return *this;
00304 }
00305 
00306 //------------------------------------------------------------------------------------------------
00307 // Binary Overloade Operators       *******************************************
00308 // + with matrix
00309 template< typename T >
00310 SPtMatrix3x3< T > SPtMatrix3x3< T >::operator+( SPtMatrix3x3< T > &M ) const
00311 {
00312     return SPtMatrix3x3< T >(   e[0][0]+M.e[0][0],  e[0][1]+M.e[0][1],  e[0][2]+M.e[0][2],
00313                                 e[1][0]+M.e[1][0],  e[1][1]+M.e[1][1],  e[1][2]+M.e[1][2],
00314                                 e[2][0]+M.e[2][0],  e[2][1]+M.e[2][1],  e[2][2]+M.e[2][2] );
00315 }
00316 
00317 //------------------------------------------------------------------------------------------------
00318 // - with matrix
00319 template< typename T >
00320 SPtMatrix3x3< T > SPtMatrix3x3< T >::operator-( SPtMatrix3x3< T > &M ) const
00321 {
00322     return SPtMatrix3x3< T >(   e[0][0]-M.e[0][0],  e[0][1]-M.e[0][1],  e[0][2]-M.e[0][2],
00323                                 e[1][0]-M.e[1][0],  e[1][1]-M.e[1][1],  e[1][2]-M.e[1][2],
00324                                 e[2][0]-M.e[2][0],  e[2][1]-M.e[2][1],  e[2][2]-M.e[2][2] );
00325 }
00326 
00327 //------------------------------------------------------------------------------------------------
00328 // * with matrix
00329 template< typename T >
00330 SPtMatrix3x3< T > SPtMatrix3x3< T >::operator*( SPtMatrix3x3< T > &M ) const
00331 {
00332     return SPtMatrix3x3< T >(   e[0][0]*M.e[0][0] + e[0][1]*M.e[1][0] + e[0][2]*M.e[2][0],
00333                                 e[0][0]*M.e[0][1] + e[0][1]*M.e[1][1] + e[0][2]*M.e[2][1],
00334                                 e[0][0]*M.e[0][2] + e[0][1]*M.e[1][2] + e[0][2]*M.e[2][2],
00335                                 e[1][0]*M.e[0][0] + e[1][1]*M.e[1][0] + e[1][2]*M.e[2][0],
00336                                 e[1][0]*M.e[0][1] + e[1][1]*M.e[1][1] + e[1][2]*M.e[2][1],
00337                                 e[1][0]*M.e[0][2] + e[1][1]*M.e[1][2] + e[1][2]*M.e[2][2],
00338                                 e[2][0]*M.e[0][0] + e[2][1]*M.e[1][0] + e[2][2]*M.e[2][0],
00339                                 e[2][0]*M.e[0][1] + e[2][1]*M.e[1][1] + e[2][2]*M.e[2][1],
00340                                 e[2][0]*M.e[0][2] + e[2][1]*M.e[1][2] + e[2][2]*M.e[2][2] );
00341 }
00342 
00343 //------------------------------------------------------------------------------------------------
00344 // * with scalar
00345 template< typename T >
00346 SPtMatrix3x3< T > SPtMatrix3x3< T >::operator*( T s ) const
00347 {
00348     return SPtMatrix3x3< T >(   e[0][0]*s,  e[0][1]*s,  e[0][2]*s,
00349                                 e[1][0]*s,  e[1][1]*s,  e[1][2]*s,
00350                                 e[2][0]*s,  e[2][1]*s,  e[2][2]*s );
00351 }
00352 
00353 //------------------------------------------------------------------------------------------------
00354 // / with scalar
00355 template< typename T >
00356 SPtMatrix3x3< T > SPtMatrix3x3< T >::operator/( T s ) const
00357 {
00358     return SPtMatrix3x3< T >(   e[0][0]/s,  e[0][1]/s,  e[0][2]/s,
00359                                 e[1][0]/s,  e[1][1]/s,  e[1][2]/s,
00360                                 e[2][0]/s,  e[2][1]/s,  e[2][2]/s );
00361 }
00362 
00363 /*
00364 // Friend Overloaded Operators
00365 // scalar * matrix
00366 template< typename T >
00367 SPtMatrix3x3< T > operator*( double s, const SPtMatrix3x3< T > &M )
00368 {
00369     return SPtMatrix3x3< T >(   M.e[0][0]*s,    M.e[0][1]*s,    M.e[0][2]*s,
00370                                 M.e[1][0]*s,    M.e[1][1]*s,    M.e[1][2]*s,
00371                                 M.e[2][0]*s,    M.e[2][1]*s,    M.e[2][2]*s );
00372 }
00373 
00374 //------------------------------------------------------------------------------------------------
00375 // scalar / matrix
00376 template< typename T >
00377 SPtMatrix3x3< T > operator/( double s, const SPtMatrix3x3< T > &M )
00378 {
00379     return SPtMatrix3x3< T >(   M.e[0][0]/s,    M.e[0][1]/s,    M.e[0][2]/s,
00380                                 M.e[1][0]/s,    M.e[1][1]/s,    M.e[1][2]/s,
00381                                 M.e[2][0]/s,    M.e[2][1]/s,    M.e[2][2]/s );
00382 }
00383 
00384 //------------------------------------------------------------------------------------------------
00385 // put it through ostream
00386 template< typename T >
00387 ostream &operator<<( ostream &output, const SPtMatrix3x3< T > &M )
00388 {
00389     output  << "3-by-3 matrix\n"
00390             << "| " << setw(12) << M.e[0][0] << setw(12) << M.e[0][1] << setw(12) << M.e[0][2] << " |\n"
00391             << "| " << setw(12) << M.e[1][0] << setw(12) << M.e[1][1] << setw(12) << M.e[1][2] << " |\n"
00392             << "| " << setw(12) << M.e[2][0] << setw(12) << M.e[2][1] << setw(12) << M.e[2][2] << " |\n";
00393 
00394     return output;
00395 }
00396 */
00397 //===============================================================================================
00398 
00399 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines