ML Reference
|
00001 // **InsertLicense** code 00002 //===================================================================================== 00004 00009 //===================================================================================== 00010 00011 #ifndef __mlMatrix3_H 00012 #define __mlMatrix3_H 00013 00014 // Include system independency file and project settings. 00015 #ifndef __mlLinearAlgebraSystem_H 00016 #include "mlLinearAlgebraSystem.h" 00017 #endif 00018 #ifndef __mlLinearAlgebraDefs_H 00019 #include "mlLinearAlgebraDefs.h" 00020 #endif 00021 #ifndef __mlLinearAlgebraTools_H 00022 #include "mlLinearAlgebraTools.h" 00023 #endif 00024 00025 #ifndef __mlFloatingPointMatrix_H 00026 #include "mlFloatingPointMatrix.h" 00027 #endif 00028 00029 #ifndef __mlMatrix2_H 00030 #include "mlMatrix2.h" 00031 #endif 00032 #ifndef __mlVector3_H 00033 #include "mlVector3.h" 00034 #endif 00035 00036 // All declarations of this header will be in the ML_LA_NAMESPACE namespace. 00037 ML_LA_START_NAMESPACE 00038 00039 //-------------------------------------------------------------------- 00041 //-------------------------------------------------------------------- 00042 template <class DT> 00043 class Tmat3 : public FloatingPointMatrix<Tvec3<DT>, 3> 00044 { 00045 00046 public: 00047 00049 typedef DT ComponentType; 00050 00051 // Build 3x3 matrix from 9 zero elements. 00052 Tmat3(); 00053 00054 // Build matrix that has the argument at the diagonal values, zero otherwise 00055 Tmat3(const DT diagValue); 00056 00057 // Build matrix of the three row vectors row0, row1, row2. 00058 Tmat3(const Tvec3<DT> &row0, const Tvec3<DT> &row1, const Tvec3<DT> &row2); 00059 00060 // Copy constructor from the Tmat3 mat. 00061 Tmat3(const Tmat3<DT> &mat); 00062 00063 // Constructor from 9 floating point values in an array given by mat, row by row. 00064 Tmat3(const float mat[9]); 00065 00066 // Constructor from 9 double values in an array given by mat, row by row. 00067 Tmat3(const double mat[9]); 00068 00069 // Initialize all matrix elements explicitly with scalars, 00070 // filling it row by row. 00071 Tmat3(const double in00, const double in01, const double in02, 00072 const double in10, const double in11, const double in12, 00073 const double in20, const double in21, const double in22); 00074 00075 // Copy contents from float array mat into *this, row by row. 00076 void setValues(const float mat[9]); 00077 00078 // Copy contents of *this into float array mat, row by row. 00079 // Note that range and precision of the float values may not be 00080 // sufficient for the double matrix contents. 00081 void getValues(float mat[9]) const; 00082 00083 // Copy contents from double array mat into *this, row by row. 00084 void setValues(const double mat[9]); 00085 00086 // Copy contents of *this into double array mat, row by row. 00087 void getValues(double mat[9]) const; 00088 00089 // Set diagonal matrix with scale on diagonal. 00090 void setScaleMatrix(const DT scale); 00091 00092 // Return a matrix filled with values val. 00093 static Tmat3<DT> getMat(const double val); 00094 00095 // Set all values to val. 00096 void set(DT val); 00097 00100 bool operator<(const Tmat3<DT> &) const { return false; } 00101 00102 // Assignment from a Tmat3 00103 const Tmat3<DT> &operator=(const Tmat3<DT> &m); 00104 00105 // Incrementation by a Tmat3. 00106 const Tmat3<DT> &operator+=(const Tmat3<DT> &m); 00107 00108 // Decrement by a Tmat3 00109 const Tmat3<DT> &operator-=(const Tmat3<DT> &m); 00110 00111 // Multiplication by a scalar constant 00112 const Tmat3<DT> &operator*=(const DT d); 00113 00114 // Division by a scalar constant. 00115 // Division by zero is not handled and must be avoided by caller. 00116 const Tmat3<DT> &operator/=(const DT d); 00117 00118 //------------------------------------------------- 00119 // Special functions 00120 //------------------------------------------------- 00121 // Determinant. 00122 DT det() const; 00123 00124 // Transpose. 00125 Tmat3 transpose() const; 00126 00127 // Return identity matrix. 00128 static Tmat3 getIdentity(); 00129 00130 // Returns the inverse. Gauss-Jordan elimination with partial pivoting. 00131 // If a non-NULL Boolean pointer is passed to isInvertible 00132 // then true is returned in *isInvertible in the case of a 00133 // successful inversion or false if the inversion is not possible 00134 // (function return is the identity then). 00135 // If a NULL pointer is passed as isInvertible the matrix must 00136 // be invertible, otherwise errors will occur. 00137 Tmat3 inverse(bool* isInvertible=NULL) const; 00138 00139 // Apply the function fct to each component. 00140 const Tmat3<DT> &apply(MLDblFuncPtr fct); 00141 00142 // Calculate Jacobi-Decomposition of 3x3 matrix. 00143 Tmat3 jacobi(Tvec3<DT> &eVal, int &rots) const; 00144 00145 }; // end of class *Tmat3* 00146 00147 00148 00149 //--------------------------------------------------------------------- 00151 00152 //--------------------------------------------------------------------- 00154 template <class DT> 00155 inline Tmat3<DT>::Tmat3() 00156 { 00157 ML_TRACE_IN_TIME_CRITICAL("Tmat3<DT>::Tmat3())"); 00158 00159 this->v[0] = this->v[1] = this->v[2] = Tvec3<DT>(0); 00160 } 00161 00162 // Construct matrix that has the argument at the diagonal values, zero otherwise 00163 template <class DT> 00164 inline Tmat3<DT>::Tmat3(const DT diagValue) 00165 { 00166 ML_TRACE_IN_TIME_CRITICAL("Tmat3<DT>::Tmat3(diagValue)"); 00167 00168 this->v[0][0] = this->v[1][1] = this->v[2][2] = diagValue; 00169 this->v[1][0] = this->v[2][0] = this->v[2][1] = 0; 00170 this->v[0][1] = this->v[0][2] = this->v[1][2] = 0; 00171 } 00172 00174 template <class DT> 00175 inline Tmat3<DT>::Tmat3(const Tvec3<DT> &row0, const Tvec3<DT> &row1, const Tvec3<DT> &row2) 00176 { 00177 ML_TRACE_IN_TIME_CRITICAL("Tmat3<DT>::Tmat3(const Tvec3<DT> &row0, const Tvec3<DT> &row1, const Tvec3<DT> &row2)"); 00178 00179 this->v[0] = row0; 00180 this->v[1] = row1; 00181 this->v[2] = row2; 00182 } 00183 00185 template <class DT> 00186 inline Tmat3<DT>::Tmat3(const Tmat3<DT> &mat) 00187 { 00188 ML_TRACE_IN_TIME_CRITICAL("Tmat3<DT>::Tmat3(const Tmat3<DT> &mat)"); 00189 00190 this->v[0] = mat.v[0]; 00191 this->v[1] = mat.v[1]; 00192 this->v[2] = mat.v[2]; 00193 } 00194 00196 template <class DT> 00197 inline Tmat3<DT>::Tmat3(const float mat[9]) 00198 { 00199 ML_TRACE_IN_TIME_CRITICAL("Tmat3<DT>::Tmat3(const float mat[9]))"); 00200 00201 setValues(mat); 00202 } 00203 00205 template <class DT> 00206 inline Tmat3<DT>::Tmat3(const double mat[9]) 00207 { 00208 ML_TRACE_IN_TIME_CRITICAL("Tmat3<DT>::Tmat3(const double mat[9])"); 00209 00210 setValues(mat); 00211 } 00212 00214 template <class DT> 00215 inline Tmat3<DT> Tmat3<DT>::getMat(const double val) 00216 { 00217 ML_TRACE_IN_TIME_CRITICAL("Tmat3<DT>::getMat(const double val)"); 00218 00219 return Tmat3<DT>(val, val, val, 00220 val, val, val, 00221 val, val, val); 00222 } 00223 00225 template <class DT> 00226 inline void Tmat3<DT>::set(DT val) 00227 { 00228 ML_TRACE_IN_TIME_CRITICAL("Tmat3<DT>::set(DT val)"); 00229 00230 this->v[0] = this->v[1] = this->v[2] = Tvec3<DT>(val); 00231 } 00232 00234 template <class DT> 00235 inline const Tmat3<DT> &Tmat3<DT>::operator=(const Tmat3<DT> &m) 00236 { 00237 ML_TRACE_IN_TIME_CRITICAL("Tmat3<DT>::operator=(const Tmat3<DT> &m)"); 00238 00239 if (&m != this){ 00240 this->v[0] = m.v[0]; 00241 this->v[1] = m.v[1]; 00242 this->v[2] = m.v[2]; 00243 } 00244 00245 return *this; 00246 } 00247 00249 template <class DT> 00250 inline const Tmat3<DT> &Tmat3<DT>::operator+=(const Tmat3<DT> &m) 00251 { 00252 ML_TRACE_IN_TIME_CRITICAL("Tmat3<DT>::operator+=(const Tmat3<DT> &m)"); 00253 00254 this->v[0] += m.v[0]; 00255 this->v[1] += m.v[1]; 00256 this->v[2] += m.v[2]; 00257 00258 return *this; 00259 } 00260 00262 template <class DT> 00263 inline const Tmat3<DT> &Tmat3<DT>::operator-=(const Tmat3<DT> &m) 00264 { 00265 ML_TRACE_IN_TIME_CRITICAL("Tmat3<DT>::operator-=(const Tmat3<DT> &m)"); 00266 00267 this->v[0] -= m.v[0]; 00268 this->v[1] -= m.v[1]; 00269 this->v[2] -= m.v[2]; 00270 00271 return *this; 00272 } 00273 00275 template <class DT> 00276 inline const Tmat3<DT> &Tmat3<DT>::operator*=(const DT d) 00277 { 00278 ML_TRACE_IN_TIME_CRITICAL("Tmat3<DT>::operator*=(const DT d)"); 00279 00280 this->v[0] *= d; 00281 this->v[1] *= d; 00282 this->v[2] *= d; 00283 00284 return *this; 00285 } 00286 00288 template <class DT> 00289 inline const Tmat3<DT> &Tmat3<DT>::operator/=(const DT d) 00290 { 00291 ML_TRACE_IN("Tmat3<DT>::operator/=(const DT d)"); 00292 ML_TRY 00293 { 00294 this->v[0] /= d; 00295 this->v[1] /= d; 00296 this->v[2] /= d; 00297 } 00298 ML_CATCH_RETHROW; 00299 return *this; 00300 } 00302 00303 00304 //==================================================================== 00306 00307 //==================================================================== 00309 template <class DT> 00310 inline Tmat3<DT> operator-(const Tmat3<DT> &a) 00311 { 00312 ML_TRACE_IN_TIME_CRITICAL("mlMatrix3.h: operator-(const Tmat3<DT> &a)"); 00313 00314 return Tmat3<DT>(a) *= static_cast<DT>(-1.0); 00315 } 00316 00318 template <class DT> 00319 inline Tmat3<DT> operator+(const Tmat3<DT> &a, const Tmat3<DT> &b) 00320 { 00321 ML_TRACE_IN_TIME_CRITICAL("mlMatrix3.h: operator+(const Tmat3<DT> &a, const Tmat3<DT> &b)"); 00322 00323 return Tmat3<DT>(a) += b; 00324 } 00325 00327 template <class DT> 00328 inline Tmat3<DT> operator-(const Tmat3<DT> &a, const Tmat3<DT> &b) 00329 { 00330 ML_TRACE_IN_TIME_CRITICAL("mlMatrix3.h: operator-(const Tmat3<DT> &a, const Tmat3<DT> &b)"); 00331 00332 return Tmat3<DT>(a) -= b; 00333 } 00334 00336 template <class DT> 00337 inline Tmat3<DT> operator*(const Tmat3<DT> &a, const DT d) 00338 { 00339 ML_TRACE_IN_TIME_CRITICAL("mlMatrix3.h: operator*(const Tmat3<DT> &a, const DT d)"); 00340 00341 return Tmat3<DT>(a) *= d; 00342 } 00343 00345 template <class DT> 00346 inline Tmat3<DT> operator*(const DT d, const Tmat3<DT> &a) 00347 { 00348 ML_TRACE_IN_TIME_CRITICAL("mlMatrix3.h: operator*(const DT d, const Tmat3<DT> &a)"); 00349 00350 return Tmat3<DT>(a) *= d; 00351 } 00352 00355 template <class DT> 00356 inline Tmat3<DT> operator/(const Tmat3<DT> &a, const DT d) 00357 { 00358 ML_TRACE_IN_TIME_CRITICAL("mlMatrix3.h: operator/(const Tmat3<DT> &a, const DT d)"); 00359 00360 Tmat3<DT> retVal(a); 00361 ML_TRY 00362 { 00363 retVal /= d; 00364 } 00365 ML_CATCH_RETHROW; 00366 return retVal; 00367 } 00369 00370 00371 //------------------------------------------------------------------- 00372 // 00374 00375 // 00376 //------------------------------------------------------------------- 00377 00378 //------------------------------------------------------------------- 00381 //------------------------------------------------------------------- 00382 template <class DT> 00383 inline Tmat3<DT>::Tmat3(const double in00, const double in01, const double in02, 00384 const double in10, const double in11, const double in12, 00385 const double in20, const double in21, const double in22) 00386 { 00387 ML_TRACE_IN("Tmat3<DT>::Tmat3( )"); 00388 00389 this->v[0][0]=static_cast<DT>(in00); this->v[0][1]=static_cast<DT>(in01); this->v[0][2]=static_cast<DT>(in02); 00390 this->v[1][0]=static_cast<DT>(in10); this->v[1][1]=static_cast<DT>(in11); this->v[1][2]=static_cast<DT>(in12); 00391 this->v[2][0]=static_cast<DT>(in20); this->v[2][1]=static_cast<DT>(in21); this->v[2][2]=static_cast<DT>(in22); 00392 } 00393 00394 00395 //-------------------------------------------------------------------- 00397 //-------------------------------------------------------------------- 00398 template <class DT> 00399 inline void Tmat3<DT>::setValues(const float mat[9]) 00400 { 00401 ML_TRACE_IN("Tmat3<DT>::setValues( )"); 00402 ML_TRY 00403 { 00404 this->v[0][0] = static_cast<DT>(mat[0]); this->v[0][1] = static_cast<DT>(mat[1]); this->v[0][2] = static_cast<DT>(mat[2]); 00405 this->v[1][0] = static_cast<DT>(mat[3]); this->v[1][1] = static_cast<DT>(mat[4]); this->v[1][2] = static_cast<DT>(mat[5]); 00406 this->v[2][0] = static_cast<DT>(mat[6]); this->v[2][1] = static_cast<DT>(mat[7]); this->v[2][2] = static_cast<DT>(mat[8]); 00407 } 00408 ML_CATCH_RETHROW; 00409 } 00410 00411 //-------------------------------------------------------------------- 00415 //-------------------------------------------------------------------- 00416 template <class DT> 00417 inline void Tmat3<DT>::getValues(float mat[9]) const 00418 { 00419 ML_TRACE_IN("Tmat3<DT>::setValues( )"); 00420 ML_TRY 00421 { 00422 mat[0] = static_cast<float>(this->v[0][0]); mat[1] = static_cast<float>(this->v[0][1]); mat[2] = static_cast<float>(this->v[0][2]); 00423 mat[3] = static_cast<float>(this->v[1][0]); mat[4] = static_cast<float>(this->v[1][1]); mat[5] = static_cast<float>(this->v[1][2]); 00424 mat[6] = static_cast<float>(this->v[2][0]); mat[7] = static_cast<float>(this->v[2][1]); mat[8] = static_cast<float>(this->v[2][2]); 00425 } 00426 ML_CATCH_RETHROW; 00427 } 00428 00429 //-------------------------------------------------------------------- 00431 //-------------------------------------------------------------------- 00432 template <class DT> 00433 inline void Tmat3<DT>::setValues(const double mat[9]) 00434 { 00435 ML_TRACE_IN("Tmat3<DT>::setValues( )"); 00436 ML_TRY 00437 { 00438 this->v[0][0] = static_cast<DT>(mat[0]); this->v[0][1] = static_cast<DT>(mat[1]); this->v[0][2] = static_cast<DT>(mat[2]); 00439 this->v[1][0] = static_cast<DT>(mat[3]); this->v[1][1] = static_cast<DT>(mat[4]); this->v[1][2] = static_cast<DT>(mat[5]); 00440 this->v[2][0] = static_cast<DT>(mat[6]); this->v[2][1] = static_cast<DT>(mat[7]); this->v[2][2] = static_cast<DT>(mat[8]); 00441 } 00442 ML_CATCH_RETHROW; 00443 } 00444 00445 //-------------------------------------------------------------------- 00449 //-------------------------------------------------------------------- 00450 template <class DT> 00451 inline void Tmat3<DT>::getValues(double mat[9]) const 00452 { 00453 ML_TRACE_IN("Tmat3<DT>::setValues( )"); 00454 ML_TRY 00455 { 00456 mat[0] = static_cast<double>(this->v[0][0]); mat[1] = static_cast<double>(this->v[0][1]); mat[2] = static_cast<double>(this->v[0][2]); 00457 mat[3] = static_cast<double>(this->v[1][0]); mat[4] = static_cast<double>(this->v[1][1]); mat[5] = static_cast<double>(this->v[1][2]); 00458 mat[6] = static_cast<double>(this->v[2][0]); mat[7] = static_cast<double>(this->v[2][1]); mat[8] = static_cast<double>(this->v[2][2]); 00459 } 00460 ML_CATCH_RETHROW; 00461 } 00462 00463 00464 //------------------------------------------------------------------- 00466 //------------------------------------------------------------------- 00467 template <class DT> 00468 inline void Tmat3<DT>::setScaleMatrix(const DT scale) 00469 { 00470 ML_TRACE_IN("Tmat3<DT>::setScaleMatrix( )"); 00471 00472 this->v[0][0]=scale; this->v[0][1]=0; this->v[0][2]=0; 00473 this->v[1][0]=0; this->v[1][1]=scale; this->v[1][2]=0; 00474 this->v[2][0]=0; this->v[2][1]=0; this->v[2][2]=scale; 00475 } 00477 00478 00479 //------------------------------------------------------------------- 00481 00482 //------------------------------------------------------------------- 00483 00485 #define DET3(A,B,C,D,E,F,G,H,I) ((A*E*I + B*F*G + C*D*H) - (A*F*H + B*D*I + C*E*G)) 00486 //------------------------------------------------------------------- 00488 //------------------------------------------------------------------- 00489 template <class DT> 00490 DT Tmat3<DT>::det() const 00491 { 00492 ML_TRACE_IN("Tmat3<DT>::det( )"); 00493 00494 return DET3(this->v[0][0], this->v[0][1], this->v[0][2], 00495 this->v[1][0], this->v[1][1], this->v[1][2], 00496 this->v[2][0], this->v[2][1], this->v[2][2]); 00497 } 00498 #undef DET3 00499 00500 //------------------------------------------------------------------- 00502 //------------------------------------------------------------------- 00503 template <class DT> 00504 inline Tmat3<DT> Tmat3<DT>::transpose() const 00505 { 00506 ML_TRACE_IN_TIME_CRITICAL("Tmat3<DT>::transpose()"); 00507 00508 return Tmat3<DT>(Tvec3<DT>(this->v[0][0], this->v[1][0], this->v[2][0]), 00509 Tvec3<DT>(this->v[0][1], this->v[1][1], this->v[2][1]), 00510 Tvec3<DT>(this->v[0][2], this->v[1][2], this->v[2][2])); 00511 } 00512 00513 //------------------------------------------------------------------- 00515 //------------------------------------------------------------------- 00516 template <class DT> 00517 inline Tmat3<DT> Tmat3<DT>::getIdentity() 00518 { 00519 ML_TRACE_IN_TIME_CRITICAL("Tmat3<DT>::getIdentity()"); 00520 00521 return Tmat3<DT>(Tvec3<DT>(1,0,0), 00522 Tvec3<DT>(0,1,0), 00523 Tvec3<DT>(0,0,1)); 00524 } 00525 00526 //------------------------------------------------------------------- 00528 //------------------------------------------------------------------- 00529 template <class DT> 00530 inline const Tmat3<DT> &Tmat3<DT>::apply(MLDblFuncPtr fct) 00531 { 00532 ML_TRACE_IN_TIME_CRITICAL("Tmat3<DT>::apply(MLDblFuncPtr fct)"); 00533 ML_TRY 00534 { 00535 this->v[0].apply(fct); 00536 this->v[1].apply(fct); 00537 this->v[2].apply(fct); 00538 } 00539 ML_CATCH_RETHROW; 00540 return *this; 00541 } 00542 00544 #define _ML_MAT3_RC(i, j) a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j] 00545 //------------------------------------------------------------------- 00547 //------------------------------------------------------------------- 00548 template <class DT> 00549 inline Tmat3<DT> operator*(const Tmat3<DT> &a, const Tmat3<DT> &b) 00550 { 00551 ML_TRACE_IN_TIME_CRITICAL("mlMatrix3.h: operator*(const Tmat3<DT> &a, const Tmat3<DT> &b)"); 00552 00553 return Tmat3<DT>(Tvec3<DT>(_ML_MAT3_RC(0,0), _ML_MAT3_RC(0,1), _ML_MAT3_RC(0,2)), 00554 Tvec3<DT>(_ML_MAT3_RC(1,0), _ML_MAT3_RC(1,1), _ML_MAT3_RC(1,2)), 00555 Tvec3<DT>(_ML_MAT3_RC(2,0), _ML_MAT3_RC(2,1), _ML_MAT3_RC(2,2))); 00556 00557 } 00558 #undef _ML_MAT3_RC 00559 00560 //------------------------------------------------------------------- 00562 //------------------------------------------------------------------- 00563 template <class DT> 00564 inline bool operator==(const Tmat3<DT> &a, const Tmat3<DT> &b) 00565 { 00566 ML_TRACE_IN_TIME_CRITICAL("mlMatrix3.h: operator==(const Tmat3<DT> &a, const Tmat3<DT> &b)"); 00567 00568 return (a[0] == b[0]) && 00569 (a[1] == b[1]) && 00570 (a[2] == b[2]); 00571 } 00572 00573 //------------------------------------------------------------------- 00575 //------------------------------------------------------------------- 00576 template <class DT> 00577 inline bool operator!=(const Tmat3<DT> &a, const Tmat3<DT> &b) 00578 { 00579 ML_TRACE_IN_TIME_CRITICAL("mlMatrix3.h: operator!=(const Tmat3<DT> &a, const Tmat3<DT> &b)"); 00580 00581 return !(a == b); 00582 } 00583 00584 //------------------------------------------------------------------- 00585 // 00586 // Special global 2D functions and 3D functions 00587 // 00588 //------------------------------------------------------------------- 00589 00590 //-------------------------------------------------------------------- 00593 //-------------------------------------------------------------------- 00594 template <class DT> 00595 Tmat3<DT> identity2D() 00596 { 00597 ML_TRACE_IN_TIME_CRITICAL("mlMatrix3.h: identity2D()"); 00598 00599 return Tmat3<DT>::getIdentity(); 00600 } 00601 00602 //------------------------------------------------------------------- 00605 //------------------------------------------------------------------- 00606 template <class DT> 00607 inline Tmat3<DT> translation2D(const Tvec2<DT> &v) 00608 { 00609 ML_TRACE_IN("mlMatrix3.h: translation2D(const Tvec2<DT> &v)"); 00610 00611 return Tmat3<DT>(Tvec3<DT>(1.0, 0.0, v[0]), 00612 Tvec3<DT>(0.0, 1.0, v[1]), 00613 Tvec3<DT>(0.0, 0.0, 1.0)); 00614 } 00615 00616 //------------------------------------------------------------------- 00619 //------------------------------------------------------------------- 00620 template <class DT> 00621 Tmat3<DT> rotation2D(const Tvec2<DT> &Center, const DT angleDeg) 00622 { 00623 ML_TRACE_IN("mlMatrix3.h: rotation2D(const Tvec2<DT> &Center, const DT angleDeg)"); 00624 00625 DT angleRad = angleDeg * M_PI / 180.0; 00626 DT c = cos(angleRad); 00627 DT s = sin(angleRad); 00628 00629 return Tmat3<DT>(Tvec3<DT>(c, -s, Center[0] * (1.0-c) + Center[1] * s), 00630 Tvec3<DT>(s, c, Center[1] * (1.0-c) - Center[0] * s), 00631 Tvec3<DT>(0.0, 0.0, 1.0)); 00632 } 00633 00634 //------------------------------------------------------------------- 00636 //------------------------------------------------------------------- 00637 template <class DT> 00638 inline Tmat3<DT> scaling2D(const Tvec2<DT> &scaleVector) 00639 { 00640 ML_TRACE_IN("mlMatrix3.h: scaling2D(const Tvec2<DT> &scaleVector)"); 00641 00642 return Tmat3<DT>(Tvec3<DT>(scaleVector[0], 0.0, 0.0), 00643 Tvec3<DT>(0.0, scaleVector[1], 0.0), 00644 Tvec3<DT>(0.0, 0.0, 1.0)); 00645 } 00646 00647 00648 00649 //------------------------------------------------------------------- 00661 //------------------------------------------------------------------- 00662 template <class DT> 00663 Tmat3<DT> Tmat3<DT>::jacobi(Tvec3<DT> &evalues, int &rots) const 00664 { 00665 ML_TRACE_IN("Tmat3<DT>::jacobi( )"); 00666 00667 Tmat3<DT> evectors (getIdentity()); 00668 ML_TRY 00669 { 00670 // TODO: Further documentation of the algorithm required! 00671 00672 DT sm = 0; // smallest entry 00673 DT theta = 0; // angle for Jacobi rotation 00674 DT c = 0, s = 0, t = 0; // cosine, sine, tangent of theta 00675 DT tau = 0; // sine / (1 + cos) 00676 DT h = 0, g = 0; // two scrap values 00677 DT thresh = 0; // threshold below which no rotation done 00678 00679 int p = 0, q = 0, i = 0, j = 0; 00680 00681 // Initialization 00682 Tvec3<DT> b (this->v[0][0], this->v[1][1], this->v[2][2]); // diagonal elements 00683 Tvec3<DT> z (0, 0, 0); 00684 evalues = b; 00685 00686 Tmat3<DT> a (*this); 00687 00688 rots = 0; 00689 for (i = 0; i < 50; i++){ // typical matrices require 6 to 10 sweeps to achieve convergence - hence 50 gives some safety margin 00690 sm = 0.0; 00691 for (p = 0; p < 2; p++){ 00692 for (q = p+1; q < 3; q++){ 00693 sm += ML_ABS(a.v[p][q]); // sum off-diagonal elements 00694 } 00695 } 00696 00697 if (sm == 0.0){ 00698 return evectors; 00699 } 00700 00701 thresh = (i < 3 ? (.2 * sm / 9) : 0.0); 00702 00703 for (p = 0; p < 2; p++) { 00704 for (q = p+1; q < 3; q++) { // compute on sweep, i.e. one rotation for each of-diagonal element of the matrix 00705 00706 g = 100.0 * ML_ABS(a.v[p][q]); 00707 00708 if ((i > 3) && 00709 (ML_ABS(evalues[p]) + g == ML_ABS(evalues[p])) && 00710 (ML_ABS(evalues[q]) + g == ML_ABS(evalues[q]))){ 00711 a.v[p][q] = 0.0; // after three sweeps, skip rotation of small off diagonal elements 00712 } 00713 else if (ML_ABS(a.v[p][q]) > thresh) { 00714 h = evalues[q] - evalues[p]; 00715 if (ML_ABS(h) + g == ML_ABS(h)){ 00716 t = a.v[p][q] / h; 00717 } 00718 else { 00719 theta = .5 * h / a.v[p][q]; 00720 t = 1.0 / (ML_ABS(theta) + sqrt(1 + theta * theta)); 00721 if (theta < 0.0){ 00722 t = -t; 00723 } 00724 } 00725 // End of computing tangent of rotation angle 00726 00727 c = 1.0 / sqrt(1.0 + t*t); 00728 s = t * c; 00729 tau = s / (1.0 + c); 00730 h = t * a.v[p][q]; 00731 z[p] -= h; 00732 z[q] += h; 00733 evalues[p] -= h; 00734 evalues[q] += h; 00735 a.v[p][q] = 0.0; 00736 00737 for (j = 0; j < p; j++) { 00738 g = a.v[j][p]; 00739 h = a.v[j][q]; 00740 a.v[j][p] = g - s * (h + g * tau); 00741 a.v[j][q] = h + s * (g - h * tau); 00742 } 00743 00744 for (j = p+1; j < q; j++) { 00745 g = a.v[p][j]; 00746 h = a.v[j][q]; 00747 a.v[p][j] = g - s * (h + g * tau); 00748 a.v[j][q] = h + s * (g - h * tau); 00749 } 00750 00751 for (j = q+1; j < 3; j++) { 00752 g = a.v[p][j]; 00753 h = a.v[q][j]; 00754 a.v[p][j] = g - s * (h + g * tau); 00755 a.v[q][j] = h + s * (g - h * tau); 00756 } 00757 00758 for (j = 0; j < 3; j++) { 00759 g = evectors.v[j][p]; 00760 h = evectors.v[j][q]; 00761 evectors.v[j][p] = g - s * (h + g * tau); 00762 evectors.v[j][q] = h + s * (g - h * tau); 00763 } 00764 } // else if (ML_ABS(a.v[p][q]) > thresh) 00765 00766 rots++; 00767 00768 } // for (q = p+1; q < 3; q++) 00769 } // for (p = 0; p < 2; p++) 00770 00771 for (p = 0; p < 3; p++) { 00772 evalues[p] = b[p] += z[p]; 00773 z[p] = 0; 00774 } 00775 00776 } // for (i = 0; i < 50; i++) 00777 ML_PRINT_ERROR("Tmat3 Tmat3<DT>::jacobi(Tvec3<DT> &evalues, int &rots) const, matrix not complete decomposed", 00778 ML_BAD_PARAMETER, 00779 "Returning incomplete decomposition"); 00780 } 00781 ML_CATCH_RETHROW; 00782 return evectors; 00783 } 00784 00785 //------------------------------------------------------------------- 00793 //------------------------------------------------------------------- 00794 template <class DT> 00795 Tmat3<DT> Tmat3<DT>::inverse(bool* isInvertible) const 00796 { 00797 ML_TRACE_IN("Tmat3<DT>::inverse( )"); 00798 00799 Tmat3<DT> retVal; 00800 ML_TRY 00801 { 00802 // Epsilon for comparison with 0 in inversion process. 00803 static const DT Epsilon = static_cast<DT>(0.); 00804 00805 // Use helper function from tools to invert the matrix. 00806 retVal = MLInverseMatHelper(*this, 00807 isInvertible, 00808 Epsilon, 00809 "Tmat3<DT> Tmat3<DT>::inverse(bool* isInvertible) const, matrix not invertable", 00810 getIdentity(), 00811 3); 00812 } 00813 ML_CATCH_RETHROW; 00814 return retVal; 00815 } 00816 00817 //----------------------------------------------------------------------------------- 00819 00820 //----------------------------------------------------------------------------------- 00821 00823 typedef Tmat3<MLfloat> Matrix3f; 00825 typedef Tmat3<MLdouble> Matrix3d; 00827 typedef Tmat3<MLldouble> Matrix3ld; 00829 typedef Tmat3<MLdouble> Matrix3; 00831 00832 00833 #ifdef ML_DEPRECATED 00834 00836 00837 00841 ML_DEPRECATED typedef Tmat3<MLfloat> matf3; 00845 ML_DEPRECATED typedef Tmat3<MLdouble> matd3; 00849 ML_DEPRECATED typedef Tmat3<MLldouble> matld3; 00853 ML_DEPRECATED typedef Tmat3<MLdouble> mat3; 00855 00856 00857 #endif // ML_DEPRECATED 00858 00859 00860 00861 ML_LA_END_NAMESPACE 00862 00863 namespace std 00864 { 00865 //------------------------------------------------------------------- 00867 //------------------------------------------------------------------- 00868 template <class DT> 00869 inline std::ostream &operator<<(std::ostream &os, const ML_LA_NAMESPACE::Tmat3<DT> &m) 00870 { 00871 return os << m[0] << '\n' << m[1] << '\n' << m[2]; 00872 } 00873 00874 //------------------------------------------------------------------- 00876 //------------------------------------------------------------------- 00877 template <class DT> 00878 inline std::istream &operator>>(std::istream &is, ML_LA_NAMESPACE::Tmat3<DT> &m) 00879 { 00880 ML_LA_NAMESPACE::Tmat3<DT> m_tmp; 00881 00882 is >> m_tmp[0] >> m_tmp[1] >> m_tmp[2]; 00883 if (is){ m = m_tmp; } 00884 return is; 00885 } 00886 } 00887 00888 00889 #endif // __mlMatrix3_H 00890 00891