00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef __VMML__MATRIX3__H__
00017 #define __VMML__MATRIX3__H__
00018
00019
00020
00021
00022
00023 #include <vmmlib/vector3.h>
00024 #include <vmmlib/vector4.h>
00025 #include <vmmlib/stringUtils.h>
00026
00027 #include <cmath>
00028 #include <cstdlib>
00029 #include <iomanip>
00030 #include <iostream>
00031 #include <algorithm>
00032 #include <cassert>
00033
00034
00035
00036
00037
00038 namespace vmml
00039 {
00040
00041 template< typename U >
00042 class Matrix4;
00043
00044 template< typename T >
00045 class Matrix3
00046 {
00047 public:
00048 union
00049 {
00053 struct
00054 {
00055 T m00, m10, m20, m01, m11, m21, m02, m12, m22;
00056 };
00057 T m[3][3];
00058 T ml[9];
00059 T array[9];
00060 };
00061
00062 Matrix3();
00063 Matrix3( const Matrix3& other );
00064 Matrix3( T v00, T v01, T v02, T v10, T v11, T v12, T v20, T v21, T v22 );
00065 Matrix3( const Vector3<T>& v0, const Vector3<T>& v1,
00066 const Vector3<T>& v2, bool columnVectors = false );
00067
00068
00069 Matrix3( float* values );
00070 Matrix3( double* values );
00071
00072
00073 template< typename U >
00074 Matrix3( const Matrix3< U >& other );
00075
00076 inline const Matrix3& operator= ( const Matrix3& other );
00077 inline const Matrix3& operator= ( const T r );
00078 template< typename U >
00079 inline const Matrix3& operator= ( const Matrix3< U >& other );
00080 template< typename U >
00081 inline const Matrix3& operator= ( const Matrix4< U >& other );
00082
00083 inline bool operator== (const Matrix3& other) const;
00084 inline bool operator!= (const Matrix3& other) const;
00085
00086 void set( const Matrix3& other );
00087
00088
00089
00090 void set( const float* other );
00091 void set( const double* other );
00092 void set( T v00, T v01, T v02, T v10, T v11, T v12, T v20, T v21, T v22 );
00093
00094
00095
00096
00097
00098 bool set( const std::string& values, char delimiter = ' ' );
00099
00100 bool set( const std::vector< std::string >& values );
00101
00102 inline Vector3< T > getColumn( const size_t col ) const;
00103 inline Vector3< T > getRow( const size_t row ) const;
00104 inline const T& getElement( const size_t row, const size_t col ) const;
00105
00106 inline void setColumn( const size_t col, const Vector3< T >& colvec );
00107 inline void setRow( const size_t row, const Vector3< T >& rowvec );
00108 inline void setElement( const size_t row, const size_t col,
00109 const T value );
00110
00111
00112 Matrix3 operator+ ( const Matrix3& other ) const;
00113 Matrix3 operator- ( const Matrix3& other ) const;
00114
00115
00116
00117 Matrix3 operator* ( const Matrix3& other ) const;
00118 Matrix3 operator* ( const T scalar ) const;
00119
00120 Matrix3& operator+= ( const Matrix3& other );
00121 Matrix3& operator-= ( const Matrix3& other );
00122 Matrix3& operator*= ( const Matrix3& other );
00123 Matrix3& operator*= ( const T scalar );
00124
00125
00126 Vector3< T > operator* ( const Vector3< T >& other ) const;
00127
00128 Matrix3 getTransposed() const;
00129
00130 T getDeterminant() const;
00131 inline T det() const;
00132
00133 bool isPositiveDefinite( const T limit = -0.0000000001 );
00134
00135 bool getInverse( Matrix3& result, const T limit = 0.0000000001 );
00136 Matrix3 getInverse( bool& isInvertible, const T limit = 0.0000000001 );
00137
00138 void tensor( const Vector3< T >& u, const Vector3< T >& v );
00139
00140 Matrix3 operator-() const;
00141 Matrix3 negate() const;
00142
00143
00144
00145 bool getString( std::string& result, const std::string& delimiter = " " ) const;
00146
00147 friend std::ostream& operator << ( std::ostream& os, const Matrix3& m )
00148 {
00149 const std::ios::fmtflags flags = os.flags();
00150 const int prec = os.precision();
00151
00152 os.setf( std::ios::right, std::ios::adjustfield );
00153 os.precision( 5 );
00154 os << std::endl << "|"
00155 << std::setw(10) << m.ml[0] << " "
00156 << std::setw(10) << m.ml[3] << " "
00157 << std::setw(10) << m.ml[6]
00158 << "|" << std::endl << "|"
00159 << std::setw(10) << m.ml[1] << " "
00160 << std::setw(10) << m.ml[4] << " "
00161 << std::setw(10) << m.ml[7]
00162 << "|" << std::endl << "|"
00163 << std::setw(10) << m.ml[2] << " "
00164 << std::setw(10) << m.ml[5] << " "
00165 << std::setw(10) << m.ml[8]
00166 << "|" << std::endl;
00167 os.precision( prec );
00168 os.setf( flags );
00169 return os;
00170 };
00171
00172 static const Matrix3 IDENTITY;
00173 static const Matrix3 ZERO;
00174
00175 };
00176
00177
00178 typedef Matrix3< float > Matrix3f;
00179 typedef Matrix3< double > Matrix3d;
00180
00181 typedef Matrix3< float > mat3f;
00182 typedef Matrix3< double > mat3d;
00183
00184
00185
00186
00187
00188
00189
00190 template< typename T >
00191 const Matrix3< T > Matrix3< T >::IDENTITY( 1., 0., 0., 0., 1., 0., 0., 0., 1. );
00192
00193
00194
00195 template< typename T >
00196 const Matrix3< T > Matrix3< T >::ZERO( 0., 0., 0., 0., 0., 0., 0., 0., 0. );
00197
00198
00199
00200
00201 template< typename T >
00202 Matrix3< T >::Matrix3()
00203 {}
00204
00205
00206
00207 template< typename T >
00208 Matrix3< T >::Matrix3( const Matrix3< T >& other )
00209 {
00210 memcpy( m, other.m, 9 * sizeof( T ));
00211 }
00212
00213
00214
00215 template< typename T >
00216 Matrix3< T >::Matrix3(
00217 T v00, T v01, T v02,
00218 T v10, T v11, T v12,
00219 T v20, T v21, T v22 )
00220 : m00( v00 )
00221 , m10( v10 )
00222 , m20( v20 )
00223 , m01( v01 )
00224 , m11( v11 )
00225 , m21( v21 )
00226 , m02( v02 )
00227 , m12( v12 )
00228 , m22( v22 )
00229 {}
00230
00231
00232
00233 template< typename T >
00234 template< typename U >
00235 Matrix3< T >::Matrix3( const Matrix3< U >& other )
00236 : m00( static_cast< T > ( other.m00 ) )
00237 , m10( static_cast< T > ( other.m10 ) )
00238 , m20( static_cast< T > ( other.m20 ) )
00239 , m01( static_cast< T > ( other.m01 ) )
00240 , m11( static_cast< T > ( other.m11 ) )
00241 , m21( static_cast< T > ( other.m21 ) )
00242 , m02( static_cast< T > ( other.m02 ) )
00243 , m12( static_cast< T > ( other.m12 ) )
00244 , m22( static_cast< T > ( other.m22 ) )
00245 {}
00246
00247
00248
00249 template< typename T >
00250 Matrix3< T >::Matrix3( const Vector3< T >& v0, const Vector3< T >& v1,
00251 const Vector3< T >& v2, bool columnVectors )
00252 {
00253 if ( columnVectors )
00254 {
00255 ml[0] = v0.x;
00256 ml[3] = v0.y;
00257 ml[6] = v0.z;
00258 ml[1] = v1.x;
00259 ml[4] = v1.y;
00260 ml[7] = v1.z;
00261 ml[2] = v2.x;
00262 ml[5] = v2.y;
00263 ml[8] = v2.z;
00264 }
00265 else
00266 {
00267 ml[0] = v0.x;
00268 ml[1] = v0.y;
00269 ml[2] = v0.z;
00270 ml[3] = v1.x;
00271 ml[4] = v1.y;
00272 ml[5] = v1.z;
00273 ml[6] = v2.x;
00274 ml[7] = v2.y;
00275 ml[8] = v2.z;
00276 }
00277 }
00278
00279
00280
00281 template< typename T >
00282 Matrix3< T >::Matrix3( float* values )
00283 {
00284 assert( values && "Matrix3: Initialisation of a Matrix from a Nullpointer was requested." );
00285 for ( size_t i = 0; i < 9; ++i )
00286 ml[i] = static_cast< T > ( values[i] );
00287 }
00288
00289
00290
00291 template< typename T >
00292 Matrix3< T >::Matrix3( double* values )
00293 {
00294 assert( values && "Matrix3: Initialisation of a Matrix from a Nullpointer was requested." );
00295 for ( size_t i = 0; i < 9; ++i )
00296 ml[i] = static_cast< T > ( values[i] );
00297 }
00298
00299
00300
00301 template< typename T >
00302 const Matrix3< T >& Matrix3< T >::operator= ( const T r )
00303 {
00304 for ( size_t i = 0; i < 9; ++i )
00305 {
00306 ml[i] = r;
00307 }
00308 return *this;
00309 }
00310
00311
00312
00313 template< typename T >
00314 const Matrix3< T >& Matrix3< T >::operator= ( const Matrix3< T >& other )
00315 {
00316 memcpy(ml,other.ml,9*sizeof(T));
00317 return *this;
00318 }
00319
00320
00321
00322 template< typename T >
00323 template< typename U >
00324 const Matrix3< T >& Matrix3< T >::operator= ( const Matrix3< U >& other )
00325 {
00326 m00 = static_cast< T > ( other.m00 );
00327 m10 = static_cast< T > ( other.m10 );
00328 m20 = static_cast< T > ( other.m20 );
00329 m01 = static_cast< T > ( other.m01 );
00330 m11 = static_cast< T > ( other.m11 );
00331 m21 = static_cast< T > ( other.m21 );
00332 m02 = static_cast< T > ( other.m02 );
00333 m12 = static_cast< T > ( other.m12 );
00334 m22 = static_cast< T > ( other.m22 );
00335 return *this;
00336 }
00337
00338
00339 template< typename T >
00340 template< typename U >
00341 const Matrix3< T >& Matrix3< T >::operator= ( const Matrix4< U >& other )
00342 {
00343 m00 = static_cast< T > ( other.m00 );
00344 m10 = static_cast< T > ( other.m10 );
00345 m20 = static_cast< T > ( other.m20 );
00346 m01 = static_cast< T > ( other.m01 );
00347 m11 = static_cast< T > ( other.m11 );
00348 m21 = static_cast< T > ( other.m21 );
00349 m02 = static_cast< T > ( other.m02 );
00350 m12 = static_cast< T > ( other.m12 );
00351 m22 = static_cast< T > ( other.m22 );
00352 return *this;
00353 }
00354
00355
00356 template< typename T >
00357 bool Matrix3< T >::operator== (const Matrix3< T >& other) const
00358 {
00359 for ( size_t i = 0; i < 9; ++i )
00360 {
00361 if( ml[i] != other.ml[i] )
00362 return false;
00363 }
00364 return true;
00365 }
00366
00367
00368
00369 template< typename T >
00370 inline bool Matrix3< T >::operator!= (const Matrix3< T >& other) const
00371 {
00372 return !operator==( other);
00373 }
00374
00375
00376
00377 template< typename T >
00378 void Matrix3< T >::set( const Matrix3& other )
00379 {
00380 memcpy( ml, other.ml, 9 * sizeof( T ) );
00381 }
00382
00383
00384
00385 template< typename T >
00386 void Matrix3< T >::set( const float* other )
00387 {
00388 assert( other && "Matrix3: Nullpointer argument as source for initialisation!" );
00389 for ( size_t i = 0; i < 9; ++i )
00390 ml[i] = static_cast< T > ( other[i] );
00391 }
00392
00393
00394
00395 template< typename T >
00396 void Matrix3< T >::set( const double* other )
00397 {
00398 assert( other && "Matrix3: Nullpointer argument as source for initialisation!" );
00399 for ( size_t i = 0; i < 9; ++i )
00400 ml[i] = static_cast< T > ( other[i] );
00401 }
00402
00403
00404
00405 template< typename T >
00406 void Matrix3< T >::set( T v00, T v01, T v02, T v10, T v11, T v12, T v20,
00407 T v21, T v22 )
00408 {
00409 m00 = v00;
00410 m01 = v01;
00411 m02 = v02;
00412 m10 = v10;
00413 m11 = v11;
00414 m12 = v12;
00415 m20 = v20;
00416 m21 = v21;
00417 m22 = v22;
00418 }
00419
00420
00421
00422
00423
00424
00425
00426 template< typename T >
00427 bool
00428 Matrix3< T >::set( const std::string& values, char delimiter )
00429 {
00430 std::vector< std::string > tokens;
00431 stringUtils::split( values, tokens, delimiter );
00432 return set( tokens );
00433 }
00434
00435
00436
00437
00438
00439
00440
00441 template< typename T >
00442 bool
00443 Matrix3< T >::set( const std::vector< std::string >& values )
00444 {
00445 bool ok = true;
00446
00447 if ( values.size() < 9 )
00448 return false;
00449
00450 std::vector< std::string >::const_iterator it = values.begin();
00451
00452 for( size_t row = 0; row < 3; ++row )
00453 {
00454 for( size_t col = 0; ok && col < 3; ++col, ++it )
00455 {
00456
00457 ok = stringUtils::fromString< T >( *it, m[ col ][ row ] );
00458 }
00459 }
00460
00461 return ok;
00462 }
00463
00464
00465
00466 template< typename T >
00467 Vector3< T > Matrix3< T >::getColumn( size_t column ) const
00468 {
00469 if ( column > 2 )
00470 std::cerr << "Matrix3::getColumn - invalid column index " << column << "." << std::endl;
00471 assert( column < 3 && "Matrix3: Requested Column ( getColumn ) with invalid index!" );
00472 return Vector3< T >( m[column] );
00473 }
00474
00475
00476
00477 template< typename T >
00478 Vector3< T > Matrix3< T >::getRow( const size_t row ) const
00479 {
00480 assert( row < 3 && "Matrix3: Requested Row ( getRow ) with invalid index!" );
00481 return Vector3< T > ( ml[0+row], ml[3+row], ml[6+row] );
00482 }
00483
00484
00485
00486 template< typename T >
00487 inline const T& Matrix3< T >::getElement( const size_t row, const size_t col ) const
00488 {
00489 return m[col][row];
00490 }
00491
00492
00493
00494 template< typename T >
00495 void Matrix3< T >::setColumn( size_t column, const Vector3< T >& columnVec )
00496 {
00497 m[column][0] = columnVec[0];
00498 m[column][1] = columnVec[1];
00499 m[column][2] = columnVec[2];
00500 }
00501
00502
00503
00504 template< typename T >
00505 void Matrix3< T >::setRow( size_t row, const Vector3< T >& rowvec )
00506 {
00507 m[0][row] = rowvec[0];
00508 m[1][row] = rowvec[1];
00509 m[2][row] = rowvec[2];
00510 }
00511
00512
00513
00514 template< typename T >
00515 inline void Matrix3< T >::setElement( const size_t row, const size_t col, const T value )
00516 {
00517 m[col][row] = value;
00518 }
00519
00520
00521
00522 template< typename T >
00523 Matrix3< T > Matrix3< T >::operator+ ( const Matrix3< T >& other ) const
00524 {
00525 Matrix3< T > result;
00526 for ( size_t i = 0; i < 9; ++i )
00527 result.ml[i] = ml[i] + other.ml[i];
00528 return result;
00529 }
00530
00531
00532
00533 template< typename T >
00534 Matrix3< T > Matrix3< T >::operator- ( const Matrix3< T >& other ) const
00535 {
00536 Matrix3< T > result;
00537 for ( size_t i = 0; i < 9; ++i )
00538 result.ml[i] = ml[i] - other.ml[i];
00539 return result;
00540 }
00541
00542
00543
00544 template< typename T >
00545 Matrix3< T > Matrix3< T >::operator* ( const Matrix3< T >& o ) const
00546 {
00547 Matrix3< T > r;
00548
00549 r.m00 = m00*o.m00 + m01*o.m10 + m02*o.m20;
00550 r.m10 = m10*o.m00 + m11*o.m10 + m12*o.m20;
00551 r.m20 = m20*o.m00 + m21*o.m10 + m22*o.m20;
00552
00553 r.m01 = m00*o.m01 + m01*o.m11 + m02*o.m21;
00554 r.m11 = m10*o.m01 + m11*o.m11 + m12*o.m21;
00555 r.m21 = m20*o.m01 + m21*o.m11 + m22*o.m21;
00556
00557 r.m02 = m00*o.m02 + m01*o.m12 + m02*o.m22;
00558 r.m12 = m10*o.m02 + m11*o.m12 + m12*o.m22;
00559 r.m22 = m20*o.m02 + m21*o.m12 + m22*o.m22;
00560
00561 return r;
00562 }
00563
00564
00565
00566 template< typename T >
00567 Matrix3< T > Matrix3< T >::operator* ( const T scalar ) const
00568 {
00569 Matrix3< T > result;
00570 for ( size_t i = 0; i < 9; ++i )
00571 result.ml[i] = ml[i] * scalar;
00572 return result;
00573 }
00574
00575
00576
00577 template< typename T >
00578 Matrix3< T >& Matrix3< T >::operator+= ( const Matrix3& other )
00579 {
00580 for ( size_t i = 0; i < 9; ++i )
00581 ml[i] += other.ml[i];
00582 return *this;
00583 }
00584
00585
00586
00587 template< typename T >
00588 Matrix3< T >& Matrix3< T >::operator-= ( const Matrix3& other )
00589 {
00590 for ( size_t i = 0; i < 9; ++i )
00591 ml[i] -= other.ml[i];
00592 return *this;
00593 }
00594
00595
00596
00597 template< typename T >
00598 Matrix3< T >& Matrix3< T >::operator*= ( const Matrix3& o )
00599 {
00600 Matrix3< T > r;
00601
00602 r.m00 = m00*o.m00 + m01*o.m10 + m02*o.m20;
00603 r.m10 = m10*o.m00 + m11*o.m10 + m12*o.m20;
00604 r.m20 = m20*o.m00 + m21*o.m10 + m22*o.m20;
00605
00606 r.m01 = m00*o.m01 + m01*o.m11 + m02*o.m21;
00607 r.m11 = m10*o.m01 + m11*o.m11 + m12*o.m21;
00608 r.m21 = m20*o.m01 + m21*o.m11 + m22*o.m21;
00609
00610 r.m02 = m00*o.m02 + m01*o.m12 + m02*o.m22;
00611 r.m12 = m10*o.m02 + m11*o.m12 + m12*o.m22;
00612 r.m22 = m20*o.m02 + m21*o.m12 + m22*o.m22;
00613
00614 *this = r;
00615 return *this;
00616 }
00617
00618
00619
00620 template< typename T >
00621 Matrix3< T >& Matrix3< T >::operator*= ( T scalar )
00622 {
00623 for ( size_t i = 0; i < 9; ++i )
00624 ml[i] *= scalar;
00625 return *this;
00626 }
00627
00628
00629
00630 template< typename T >
00631 Vector3< T > Matrix3< T >::operator* ( const Vector3< T >& other ) const
00632 {
00633 return Vector3< T >( m00 * other[0] + m01 * other[1] + m02 * other[2],
00634 m10 * other[0] + m11 * other[1] + m12 * other[2],
00635 m20 * other[0] + m21 * other[1] + m22 * other[2] );
00636 }
00637
00638
00639
00640 template< typename T >
00641 Matrix3< T > Matrix3< T >::getTransposed() const
00642 {
00643 Matrix3< T > result;
00644 result.m[0][0] = m[0][0];
00645 result.m[0][1] = m[1][0];
00646 result.m[0][2] = m[2][0];
00647 result.m[1][0] = m[0][1];
00648 result.m[1][1] = m[1][1];
00649 result.m[1][2] = m[2][1];
00650 result.m[2][0] = m[0][2];
00651 result.m[2][1] = m[1][2];
00652 result.m[2][2] = m[2][2];
00653 return result;
00654 }
00655
00656
00657
00658 template< typename T >
00659 inline T Matrix3< T >::det() const
00660 {
00661 return getDeterminant();
00662 }
00663
00664
00665
00666 template< typename T >
00667 T Matrix3< T >::getDeterminant() const
00668 {
00669 const Vector3< T > cof( m11 * m22 - m12 * m21,
00670 m12 * m20 - m10 * m22,
00671 m10 * m21 - m11 * m20 );
00672 return m00 * cof[0] + m01 * cof[1] + m02 * cof[2];
00673 }
00674
00675
00676
00677 template< typename T >
00678 bool Matrix3< T >::isPositiveDefinite( T limit )
00679 {
00680 if( ( m00 ) < limit ||
00681 ( m00*m11 - m01*m10 ) < limit ||
00682 ( m00*m11*m22 - m00*m12*m21 +
00683 m01*m12*m20 - m01*m10*m22 +
00684 m02*m10*m21 - m02*m11*m20 ) < limit )
00685
00686 return false;
00687 return true;
00688 }
00689
00690
00691
00692 template< typename T >
00693 Matrix3< T > Matrix3< T >::getInverse( bool& isInvertible, T limit )
00694 {
00695 Matrix3< T > inv;
00696 isInvertible = getInverse( inv, limit );
00697 return inv;
00698 }
00699
00700
00701
00702 template< typename T >
00703 bool Matrix3< T >::getInverse( Matrix3< T >& result, T limit )
00704 {
00705
00706
00707
00708 result.m00 = m11 * m22 - m12 * m21;
00709 result.m01 = m02 * m21 - m01 * m22;
00710 result.m02 = m01 * m12 - m02 * m11;
00711 result.m10 = m12 * m20 - m10 * m22;
00712 result.m11 = m00 * m22 - m02 * m20;
00713 result.m12 = m02 * m10 - m00 * m12;
00714 result.m20 = m10 * m21 - m11 * m20;
00715 result.m21 = m01 * m20 - m00 * m21;
00716 result.m22 = m00 * m11 - m01 * m10;
00717
00718 const T determinant = m00 * result.m00 + m01 * result.m10 +
00719 m02 * result.m20;
00720
00721 if ( fabs( determinant ) <= limit )
00722 return false;
00723
00724 const T detinv = 1.0 / determinant;
00725 result.m00 *= detinv;
00726 result.m01 *= detinv;
00727 result.m02 *= detinv;
00728 result.m10 *= detinv;
00729 result.m11 *= detinv;
00730 result.m12 *= detinv;
00731 result.m20 *= detinv;
00732 result.m21 *= detinv;
00733 result.m22 *= detinv;
00734 return true;
00735 }
00736
00737
00738
00739 template< typename T >
00740 void Matrix3< T >::tensor( const Vector3< T >& u, const Vector3< T >& v)
00741 {
00742 for( int j = 0; j < 3; j++)
00743 for( int i = 0; i < 3; i++)
00744 m[i][j] = u[j] * v[i];
00745 }
00746
00747
00748
00749 template< typename T >
00750 Matrix3< T > Matrix3< T >::operator-() const
00751 {
00752 Matrix3< T > result( *this );
00753 result *= -1.0;
00754 return result;
00755 }
00756
00757
00758
00759 template< typename T >
00760 Matrix3< T > Matrix3< T >::negate() const
00761 {
00762 Matrix3< T > result( *this );
00763 result *= -1.0;
00764 return result;
00765 }
00766
00767
00768
00769
00770
00771 template< typename T >
00772 bool
00773 Matrix3< T >::getString( std::string& result, const std::string& delimiter ) const
00774 {
00775 std::string tmp;
00776 bool ok = true;
00777 for( size_t row = 0; row < 3; ++row )
00778 {
00779 for( size_t col = 0; ok && col < 3; ++col )
00780 {
00781 ok = stringUtils::toString< T >( m[ col ][ row ], tmp );
00782 result += tmp;
00783 result += delimiter;
00784 }
00785 }
00786 return ok;
00787 }
00788
00789
00790 }
00791
00792 #endif
00793