00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "../additional/streams/mystreams.h"
00016 #include <assert.h>
00017 #include "math2.h"
00018
00019
00020
00021 #include "Vector4.h"
00022
00023 #include "Matrix4x4.h"
00024 #include "Matrixmxn.h"
00025
00026
00027
00028
00029
00030
00031
00032
00033 static const double DEFAULT_TOL = 0.1;
00034
00035
00036
00037
00038 Matrix4x4::Matrix4x4 ()
00039
00040
00041
00042
00043 {
00044
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
00060 }
00061
00062
00063 Matrix4x4::~Matrix4x4()
00064 {
00065
00066
00067 }
00068
00069
00070
00071
00072 Matrix4x4 Matrix4x4::operator * (const Matrix4x4& right) const
00073 {
00074
00075
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
00090
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
00116
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
00137
00138
00139
00140
00141
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;
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;
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;
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
00162 }
00163
00164 Matrix4x4& Matrix4x4::operator *= (const Matrix4x4& right)
00165 {
00166
00167 Matrix4x4 result ;
00168 result = ( *this ) * right ;
00169 ( *this ) = result ;
00170 return *this ;
00171
00172 }
00173
00174
00175
00176
00177
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
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
00212 }
00213
00214 void Matrix4x4::Scale (const double x, const double y, const double z)
00215 {
00216
00217 Matrix4x4 multiplyMe ;
00218 multiplyMe( 0, 0 ) = x ;
00219 multiplyMe( 1, 1 ) = y ;
00220 multiplyMe( 2, 2 ) = z ;
00221 *this = multiplyMe * ( *this ) ;
00222
00223 }
00224
00225 void Matrix4x4::Translate (const double x, const double y, const double z)
00226 {
00227
00228 Matrix4x4 multiplyMe ;
00229 multiplyMe( 0, 3 ) = x ;
00230 multiplyMe( 1, 3 ) = y ;
00231 multiplyMe( 2, 3 ) = z ;
00232 *this = multiplyMe * ( *this ) ;
00233
00234 }
00235
00236 void Matrix4x4::Rotate (const Vector4& axis, double angle)
00237 {
00238
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 ) ;
00259
00260 }
00261
00262 void Matrix4x4::Rotate2 (const Vector4& axis, double angle)
00263 {
00264
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;
00285
00286 }
00287
00288 void Matrix4x4::Translate (const Vector4& offset)
00289 {
00290
00291 Translate( offset[ 0 ], offset[ 1 ], offset[ 2 ] ) ;
00292
00293 }
00294
00295 Matrix4x4 Matrix4x4::Transpose () const
00296 {
00297
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
00308 }
00309
00310 void Matrix4x4::SetValues (const Matrix4x4& values)
00311 {
00312
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
00322 }
00323
00324
00325
00326
00327
00328
00329 void Matrix4x4::SetValues ( const double values[ 16 ] )
00330 {
00331 for( int i = 0; i < 4; i++ )
00332 {
00333 for( int j = 0; j < 4; j++ )
00334 {
00335 int index = i + ( j * 4 );
00336 double value = values[ index ];
00337 this->operator()( j, i ) = value;
00338 }
00339 }
00340 }
00341
00342
00343
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
00362
00363
00364
00365
00366
00367
00368
00369
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
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() ;
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 }