00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 namespace Wm4
00018 {
00019
00020 template <class Real>
00021 Matrix3<Real>::Matrix3 (bool bZero)
00022 {
00023 if (bZero)
00024 {
00025 MakeZero();
00026 }
00027 else
00028 {
00029 MakeIdentity();
00030 }
00031 }
00032
00033 template <class Real>
00034 Matrix3<Real>::Matrix3 (const Matrix3& rkM)
00035 {
00036 m_afEntry[0] = rkM.m_afEntry[0];
00037 m_afEntry[1] = rkM.m_afEntry[1];
00038 m_afEntry[2] = rkM.m_afEntry[2];
00039 m_afEntry[3] = rkM.m_afEntry[3];
00040 m_afEntry[4] = rkM.m_afEntry[4];
00041 m_afEntry[5] = rkM.m_afEntry[5];
00042 m_afEntry[6] = rkM.m_afEntry[6];
00043 m_afEntry[7] = rkM.m_afEntry[7];
00044 m_afEntry[8] = rkM.m_afEntry[8];
00045 }
00046
00047 template <class Real>
00048 Matrix3<Real>::Matrix3 (Real fM00, Real fM01, Real fM02, Real fM10, Real fM11,
00049 Real fM12, Real fM20, Real fM21, Real fM22)
00050 {
00051 m_afEntry[0] = fM00;
00052 m_afEntry[1] = fM01;
00053 m_afEntry[2] = fM02;
00054 m_afEntry[3] = fM10;
00055 m_afEntry[4] = fM11;
00056 m_afEntry[5] = fM12;
00057 m_afEntry[6] = fM20;
00058 m_afEntry[7] = fM21;
00059 m_afEntry[8] = fM22;
00060 }
00061
00062 template <class Real>
00063 Matrix3<Real>::Matrix3 (const Real afEntry[9], bool bRowMajor)
00064 {
00065 if (bRowMajor)
00066 {
00067 m_afEntry[0] = afEntry[0];
00068 m_afEntry[1] = afEntry[1];
00069 m_afEntry[2] = afEntry[2];
00070 m_afEntry[3] = afEntry[3];
00071 m_afEntry[4] = afEntry[4];
00072 m_afEntry[5] = afEntry[5];
00073 m_afEntry[6] = afEntry[6];
00074 m_afEntry[7] = afEntry[7];
00075 m_afEntry[8] = afEntry[8];
00076 }
00077 else
00078 {
00079 m_afEntry[0] = afEntry[0];
00080 m_afEntry[1] = afEntry[3];
00081 m_afEntry[2] = afEntry[6];
00082 m_afEntry[3] = afEntry[1];
00083 m_afEntry[4] = afEntry[4];
00084 m_afEntry[5] = afEntry[7];
00085 m_afEntry[6] = afEntry[2];
00086 m_afEntry[7] = afEntry[5];
00087 m_afEntry[8] = afEntry[8];
00088 }
00089 }
00090
00091 template <class Real>
00092 Matrix3<Real>::Matrix3 (const Vector3<Real>& rkU, const Vector3<Real>& rkV,
00093 const Vector3<Real>& rkW, bool bColumns)
00094 {
00095 if (bColumns)
00096 {
00097 m_afEntry[0] = rkU[0];
00098 m_afEntry[1] = rkV[0];
00099 m_afEntry[2] = rkW[0];
00100 m_afEntry[3] = rkU[1];
00101 m_afEntry[4] = rkV[1];
00102 m_afEntry[5] = rkW[1];
00103 m_afEntry[6] = rkU[2];
00104 m_afEntry[7] = rkV[2];
00105 m_afEntry[8] = rkW[2];
00106 }
00107 else
00108 {
00109 m_afEntry[0] = rkU[0];
00110 m_afEntry[1] = rkU[1];
00111 m_afEntry[2] = rkU[2];
00112 m_afEntry[3] = rkV[0];
00113 m_afEntry[4] = rkV[1];
00114 m_afEntry[5] = rkV[2];
00115 m_afEntry[6] = rkW[0];
00116 m_afEntry[7] = rkW[1];
00117 m_afEntry[8] = rkW[2];
00118 }
00119 }
00120
00121 template <class Real>
00122 Matrix3<Real>::Matrix3 (const Vector3<Real>* akV, bool bColumns)
00123 {
00124 if (bColumns)
00125 {
00126 m_afEntry[0] = akV[0][0];
00127 m_afEntry[1] = akV[1][0];
00128 m_afEntry[2] = akV[2][0];
00129 m_afEntry[3] = akV[0][1];
00130 m_afEntry[4] = akV[1][1];
00131 m_afEntry[5] = akV[2][1];
00132 m_afEntry[6] = akV[0][2];
00133 m_afEntry[7] = akV[1][2];
00134 m_afEntry[8] = akV[2][2];
00135 }
00136 else
00137 {
00138 m_afEntry[0] = akV[0][0];
00139 m_afEntry[1] = akV[0][1];
00140 m_afEntry[2] = akV[0][2];
00141 m_afEntry[3] = akV[1][0];
00142 m_afEntry[4] = akV[1][1];
00143 m_afEntry[5] = akV[1][2];
00144 m_afEntry[6] = akV[2][0];
00145 m_afEntry[7] = akV[2][1];
00146 m_afEntry[8] = akV[2][2];
00147 }
00148 }
00149
00150 template <class Real>
00151 Matrix3<Real>::Matrix3 (Real fM00, Real fM11, Real fM22)
00152 {
00153 MakeDiagonal(fM00,fM11,fM22);
00154 }
00155
00156 template <class Real>
00157 Matrix3<Real>::Matrix3 (const Vector3<Real>& rkAxis, Real fAngle)
00158 {
00159 FromAxisAngle(rkAxis,fAngle);
00160 }
00161
00162 template <class Real>
00163 Matrix3<Real>::Matrix3 (const Vector3<Real>& rkU, const Vector3<Real>& rkV)
00164 {
00165 MakeTensorProduct(rkU,rkV);
00166 }
00167
00168 template <class Real>
00169 Matrix3<Real>::operator const Real* () const
00170 {
00171 return m_afEntry;
00172 }
00173
00174 template <class Real>
00175 Matrix3<Real>::operator Real* ()
00176 {
00177 return m_afEntry;
00178 }
00179
00180 template <class Real>
00181 const Real* Matrix3<Real>::operator[] (int iRow) const
00182 {
00183 return &m_afEntry[3*iRow];
00184 }
00185
00186 template <class Real>
00187 Real* Matrix3<Real>::operator[] (int iRow)
00188 {
00189 return &m_afEntry[3*iRow];
00190 }
00191
00192 template <class Real>
00193 Real Matrix3<Real>::operator() (int iRow, int iCol) const
00194 {
00195 return m_afEntry[iCol+3*iRow];
00196 }
00197
00198 template <class Real>
00199 Real& Matrix3<Real>::operator() (int iRow, int iCol)
00200 {
00201 return m_afEntry[iCol+3*iRow];
00202 }
00203
00204 template <class Real>
00205 Matrix3<Real>& Matrix3<Real>::MakeZero ()
00206 {
00207 m_afEntry[0] = (Real)0.0;
00208 m_afEntry[1] = (Real)0.0;
00209 m_afEntry[2] = (Real)0.0;
00210 m_afEntry[3] = (Real)0.0;
00211 m_afEntry[4] = (Real)0.0;
00212 m_afEntry[5] = (Real)0.0;
00213 m_afEntry[6] = (Real)0.0;
00214 m_afEntry[7] = (Real)0.0;
00215 m_afEntry[8] = (Real)0.0;
00216 return *this;
00217 }
00218
00219 template <class Real>
00220 Matrix3<Real>& Matrix3<Real>::MakeIdentity ()
00221 {
00222 m_afEntry[0] = (Real)1.0;
00223 m_afEntry[1] = (Real)0.0;
00224 m_afEntry[2] = (Real)0.0;
00225 m_afEntry[3] = (Real)0.0;
00226 m_afEntry[4] = (Real)1.0;
00227 m_afEntry[5] = (Real)0.0;
00228 m_afEntry[6] = (Real)0.0;
00229 m_afEntry[7] = (Real)0.0;
00230 m_afEntry[8] = (Real)1.0;
00231 return *this;
00232 }
00233
00234 template <class Real>
00235 Matrix3<Real>& Matrix3<Real>::MakeDiagonal (Real fM00, Real fM11, Real fM22)
00236 {
00237 m_afEntry[0] = fM00;
00238 m_afEntry[1] = (Real)0.0;
00239 m_afEntry[2] = (Real)0.0;
00240 m_afEntry[3] = (Real)0.0;
00241 m_afEntry[4] = fM11;
00242 m_afEntry[5] = (Real)0.0;
00243 m_afEntry[6] = (Real)0.0;
00244 m_afEntry[7] = (Real)0.0;
00245 m_afEntry[8] = fM22;
00246 return *this;
00247 }
00248
00249 template <class Real>
00250 Matrix3<Real>& Matrix3<Real>::FromAxisAngle (const Vector3<Real>& rkAxis,
00251 Real fAngle)
00252 {
00253 Real fCos = Math<Real>::Cos(fAngle);
00254 Real fSin = Math<Real>::Sin(fAngle);
00255 Real fOneMinusCos = ((Real)1.0)-fCos;
00256 Real fX2 = rkAxis[0]*rkAxis[0];
00257 Real fY2 = rkAxis[1]*rkAxis[1];
00258 Real fZ2 = rkAxis[2]*rkAxis[2];
00259 Real fXYM = rkAxis[0]*rkAxis[1]*fOneMinusCos;
00260 Real fXZM = rkAxis[0]*rkAxis[2]*fOneMinusCos;
00261 Real fYZM = rkAxis[1]*rkAxis[2]*fOneMinusCos;
00262 Real fXSin = rkAxis[0]*fSin;
00263 Real fYSin = rkAxis[1]*fSin;
00264 Real fZSin = rkAxis[2]*fSin;
00265
00266 m_afEntry[0] = fX2*fOneMinusCos+fCos;
00267 m_afEntry[1] = fXYM-fZSin;
00268 m_afEntry[2] = fXZM+fYSin;
00269 m_afEntry[3] = fXYM+fZSin;
00270 m_afEntry[4] = fY2*fOneMinusCos+fCos;
00271 m_afEntry[5] = fYZM-fXSin;
00272 m_afEntry[6] = fXZM-fYSin;
00273 m_afEntry[7] = fYZM+fXSin;
00274 m_afEntry[8] = fZ2*fOneMinusCos+fCos;
00275
00276 return *this;
00277 }
00278
00279 template <class Real>
00280 Matrix3<Real>& Matrix3<Real>::MakeTensorProduct (const Vector3<Real>& rkU,
00281 const Vector3<Real>& rkV)
00282 {
00283 m_afEntry[0] = rkU[0]*rkV[0];
00284 m_afEntry[1] = rkU[0]*rkV[1];
00285 m_afEntry[2] = rkU[0]*rkV[2];
00286 m_afEntry[3] = rkU[1]*rkV[0];
00287 m_afEntry[4] = rkU[1]*rkV[1];
00288 m_afEntry[5] = rkU[1]*rkV[2];
00289 m_afEntry[6] = rkU[2]*rkV[0];
00290 m_afEntry[7] = rkU[2]*rkV[1];
00291 m_afEntry[8] = rkU[2]*rkV[2];
00292 return *this;
00293 }
00294
00295 template <class Real>
00296 void Matrix3<Real>::SetRow (int iRow, const Vector3<Real>& rkV)
00297 {
00298 int i0 = 3*iRow, i1 = i0+1, i2 = i1+1;
00299 m_afEntry[i0] = rkV[0];
00300 m_afEntry[i1] = rkV[1];
00301 m_afEntry[i2] = rkV[2];
00302 }
00303
00304 template <class Real>
00305 Vector3<Real> Matrix3<Real>::GetRow (int iRow) const
00306 {
00307 int i0 = 3*iRow, i1 = i0+1, i2 = i1+1;
00308 return Vector3<Real>(m_afEntry[i0],m_afEntry[i1],m_afEntry[i2]);
00309 }
00310
00311 template <class Real>
00312 void Matrix3<Real>::SetColumn (int iCol, const Vector3<Real>& rkV)
00313 {
00314 m_afEntry[iCol] = rkV[0];
00315 m_afEntry[iCol+3] = rkV[1];
00316 m_afEntry[iCol+6] = rkV[2];
00317 }
00318
00319 template <class Real>
00320 Vector3<Real> Matrix3<Real>::GetColumn (int iCol) const
00321 {
00322 return Vector3<Real>(m_afEntry[iCol],m_afEntry[iCol+3],m_afEntry[iCol+6]);
00323 }
00324
00325 template <class Real>
00326 void Matrix3<Real>::GetColumnMajor (Real* afCMajor) const
00327 {
00328 afCMajor[0] = m_afEntry[0];
00329 afCMajor[1] = m_afEntry[3];
00330 afCMajor[2] = m_afEntry[6];
00331 afCMajor[3] = m_afEntry[1];
00332 afCMajor[4] = m_afEntry[4];
00333 afCMajor[5] = m_afEntry[7];
00334 afCMajor[6] = m_afEntry[2];
00335 afCMajor[7] = m_afEntry[5];
00336 afCMajor[8] = m_afEntry[8];
00337 }
00338
00339 template <class Real>
00340 Matrix3<Real>& Matrix3<Real>::operator= (const Matrix3& rkM)
00341 {
00342 m_afEntry[0] = rkM.m_afEntry[0];
00343 m_afEntry[1] = rkM.m_afEntry[1];
00344 m_afEntry[2] = rkM.m_afEntry[2];
00345 m_afEntry[3] = rkM.m_afEntry[3];
00346 m_afEntry[4] = rkM.m_afEntry[4];
00347 m_afEntry[5] = rkM.m_afEntry[5];
00348 m_afEntry[6] = rkM.m_afEntry[6];
00349 m_afEntry[7] = rkM.m_afEntry[7];
00350 m_afEntry[8] = rkM.m_afEntry[8];
00351 return *this;
00352 }
00353
00354 template <class Real>
00355 int Matrix3<Real>::CompareArrays (const Matrix3& rkM) const
00356 {
00357 return memcmp(m_afEntry,rkM.m_afEntry,9*sizeof(Real));
00358 }
00359
00360 template <class Real>
00361 bool Matrix3<Real>::operator== (const Matrix3& rkM) const
00362 {
00363 return CompareArrays(rkM) == 0;
00364 }
00365
00366 template <class Real>
00367 bool Matrix3<Real>::operator!= (const Matrix3& rkM) const
00368 {
00369 return CompareArrays(rkM) != 0;
00370 }
00371
00372 template <class Real>
00373 bool Matrix3<Real>::operator< (const Matrix3& rkM) const
00374 {
00375 return CompareArrays(rkM) < 0;
00376 }
00377
00378 template <class Real>
00379 bool Matrix3<Real>::operator<= (const Matrix3& rkM) const
00380 {
00381 return CompareArrays(rkM) <= 0;
00382 }
00383
00384 template <class Real>
00385 bool Matrix3<Real>::operator> (const Matrix3& rkM) const
00386 {
00387 return CompareArrays(rkM) > 0;
00388 }
00389
00390 template <class Real>
00391 bool Matrix3<Real>::operator>= (const Matrix3& rkM) const
00392 {
00393 return CompareArrays(rkM) >= 0;
00394 }
00395
00396 template <class Real>
00397 Matrix3<Real> Matrix3<Real>::operator+ (const Matrix3& rkM) const
00398 {
00399 return Matrix3<Real>(
00400 m_afEntry[0] + rkM.m_afEntry[0],
00401 m_afEntry[1] + rkM.m_afEntry[1],
00402 m_afEntry[2] + rkM.m_afEntry[2],
00403 m_afEntry[3] + rkM.m_afEntry[3],
00404 m_afEntry[4] + rkM.m_afEntry[4],
00405 m_afEntry[5] + rkM.m_afEntry[5],
00406 m_afEntry[6] + rkM.m_afEntry[6],
00407 m_afEntry[7] + rkM.m_afEntry[7],
00408 m_afEntry[8] + rkM.m_afEntry[8]);
00409 }
00410
00411 template <class Real>
00412 Matrix3<Real> Matrix3<Real>::operator- (const Matrix3& rkM) const
00413 {
00414 return Matrix3<Real>(
00415 m_afEntry[0] - rkM.m_afEntry[0],
00416 m_afEntry[1] - rkM.m_afEntry[1],
00417 m_afEntry[2] - rkM.m_afEntry[2],
00418 m_afEntry[3] - rkM.m_afEntry[3],
00419 m_afEntry[4] - rkM.m_afEntry[4],
00420 m_afEntry[5] - rkM.m_afEntry[5],
00421 m_afEntry[6] - rkM.m_afEntry[6],
00422 m_afEntry[7] - rkM.m_afEntry[7],
00423 m_afEntry[8] - rkM.m_afEntry[8]);
00424 }
00425
00426 template <class Real>
00427 Matrix3<Real> Matrix3<Real>::operator* (const Matrix3& rkM) const
00428 {
00429 return Matrix3<Real>(
00430 m_afEntry[0]*rkM.m_afEntry[0] +
00431 m_afEntry[1]*rkM.m_afEntry[3] +
00432 m_afEntry[2]*rkM.m_afEntry[6],
00433
00434 m_afEntry[0]*rkM.m_afEntry[1] +
00435 m_afEntry[1]*rkM.m_afEntry[4] +
00436 m_afEntry[2]*rkM.m_afEntry[7],
00437
00438 m_afEntry[0]*rkM.m_afEntry[2] +
00439 m_afEntry[1]*rkM.m_afEntry[5] +
00440 m_afEntry[2]*rkM.m_afEntry[8],
00441
00442 m_afEntry[3]*rkM.m_afEntry[0] +
00443 m_afEntry[4]*rkM.m_afEntry[3] +
00444 m_afEntry[5]*rkM.m_afEntry[6],
00445
00446 m_afEntry[3]*rkM.m_afEntry[1] +
00447 m_afEntry[4]*rkM.m_afEntry[4] +
00448 m_afEntry[5]*rkM.m_afEntry[7],
00449
00450 m_afEntry[3]*rkM.m_afEntry[2] +
00451 m_afEntry[4]*rkM.m_afEntry[5] +
00452 m_afEntry[5]*rkM.m_afEntry[8],
00453
00454 m_afEntry[6]*rkM.m_afEntry[0] +
00455 m_afEntry[7]*rkM.m_afEntry[3] +
00456 m_afEntry[8]*rkM.m_afEntry[6],
00457
00458 m_afEntry[6]*rkM.m_afEntry[1] +
00459 m_afEntry[7]*rkM.m_afEntry[4] +
00460 m_afEntry[8]*rkM.m_afEntry[7],
00461
00462 m_afEntry[6]*rkM.m_afEntry[2] +
00463 m_afEntry[7]*rkM.m_afEntry[5] +
00464 m_afEntry[8]*rkM.m_afEntry[8]);
00465 }
00466
00467 template <class Real>
00468 Matrix3<Real> Matrix3<Real>::operator* (Real fScalar) const
00469 {
00470 return Matrix3<Real>(
00471 fScalar*m_afEntry[0],
00472 fScalar*m_afEntry[1],
00473 fScalar*m_afEntry[2],
00474 fScalar*m_afEntry[3],
00475 fScalar*m_afEntry[4],
00476 fScalar*m_afEntry[5],
00477 fScalar*m_afEntry[6],
00478 fScalar*m_afEntry[7],
00479 fScalar*m_afEntry[8]);
00480 }
00481
00482 template <class Real>
00483 Matrix3<Real> Matrix3<Real>::operator/ (Real fScalar) const
00484 {
00485 if (fScalar != (Real)0.0)
00486 {
00487 Real fInvScalar = ((Real)1.0)/fScalar;
00488 return Matrix3<Real>(
00489 fInvScalar*m_afEntry[0],
00490 fInvScalar*m_afEntry[1],
00491 fInvScalar*m_afEntry[2],
00492 fInvScalar*m_afEntry[3],
00493 fInvScalar*m_afEntry[4],
00494 fInvScalar*m_afEntry[5],
00495 fInvScalar*m_afEntry[6],
00496 fInvScalar*m_afEntry[7],
00497 fInvScalar*m_afEntry[8]);
00498 }
00499
00500 return Matrix3<Real>(
00501 Math<Real>::MAX_REAL,
00502 Math<Real>::MAX_REAL,
00503 Math<Real>::MAX_REAL,
00504 Math<Real>::MAX_REAL,
00505 Math<Real>::MAX_REAL,
00506 Math<Real>::MAX_REAL,
00507 Math<Real>::MAX_REAL,
00508 Math<Real>::MAX_REAL,
00509 Math<Real>::MAX_REAL);
00510 }
00511
00512 template <class Real>
00513 Matrix3<Real> Matrix3<Real>::operator- () const
00514 {
00515 return Matrix3<Real>(
00516 -m_afEntry[0],
00517 -m_afEntry[1],
00518 -m_afEntry[2],
00519 -m_afEntry[3],
00520 -m_afEntry[4],
00521 -m_afEntry[5],
00522 -m_afEntry[6],
00523 -m_afEntry[7],
00524 -m_afEntry[8]);
00525 }
00526
00527 template <class Real>
00528 Matrix3<Real>& Matrix3<Real>::operator+= (const Matrix3& rkM)
00529 {
00530 m_afEntry[0] += rkM.m_afEntry[0];
00531 m_afEntry[1] += rkM.m_afEntry[1];
00532 m_afEntry[2] += rkM.m_afEntry[2];
00533 m_afEntry[3] += rkM.m_afEntry[3];
00534 m_afEntry[4] += rkM.m_afEntry[4];
00535 m_afEntry[5] += rkM.m_afEntry[5];
00536 m_afEntry[6] += rkM.m_afEntry[6];
00537 m_afEntry[7] += rkM.m_afEntry[7];
00538 m_afEntry[8] += rkM.m_afEntry[8];
00539 return *this;
00540 }
00541
00542 template <class Real>
00543 Matrix3<Real>& Matrix3<Real>::operator-= (const Matrix3& rkM)
00544 {
00545 m_afEntry[0] -= rkM.m_afEntry[0];
00546 m_afEntry[1] -= rkM.m_afEntry[1];
00547 m_afEntry[2] -= rkM.m_afEntry[2];
00548 m_afEntry[3] -= rkM.m_afEntry[3];
00549 m_afEntry[4] -= rkM.m_afEntry[4];
00550 m_afEntry[5] -= rkM.m_afEntry[5];
00551 m_afEntry[6] -= rkM.m_afEntry[6];
00552 m_afEntry[7] -= rkM.m_afEntry[7];
00553 m_afEntry[8] -= rkM.m_afEntry[8];
00554 return *this;
00555 }
00556
00557 template <class Real>
00558 Matrix3<Real>& Matrix3<Real>::operator*= (Real fScalar)
00559 {
00560 m_afEntry[0] *= fScalar;
00561 m_afEntry[1] *= fScalar;
00562 m_afEntry[2] *= fScalar;
00563 m_afEntry[3] *= fScalar;
00564 m_afEntry[4] *= fScalar;
00565 m_afEntry[5] *= fScalar;
00566 m_afEntry[6] *= fScalar;
00567 m_afEntry[7] *= fScalar;
00568 m_afEntry[8] *= fScalar;
00569 return *this;
00570 }
00571
00572 template <class Real>
00573 Matrix3<Real>& Matrix3<Real>::operator/= (Real fScalar)
00574 {
00575 if (fScalar != (Real)0.0)
00576 {
00577 Real fInvScalar = ((Real)1.0)/fScalar;
00578 m_afEntry[0] *= fInvScalar;
00579 m_afEntry[1] *= fInvScalar;
00580 m_afEntry[2] *= fInvScalar;
00581 m_afEntry[3] *= fInvScalar;
00582 m_afEntry[4] *= fInvScalar;
00583 m_afEntry[5] *= fInvScalar;
00584 m_afEntry[6] *= fInvScalar;
00585 m_afEntry[7] *= fInvScalar;
00586 m_afEntry[8] *= fInvScalar;
00587 }
00588 else
00589 {
00590 m_afEntry[0] = Math<Real>::MAX_REAL;
00591 m_afEntry[1] = Math<Real>::MAX_REAL;
00592 m_afEntry[2] = Math<Real>::MAX_REAL;
00593 m_afEntry[3] = Math<Real>::MAX_REAL;
00594 m_afEntry[4] = Math<Real>::MAX_REAL;
00595 m_afEntry[5] = Math<Real>::MAX_REAL;
00596 m_afEntry[6] = Math<Real>::MAX_REAL;
00597 m_afEntry[7] = Math<Real>::MAX_REAL;
00598 m_afEntry[8] = Math<Real>::MAX_REAL;
00599 }
00600
00601 return *this;
00602 }
00603
00604 template <class Real>
00605 Vector3<Real> Matrix3<Real>::operator* (const Vector3<Real>& rkV) const
00606 {
00607 return Vector3<Real>(
00608 m_afEntry[0]*rkV[0] + m_afEntry[1]*rkV[1] + m_afEntry[2]*rkV[2],
00609 m_afEntry[3]*rkV[0] + m_afEntry[4]*rkV[1] + m_afEntry[5]*rkV[2],
00610 m_afEntry[6]*rkV[0] + m_afEntry[7]*rkV[1] + m_afEntry[8]*rkV[2]);
00611 }
00612
00613 template <class Real>
00614 Matrix3<Real> Matrix3<Real>::Transpose () const
00615 {
00616 return Matrix3<Real>(
00617 m_afEntry[0],
00618 m_afEntry[3],
00619 m_afEntry[6],
00620 m_afEntry[1],
00621 m_afEntry[4],
00622 m_afEntry[7],
00623 m_afEntry[2],
00624 m_afEntry[5],
00625 m_afEntry[8]);
00626 }
00627
00628 template <class Real>
00629 Matrix3<Real> Matrix3<Real>::TransposeTimes (const Matrix3& rkM) const
00630 {
00631
00632 return Matrix3<Real>(
00633 m_afEntry[0]*rkM.m_afEntry[0] +
00634 m_afEntry[3]*rkM.m_afEntry[3] +
00635 m_afEntry[6]*rkM.m_afEntry[6],
00636
00637 m_afEntry[0]*rkM.m_afEntry[1] +
00638 m_afEntry[3]*rkM.m_afEntry[4] +
00639 m_afEntry[6]*rkM.m_afEntry[7],
00640
00641 m_afEntry[0]*rkM.m_afEntry[2] +
00642 m_afEntry[3]*rkM.m_afEntry[5] +
00643 m_afEntry[6]*rkM.m_afEntry[8],
00644
00645 m_afEntry[1]*rkM.m_afEntry[0] +
00646 m_afEntry[4]*rkM.m_afEntry[3] +
00647 m_afEntry[7]*rkM.m_afEntry[6],
00648
00649 m_afEntry[1]*rkM.m_afEntry[1] +
00650 m_afEntry[4]*rkM.m_afEntry[4] +
00651 m_afEntry[7]*rkM.m_afEntry[7],
00652
00653 m_afEntry[1]*rkM.m_afEntry[2] +
00654 m_afEntry[4]*rkM.m_afEntry[5] +
00655 m_afEntry[7]*rkM.m_afEntry[8],
00656
00657 m_afEntry[2]*rkM.m_afEntry[0] +
00658 m_afEntry[5]*rkM.m_afEntry[3] +
00659 m_afEntry[8]*rkM.m_afEntry[6],
00660
00661 m_afEntry[2]*rkM.m_afEntry[1] +
00662 m_afEntry[5]*rkM.m_afEntry[4] +
00663 m_afEntry[8]*rkM.m_afEntry[7],
00664
00665 m_afEntry[2]*rkM.m_afEntry[2] +
00666 m_afEntry[5]*rkM.m_afEntry[5] +
00667 m_afEntry[8]*rkM.m_afEntry[8]);
00668 }
00669
00670 template <class Real>
00671 Matrix3<Real> Matrix3<Real>::TimesTranspose (const Matrix3& rkM) const
00672 {
00673
00674 return Matrix3<Real>(
00675 m_afEntry[0]*rkM.m_afEntry[0] +
00676 m_afEntry[1]*rkM.m_afEntry[1] +
00677 m_afEntry[2]*rkM.m_afEntry[2],
00678
00679 m_afEntry[0]*rkM.m_afEntry[3] +
00680 m_afEntry[1]*rkM.m_afEntry[4] +
00681 m_afEntry[2]*rkM.m_afEntry[5],
00682
00683 m_afEntry[0]*rkM.m_afEntry[6] +
00684 m_afEntry[1]*rkM.m_afEntry[7] +
00685 m_afEntry[2]*rkM.m_afEntry[8],
00686
00687 m_afEntry[3]*rkM.m_afEntry[0] +
00688 m_afEntry[4]*rkM.m_afEntry[1] +
00689 m_afEntry[5]*rkM.m_afEntry[2],
00690
00691 m_afEntry[3]*rkM.m_afEntry[3] +
00692 m_afEntry[4]*rkM.m_afEntry[4] +
00693 m_afEntry[5]*rkM.m_afEntry[5],
00694
00695 m_afEntry[3]*rkM.m_afEntry[6] +
00696 m_afEntry[4]*rkM.m_afEntry[7] +
00697 m_afEntry[5]*rkM.m_afEntry[8],
00698
00699 m_afEntry[6]*rkM.m_afEntry[0] +
00700 m_afEntry[7]*rkM.m_afEntry[1] +
00701 m_afEntry[8]*rkM.m_afEntry[2],
00702
00703 m_afEntry[6]*rkM.m_afEntry[3] +
00704 m_afEntry[7]*rkM.m_afEntry[4] +
00705 m_afEntry[8]*rkM.m_afEntry[5],
00706
00707 m_afEntry[6]*rkM.m_afEntry[6] +
00708 m_afEntry[7]*rkM.m_afEntry[7] +
00709 m_afEntry[8]*rkM.m_afEntry[8]);
00710 }
00711
00712 template <class Real>
00713 Matrix3<Real> Matrix3<Real>::Inverse () const
00714 {
00715
00716
00717
00718 Matrix3 kInverse;
00719
00720 kInverse.m_afEntry[0] =
00721 m_afEntry[4]*m_afEntry[8] - m_afEntry[5]*m_afEntry[7];
00722 kInverse.m_afEntry[1] =
00723 m_afEntry[2]*m_afEntry[7] - m_afEntry[1]*m_afEntry[8];
00724 kInverse.m_afEntry[2] =
00725 m_afEntry[1]*m_afEntry[5] - m_afEntry[2]*m_afEntry[4];
00726 kInverse.m_afEntry[3] =
00727 m_afEntry[5]*m_afEntry[6] - m_afEntry[3]*m_afEntry[8];
00728 kInverse.m_afEntry[4] =
00729 m_afEntry[0]*m_afEntry[8] - m_afEntry[2]*m_afEntry[6];
00730 kInverse.m_afEntry[5] =
00731 m_afEntry[2]*m_afEntry[3] - m_afEntry[0]*m_afEntry[5];
00732 kInverse.m_afEntry[6] =
00733 m_afEntry[3]*m_afEntry[7] - m_afEntry[4]*m_afEntry[6];
00734 kInverse.m_afEntry[7] =
00735 m_afEntry[1]*m_afEntry[6] - m_afEntry[0]*m_afEntry[7];
00736 kInverse.m_afEntry[8] =
00737 m_afEntry[0]*m_afEntry[4] - m_afEntry[1]*m_afEntry[3];
00738
00739 Real fDet =
00740 m_afEntry[0]*kInverse.m_afEntry[0] +
00741 m_afEntry[1]*kInverse.m_afEntry[3] +
00742 m_afEntry[2]*kInverse.m_afEntry[6];
00743
00744 if (Math<Real>::FAbs(fDet) <= Math<Real>::ZERO_TOLERANCE)
00745 {
00746 return ZERO;
00747 }
00748
00749 Real fInvDet = ((Real)1.0)/fDet;
00750 kInverse.m_afEntry[0] *= fInvDet;
00751 kInverse.m_afEntry[1] *= fInvDet;
00752 kInverse.m_afEntry[2] *= fInvDet;
00753 kInverse.m_afEntry[3] *= fInvDet;
00754 kInverse.m_afEntry[4] *= fInvDet;
00755 kInverse.m_afEntry[5] *= fInvDet;
00756 kInverse.m_afEntry[6] *= fInvDet;
00757 kInverse.m_afEntry[7] *= fInvDet;
00758 kInverse.m_afEntry[8] *= fInvDet;
00759 return kInverse;
00760 }
00761
00762 template <class Real>
00763 Matrix3<Real> Matrix3<Real>::Adjoint () const
00764 {
00765 return Matrix3<Real>(
00766 m_afEntry[4]*m_afEntry[8] - m_afEntry[5]*m_afEntry[7],
00767 m_afEntry[2]*m_afEntry[7] - m_afEntry[1]*m_afEntry[8],
00768 m_afEntry[1]*m_afEntry[5] - m_afEntry[2]*m_afEntry[4],
00769 m_afEntry[5]*m_afEntry[6] - m_afEntry[3]*m_afEntry[8],
00770 m_afEntry[0]*m_afEntry[8] - m_afEntry[2]*m_afEntry[6],
00771 m_afEntry[2]*m_afEntry[3] - m_afEntry[0]*m_afEntry[5],
00772 m_afEntry[3]*m_afEntry[7] - m_afEntry[4]*m_afEntry[6],
00773 m_afEntry[1]*m_afEntry[6] - m_afEntry[0]*m_afEntry[7],
00774 m_afEntry[0]*m_afEntry[4] - m_afEntry[1]*m_afEntry[3]);
00775 }
00776
00777 template <class Real>
00778 Real Matrix3<Real>::Determinant () const
00779 {
00780 Real fCo00 = m_afEntry[4]*m_afEntry[8] - m_afEntry[5]*m_afEntry[7];
00781 Real fCo10 = m_afEntry[5]*m_afEntry[6] - m_afEntry[3]*m_afEntry[8];
00782 Real fCo20 = m_afEntry[3]*m_afEntry[7] - m_afEntry[4]*m_afEntry[6];
00783 Real fDet = m_afEntry[0]*fCo00 + m_afEntry[1]*fCo10 + m_afEntry[2]*fCo20;
00784 return fDet;
00785 }
00786
00787 template <class Real>
00788 Real Matrix3<Real>::QForm (const Vector3<Real>& rkU, const Vector3<Real>& rkV)
00789 const
00790 {
00791 return rkU.Dot((*this)*rkV);
00792 }
00793
00794 template <class Real>
00795 Matrix3<Real> Matrix3<Real>::TimesDiagonal (const Vector3<Real>& rkDiag) const
00796 {
00797 return Matrix3<Real>(
00798 m_afEntry[0]*rkDiag[0],m_afEntry[1]*rkDiag[1],m_afEntry[2]*rkDiag[2],
00799 m_afEntry[3]*rkDiag[0],m_afEntry[4]*rkDiag[1],m_afEntry[5]*rkDiag[2],
00800 m_afEntry[6]*rkDiag[0],m_afEntry[7]*rkDiag[1],m_afEntry[8]*rkDiag[2]);
00801 }
00802
00803 template <class Real>
00804 Matrix3<Real> Matrix3<Real>::DiagonalTimes (const Vector3<Real>& rkDiag) const
00805 {
00806 return Matrix3<Real>(
00807 rkDiag[0]*m_afEntry[0],rkDiag[0]*m_afEntry[1],rkDiag[0]*m_afEntry[2],
00808 rkDiag[1]*m_afEntry[3],rkDiag[1]*m_afEntry[4],rkDiag[1]*m_afEntry[5],
00809 rkDiag[2]*m_afEntry[6],rkDiag[2]*m_afEntry[7],rkDiag[2]*m_afEntry[8]);
00810 }
00811
00812 template <class Real>
00813 void Matrix3<Real>::ToAxisAngle (Vector3<Real>& rkAxis, Real& rfAngle) const
00814 {
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837 Real fTrace = m_afEntry[0] + m_afEntry[4] + m_afEntry[8];
00838 Real fCos = ((Real)0.5)*(fTrace-(Real)1.0);
00839 rfAngle = Math<Real>::ACos(fCos);
00840
00841 if (rfAngle > (Real)0.0)
00842 {
00843 if (rfAngle < Math<Real>::PI)
00844 {
00845 rkAxis[0] = m_afEntry[7]-m_afEntry[5];
00846 rkAxis[1] = m_afEntry[2]-m_afEntry[6];
00847 rkAxis[2] = m_afEntry[3]-m_afEntry[1];
00848 rkAxis.Normalize();
00849 }
00850 else
00851 {
00852
00853 Real fHalfInverse;
00854 if (m_afEntry[0] >= m_afEntry[4])
00855 {
00856
00857 if (m_afEntry[0] >= m_afEntry[8])
00858 {
00859
00860 rkAxis[0] = ((Real)0.5)*Math<Real>::Sqrt(m_afEntry[0] -
00861 m_afEntry[4] - m_afEntry[8] + (Real)1.0);
00862 fHalfInverse = ((Real)0.5)/rkAxis[0];
00863 rkAxis[1] = fHalfInverse*m_afEntry[1];
00864 rkAxis[2] = fHalfInverse*m_afEntry[2];
00865 }
00866 else
00867 {
00868
00869 rkAxis[2] = ((Real)0.5)*Math<Real>::Sqrt(m_afEntry[8] -
00870 m_afEntry[0] - m_afEntry[4] + (Real)1.0);
00871 fHalfInverse = ((Real)0.5)/rkAxis[2];
00872 rkAxis[0] = fHalfInverse*m_afEntry[2];
00873 rkAxis[1] = fHalfInverse*m_afEntry[5];
00874 }
00875 }
00876 else
00877 {
00878
00879 if (m_afEntry[4] >= m_afEntry[8])
00880 {
00881
00882 rkAxis[1] = ((Real)0.5)*Math<Real>::Sqrt(m_afEntry[4] -
00883 m_afEntry[0] - m_afEntry[8] + (Real)1.0);
00884 fHalfInverse = ((Real)0.5)/rkAxis[1];
00885 rkAxis[0] = fHalfInverse*m_afEntry[1];
00886 rkAxis[2] = fHalfInverse*m_afEntry[5];
00887 }
00888 else
00889 {
00890
00891 rkAxis[2] = ((Real)0.5)*Math<Real>::Sqrt(m_afEntry[8] -
00892 m_afEntry[0] - m_afEntry[4] + (Real)1.0);
00893 fHalfInverse = ((Real)0.5)/rkAxis[2];
00894 rkAxis[0] = fHalfInverse*m_afEntry[2];
00895 rkAxis[1] = fHalfInverse*m_afEntry[5];
00896 }
00897 }
00898 }
00899 }
00900 else
00901 {
00902
00903
00904 rkAxis[0] = (Real)1.0;
00905 rkAxis[1] = (Real)0.0;
00906 rkAxis[2] = (Real)0.0;
00907 }
00908 }
00909
00910 template <class Real>
00911 void Matrix3<Real>::Orthonormalize ()
00912 {
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924 Real fInvLength = Math<Real>::InvSqrt(m_afEntry[0]*m_afEntry[0] +
00925 m_afEntry[3]*m_afEntry[3] + m_afEntry[6]*m_afEntry[6]);
00926
00927 m_afEntry[0] *= fInvLength;
00928 m_afEntry[3] *= fInvLength;
00929 m_afEntry[6] *= fInvLength;
00930
00931
00932 Real fDot0 = m_afEntry[0]*m_afEntry[1] + m_afEntry[3]*m_afEntry[4] +
00933 m_afEntry[6]*m_afEntry[7];
00934
00935 m_afEntry[1] -= fDot0*m_afEntry[0];
00936 m_afEntry[4] -= fDot0*m_afEntry[3];
00937 m_afEntry[7] -= fDot0*m_afEntry[6];
00938
00939 fInvLength = Math<Real>::InvSqrt(m_afEntry[1]*m_afEntry[1] +
00940 m_afEntry[4]*m_afEntry[4] + m_afEntry[7]*m_afEntry[7]);
00941
00942 m_afEntry[1] *= fInvLength;
00943 m_afEntry[4] *= fInvLength;
00944 m_afEntry[7] *= fInvLength;
00945
00946
00947 Real fDot1 = m_afEntry[1]*m_afEntry[2] + m_afEntry[4]*m_afEntry[5] +
00948 m_afEntry[7]*m_afEntry[8];
00949
00950 fDot0 = m_afEntry[0]*m_afEntry[2] + m_afEntry[3]*m_afEntry[5] +
00951 m_afEntry[6]*m_afEntry[8];
00952
00953 m_afEntry[2] -= fDot0*m_afEntry[0] + fDot1*m_afEntry[1];
00954 m_afEntry[5] -= fDot0*m_afEntry[3] + fDot1*m_afEntry[4];
00955 m_afEntry[8] -= fDot0*m_afEntry[6] + fDot1*m_afEntry[7];
00956
00957 fInvLength = Math<Real>::InvSqrt(m_afEntry[2]*m_afEntry[2] +
00958 m_afEntry[5]*m_afEntry[5] + m_afEntry[8]*m_afEntry[8]);
00959
00960 m_afEntry[2] *= fInvLength;
00961 m_afEntry[5] *= fInvLength;
00962 m_afEntry[8] *= fInvLength;
00963 }
00964
00965 template <class Real>
00966 void Matrix3<Real>::EigenDecomposition (Matrix3& rkRot, Matrix3& rkDiag) const
00967 {
00968
00969
00970 Real afDiag[3], afSubd[2];
00971 rkRot = *this;
00972 bool bReflection = rkRot.Tridiagonalize(afDiag,afSubd);
00973 bool bConverged = rkRot.QLAlgorithm(afDiag,afSubd);
00974 if (!bConverged) throw std::exception();
00975 assert(bConverged);
00976
00977
00978 int i;
00979 Real fSave;
00980
00981 if (afDiag[1] < afDiag[0])
00982 {
00983
00984 fSave = afDiag[0];
00985 afDiag[0] = afDiag[1];
00986 afDiag[1] = fSave;
00987
00988
00989 for (i = 0; i < 3; i++)
00990 {
00991 fSave = rkRot[i][0];
00992 rkRot[i][0] = rkRot[i][1];
00993 rkRot[i][1] = fSave;
00994 }
00995 bReflection = !bReflection;
00996 }
00997
00998 if (afDiag[2] < afDiag[1])
00999 {
01000
01001 fSave = afDiag[1];
01002 afDiag[1] = afDiag[2];
01003 afDiag[2] = fSave;
01004
01005
01006 for (i = 0; i < 3; i++)
01007 {
01008 fSave = rkRot[i][1];
01009 rkRot[i][1] = rkRot[i][2];
01010 rkRot[i][2] = fSave;
01011 }
01012 bReflection = !bReflection;
01013 }
01014
01015 if (afDiag[1] < afDiag[0])
01016 {
01017
01018 fSave = afDiag[0];
01019 afDiag[0] = afDiag[1];
01020 afDiag[1] = fSave;
01021
01022
01023 for (i = 0; i < 3; i++)
01024 {
01025 fSave = rkRot[i][0];
01026 rkRot[i][0] = rkRot[i][1];
01027 rkRot[i][1] = fSave;
01028 }
01029 bReflection = !bReflection;
01030 }
01031
01032 rkDiag.MakeDiagonal(afDiag[0],afDiag[1],afDiag[2]);
01033
01034 if (bReflection)
01035 {
01036
01037
01038
01039 rkRot[0][2] = -rkRot[0][2];
01040 rkRot[1][2] = -rkRot[1][2];
01041 rkRot[2][2] = -rkRot[2][2];
01042 }
01043 }
01044
01045 template <class Real>
01046 Matrix3<Real>& Matrix3<Real>::FromEulerAnglesXYZ (Real fXAngle, Real fYAngle,
01047 Real fZAngle)
01048 {
01049 Real fCos, fSin;
01050
01051 fCos = Math<Real>::Cos(fXAngle);
01052 fSin = Math<Real>::Sin(fXAngle);
01053 Matrix3 kXMat(
01054 (Real)1.0,(Real)0.0,(Real)0.0,
01055 (Real)0.0,fCos,-fSin,
01056 (Real)0.0,fSin,fCos);
01057
01058 fCos = Math<Real>::Cos(fYAngle);
01059 fSin = Math<Real>::Sin(fYAngle);
01060 Matrix3 kYMat(
01061 fCos,(Real)0.0,fSin,
01062 (Real)0.0,(Real)1.0,(Real)0.0,
01063 -fSin,(Real)0.0,fCos);
01064
01065 fCos = Math<Real>::Cos(fZAngle);
01066 fSin = Math<Real>::Sin(fZAngle);
01067 Matrix3 kZMat(
01068 fCos,-fSin,(Real)0.0,
01069 fSin,fCos,(Real)0.0,
01070 (Real)0.0,(Real)0.0,(Real)1.0);
01071
01072 *this = kXMat*(kYMat*kZMat);
01073 return *this;
01074 }
01075
01076 template <class Real>
01077 Matrix3<Real>& Matrix3<Real>::FromEulerAnglesXZY (Real fXAngle, Real fZAngle,
01078 Real fYAngle)
01079 {
01080 Real fCos, fSin;
01081
01082 fCos = Math<Real>::Cos(fXAngle);
01083 fSin = Math<Real>::Sin(fXAngle);
01084 Matrix3 kXMat(
01085 (Real)1.0,(Real)0.0,(Real)0.0,
01086 (Real)0.0,fCos,-fSin,
01087 (Real)0.0,fSin,fCos);
01088
01089 fCos = Math<Real>::Cos(fZAngle);
01090 fSin = Math<Real>::Sin(fZAngle);
01091 Matrix3 kZMat(
01092 fCos,-fSin,(Real)0.0,
01093 fSin,fCos,(Real)0.0,
01094 (Real)0.0,(Real)0.0,(Real)1.0);
01095
01096 fCos = Math<Real>::Cos(fYAngle);
01097 fSin = Math<Real>::Sin(fYAngle);
01098 Matrix3 kYMat(
01099 fCos,(Real)0.0,fSin,
01100 (Real)0.0,(Real)1.0,(Real)0.0,
01101 -fSin,(Real)0.0,fCos);
01102
01103 *this = kXMat*(kZMat*kYMat);
01104 return *this;
01105 }
01106
01107 template <class Real>
01108 Matrix3<Real>& Matrix3<Real>::FromEulerAnglesYXZ (Real fYAngle, Real fXAngle,
01109 Real fZAngle)
01110 {
01111 Real fCos, fSin;
01112
01113 fCos = Math<Real>::Cos(fYAngle);
01114 fSin = Math<Real>::Sin(fYAngle);
01115 Matrix3 kYMat(
01116 fCos,(Real)0.0,fSin,
01117 (Real)0.0,(Real)1.0,(Real)0.0,
01118 -fSin,(Real)0.0,fCos);
01119
01120 fCos = Math<Real>::Cos(fXAngle);
01121 fSin = Math<Real>::Sin(fXAngle);
01122 Matrix3 kXMat(
01123 (Real)1.0,(Real)0.0,(Real)0.0,
01124 (Real)0.0,fCos,-fSin,
01125 (Real)0.0,fSin,fCos);
01126
01127 fCos = Math<Real>::Cos(fZAngle);
01128 fSin = Math<Real>::Sin(fZAngle);
01129 Matrix3 kZMat(
01130 fCos,-fSin,(Real)0.0,
01131 fSin,fCos,(Real)0.0,
01132 (Real)0.0,(Real)0.0,(Real)1.0);
01133
01134 *this = kYMat*(kXMat*kZMat);
01135 return *this;
01136 }
01137
01138 template <class Real>
01139 Matrix3<Real>& Matrix3<Real>::FromEulerAnglesYZX (Real fYAngle, Real fZAngle,
01140 Real fXAngle)
01141 {
01142 Real fCos, fSin;
01143
01144 fCos = Math<Real>::Cos(fYAngle);
01145 fSin = Math<Real>::Sin(fYAngle);
01146 Matrix3 kYMat(
01147 fCos,(Real)0.0,fSin,
01148 (Real)0.0,(Real)1.0,(Real)0.0,
01149 -fSin,(Real)0.0,fCos);
01150
01151 fCos = Math<Real>::Cos(fZAngle);
01152 fSin = Math<Real>::Sin(fZAngle);
01153 Matrix3 kZMat(
01154 fCos,-fSin,(Real)0.0,
01155 fSin,fCos,(Real)0.0,
01156 (Real)0.0,(Real)0.0,(Real)1.0);
01157
01158 fCos = Math<Real>::Cos(fXAngle);
01159 fSin = Math<Real>::Sin(fXAngle);
01160 Matrix3 kXMat(
01161 (Real)1.0,(Real)0.0,(Real)0.0,
01162 (Real)0.0,fCos,-fSin,
01163 (Real)0.0,fSin,fCos);
01164
01165 *this = kYMat*(kZMat*kXMat);
01166 return *this;
01167 }
01168
01169 template <class Real>
01170 Matrix3<Real>& Matrix3<Real>::FromEulerAnglesZXY (Real fZAngle, Real fXAngle,
01171 Real fYAngle)
01172 {
01173 Real fCos, fSin;
01174
01175 fCos = Math<Real>::Cos(fZAngle);
01176 fSin = Math<Real>::Sin(fZAngle);
01177 Matrix3 kZMat(
01178 fCos,-fSin,(Real)0.0,
01179 fSin,fCos,(Real)0.0,
01180 (Real)0.0,(Real)0.0,(Real)1.0);
01181
01182 fCos = Math<Real>::Cos(fXAngle);
01183 fSin = Math<Real>::Sin(fXAngle);
01184 Matrix3 kXMat(
01185 (Real)1.0,(Real)0.0,(Real)0.0,
01186 (Real)0.0,fCos,-fSin,
01187 (Real)0.0,fSin,fCos);
01188
01189 fCos = Math<Real>::Cos(fYAngle);
01190 fSin = Math<Real>::Sin(fYAngle);
01191 Matrix3 kYMat(
01192 fCos,(Real)0.0,fSin,
01193 (Real)0.0,(Real)1.0,(Real)0.0,
01194 -fSin,(Real)0.0,fCos);
01195
01196 *this = kZMat*(kXMat*kYMat);
01197 return *this;
01198 }
01199
01200 template <class Real>
01201 Matrix3<Real>& Matrix3<Real>::FromEulerAnglesZYX (Real fZAngle, Real fYAngle,
01202 Real fXAngle)
01203 {
01204 Real fCos, fSin;
01205
01206 fCos = Math<Real>::Cos(fZAngle);
01207 fSin = Math<Real>::Sin(fZAngle);
01208 Matrix3 kZMat(
01209 fCos,-fSin,(Real)0.0,
01210 fSin,fCos,(Real)0.0,
01211 (Real)0.0,(Real)0.0,(Real)1.0);
01212
01213 fCos = Math<Real>::Cos(fYAngle);
01214 fSin = Math<Real>::Sin(fYAngle);
01215 Matrix3 kYMat(
01216 fCos,(Real)0.0,fSin,
01217 (Real)0.0,(Real)1.0,(Real)0.0,
01218 -fSin,(Real)0.0,fCos);
01219
01220 fCos = Math<Real>::Cos(fXAngle);
01221 fSin = Math<Real>::Sin(fXAngle);
01222 Matrix3 kXMat(
01223 (Real)1.0,(Real)0.0,(Real)0.0,
01224 (Real)0.0,fCos,-fSin,
01225 (Real)0.0,fSin,fCos);
01226
01227 *this = kZMat*(kYMat*kXMat);
01228 return *this;
01229 }
01230
01231 template <class Real>
01232 bool Matrix3<Real>::ToEulerAnglesXYZ (Real& rfXAngle, Real& rfYAngle,
01233 Real& rfZAngle) const
01234 {
01235
01236
01237
01238
01239 if (m_afEntry[2] < (Real)1.0)
01240 {
01241 if (m_afEntry[2] > -(Real)1.0)
01242 {
01243 rfXAngle = Math<Real>::ATan2(-m_afEntry[5],m_afEntry[8]);
01244 rfYAngle = (Real)asin((double)m_afEntry[2]);
01245 rfZAngle = Math<Real>::ATan2(-m_afEntry[1],m_afEntry[0]);
01246 return true;
01247 }
01248 else
01249 {
01250
01251 rfXAngle = -Math<Real>::ATan2(m_afEntry[3],m_afEntry[4]);
01252 rfYAngle = -Math<Real>::HALF_PI;
01253 rfZAngle = (Real)0.0;
01254 return false;
01255 }
01256 }
01257 else
01258 {
01259
01260 rfXAngle = Math<Real>::ATan2(m_afEntry[3],m_afEntry[4]);
01261 rfYAngle = Math<Real>::HALF_PI;
01262 rfZAngle = (Real)0.0;
01263 return false;
01264 }
01265 }
01266
01267 template <class Real>
01268 bool Matrix3<Real>::ToEulerAnglesXZY (Real& rfXAngle, Real& rfZAngle,
01269 Real& rfYAngle) const
01270 {
01271
01272
01273
01274
01275 if (m_afEntry[1] < (Real)1.0)
01276 {
01277 if (m_afEntry[1] > -(Real)1.0)
01278 {
01279 rfXAngle = Math<Real>::ATan2(m_afEntry[7],m_afEntry[4]);
01280 rfZAngle = (Real)asin(-(double)m_afEntry[1]);
01281 rfYAngle = Math<Real>::ATan2(m_afEntry[2],m_afEntry[0]);
01282 return true;
01283 }
01284 else
01285 {
01286
01287 rfXAngle = Math<Real>::ATan2(m_afEntry[6],m_afEntry[8]);
01288 rfZAngle = Math<Real>::HALF_PI;
01289 rfYAngle = (Real)0.0;
01290 return false;
01291 }
01292 }
01293 else
01294 {
01295
01296 rfXAngle = Math<Real>::ATan2(-m_afEntry[6],m_afEntry[8]);
01297 rfZAngle = -Math<Real>::HALF_PI;
01298 rfYAngle = (Real)0.0;
01299 return false;
01300 }
01301 }
01302
01303 template <class Real>
01304 bool Matrix3<Real>::ToEulerAnglesYXZ (Real& rfYAngle, Real& rfXAngle,
01305 Real& rfZAngle) const
01306 {
01307
01308
01309
01310
01311 if (m_afEntry[5] < (Real)1.0)
01312 {
01313 if (m_afEntry[5] > -(Real)1.0)
01314 {
01315 rfYAngle = Math<Real>::ATan2(m_afEntry[2],m_afEntry[8]);
01316 rfXAngle = (Real)asin(-(double)m_afEntry[5]);
01317 rfZAngle = Math<Real>::ATan2(m_afEntry[3],m_afEntry[4]);
01318 return true;
01319 }
01320 else
01321 {
01322
01323 rfYAngle = Math<Real>::ATan2(m_afEntry[1],m_afEntry[0]);
01324 rfXAngle = Math<Real>::HALF_PI;
01325 rfZAngle = (Real)0.0;
01326 return false;
01327 }
01328 }
01329 else
01330 {
01331
01332 rfYAngle = Math<Real>::ATan2(-m_afEntry[1],m_afEntry[0]);
01333 rfXAngle = -Math<Real>::HALF_PI;
01334 rfZAngle = (Real)0.0;
01335 return false;
01336 }
01337 }
01338
01339 template <class Real>
01340 bool Matrix3<Real>::ToEulerAnglesYZX (Real& rfYAngle, Real& rfZAngle,
01341 Real& rfXAngle) const
01342 {
01343
01344
01345
01346
01347 if (m_afEntry[3] < (Real)1.0)
01348 {
01349 if (m_afEntry[3] > -(Real)1.0)
01350 {
01351 rfYAngle = Math<Real>::ATan2(-m_afEntry[6],m_afEntry[0]);
01352 rfZAngle = (Real)asin((double)m_afEntry[3]);
01353 rfXAngle = Math<Real>::ATan2(-m_afEntry[5],m_afEntry[4]);
01354 return true;
01355 }
01356 else
01357 {
01358
01359 rfYAngle = -Math<Real>::ATan2(m_afEntry[7],m_afEntry[8]);
01360 rfZAngle = -Math<Real>::HALF_PI;
01361 rfXAngle = (Real)0.0;
01362 return false;
01363 }
01364 }
01365 else
01366 {
01367
01368 rfYAngle = Math<Real>::ATan2(m_afEntry[7],m_afEntry[8]);
01369 rfZAngle = Math<Real>::HALF_PI;
01370 rfXAngle = (Real)0.0;
01371 return false;
01372 }
01373 }
01374
01375 template <class Real>
01376 bool Matrix3<Real>::ToEulerAnglesZXY (Real& rfZAngle, Real& rfXAngle,
01377 Real& rfYAngle) const
01378 {
01379
01380
01381
01382
01383 if (m_afEntry[7] < (Real)1.0)
01384 {
01385 if (m_afEntry[7] > -(Real)1.0)
01386 {
01387 rfZAngle = Math<Real>::ATan2(-m_afEntry[1],m_afEntry[4]);
01388 rfXAngle = (Real)asin((double)m_afEntry[7]);
01389 rfYAngle = Math<Real>::ATan2(-m_afEntry[6],m_afEntry[8]);
01390 return true;
01391 }
01392 else
01393 {
01394
01395 rfZAngle = -Math<Real>::ATan2(m_afEntry[2],m_afEntry[0]);
01396 rfXAngle = -Math<Real>::HALF_PI;
01397 rfYAngle = (Real)0.0;
01398 return false;
01399 }
01400 }
01401 else
01402 {
01403
01404 rfZAngle = Math<Real>::ATan2(m_afEntry[2],m_afEntry[0]);
01405 rfXAngle = Math<Real>::HALF_PI;
01406 rfYAngle = (Real)0.0;
01407 return false;
01408 }
01409 }
01410
01411 template <class Real>
01412 bool Matrix3<Real>::ToEulerAnglesZYX (Real& rfZAngle, Real& rfYAngle,
01413 Real& rfXAngle) const
01414 {
01415
01416
01417
01418
01419 if (m_afEntry[6] < (Real)1.0)
01420 {
01421 if (m_afEntry[6] > -(Real)1.0)
01422 {
01423 rfZAngle = Math<Real>::ATan2(m_afEntry[3],m_afEntry[0]);
01424 rfYAngle = (Real)asin(-(double)m_afEntry[6]);
01425 rfXAngle = Math<Real>::ATan2(m_afEntry[7],m_afEntry[8]);
01426 return true;
01427 }
01428 else
01429 {
01430
01431 rfZAngle = -Math<Real>::ATan2(m_afEntry[1],m_afEntry[2]);
01432 rfYAngle = Math<Real>::HALF_PI;
01433 rfXAngle = (Real)0.0;
01434 return false;
01435 }
01436 }
01437 else
01438 {
01439
01440 rfZAngle = Math<Real>::ATan2(-m_afEntry[1],-m_afEntry[2]);
01441 rfYAngle = -Math<Real>::HALF_PI;
01442 rfXAngle = (Real)0.0;
01443 return false;
01444 }
01445 }
01446
01447 template <class Real>
01448 Matrix3<Real>& Matrix3<Real>::Slerp (Real fT, const Matrix3& rkR0,
01449 const Matrix3& rkR1)
01450 {
01451 Vector3<Real> kAxis;
01452 Real fAngle;
01453 Matrix3 kProd = rkR0.TransposeTimes(rkR1);
01454 kProd.ToAxisAngle(kAxis,fAngle);
01455 FromAxisAngle(kAxis,fT*fAngle);
01456 return *this;
01457 }
01458
01459 template <class Real>
01460 bool Matrix3<Real>::Tridiagonalize (Real afDiag[3], Real afSubd[2])
01461 {
01462
01463
01464
01465
01466
01467
01468
01469
01470 Real fM00 = m_afEntry[0];
01471 Real fM01 = m_afEntry[1];
01472 Real fM02 = m_afEntry[2];
01473 Real fM11 = m_afEntry[4];
01474 Real fM12 = m_afEntry[5];
01475 Real fM22 = m_afEntry[8];
01476
01477 afDiag[0] = fM00;
01478 if (Math<Real>::FAbs(fM02) >= Math<Real>::ZERO_TOLERANCE)
01479 {
01480 afSubd[0] = Math<Real>::Sqrt(fM01*fM01+fM02*fM02);
01481 Real fInvLength = ((Real)1.0)/afSubd[0];
01482 fM01 *= fInvLength;
01483 fM02 *= fInvLength;
01484 Real fTmp = ((Real)2.0)*fM01*fM12+fM02*(fM22-fM11);
01485 afDiag[1] = fM11+fM02*fTmp;
01486 afDiag[2] = fM22-fM02*fTmp;
01487 afSubd[1] = fM12-fM01*fTmp;
01488
01489 m_afEntry[0] = (Real)1.0;
01490 m_afEntry[1] = (Real)0.0;
01491 m_afEntry[2] = (Real)0.0;
01492 m_afEntry[3] = (Real)0.0;
01493 m_afEntry[4] = fM01;
01494 m_afEntry[5] = fM02;
01495 m_afEntry[6] = (Real)0.0;
01496 m_afEntry[7] = fM02;
01497 m_afEntry[8] = -fM01;
01498 return true;
01499 }
01500 else
01501 {
01502 afDiag[1] = fM11;
01503 afDiag[2] = fM22;
01504 afSubd[0] = fM01;
01505 afSubd[1] = fM12;
01506
01507 m_afEntry[0] = (Real)1.0;
01508 m_afEntry[1] = (Real)0.0;
01509 m_afEntry[2] = (Real)0.0;
01510 m_afEntry[3] = (Real)0.0;
01511 m_afEntry[4] = (Real)1.0;
01512 m_afEntry[5] = (Real)0.0;
01513 m_afEntry[6] = (Real)0.0;
01514 m_afEntry[7] = (Real)0.0;
01515 m_afEntry[8] = (Real)1.0;
01516 return false;
01517 }
01518 }
01519
01520 template <class Real>
01521 bool Matrix3<Real>::QLAlgorithm (Real afDiag[3], Real afSubd[2])
01522 {
01523
01524
01525
01526
01527
01528
01529
01530 const int iMax = 32;
01531 for (int i = 0; i < iMax; i++)
01532 {
01533 Real fSum, fDiff, fDiscr, fEValue0, fEValue1, fCos, fSin, fTmp;
01534 int iRow;
01535
01536 fSum = Math<Real>::FAbs(afDiag[0]) + Math<Real>::FAbs(afDiag[1]);
01537 if (Math<Real>::FAbs(afSubd[0]) + fSum == fSum)
01538 {
01539
01540
01541
01542
01543
01544
01545
01546
01547 fSum = afDiag[1] + afDiag[2];
01548 fDiff = afDiag[1] - afDiag[2];
01549 fDiscr = Math<Real>::Sqrt(fDiff*fDiff +
01550 ((Real)4.0)*afSubd[1]*afSubd[1]);
01551 fEValue0 = ((Real)0.5)*(fSum - fDiscr);
01552 fEValue1 = ((Real)0.5)*(fSum + fDiscr);
01553
01554
01555 if (fDiff >= (Real)0.0)
01556 {
01557 fCos = afSubd[1];
01558 fSin = afDiag[1] - fEValue0;
01559 }
01560 else
01561 {
01562 fCos = afDiag[2] - fEValue0;
01563 fSin = afSubd[1];
01564 }
01565 fTmp = Math<Real>::InvSqrt(fCos*fCos + fSin*fSin);
01566 fCos *= fTmp;
01567 fSin *= fTmp;
01568
01569
01570
01571 for (iRow = 0; iRow < 3; iRow++)
01572 {
01573 fTmp = m_afEntry[2+3*iRow];
01574 m_afEntry[2+3*iRow] = fSin*m_afEntry[1+3*iRow] + fCos*fTmp;
01575 m_afEntry[1+3*iRow] = fCos*m_afEntry[1+3*iRow] - fSin*fTmp;
01576 }
01577
01578
01579 afDiag[1] = fEValue0;
01580 afDiag[2] = fEValue1;
01581 afSubd[0] = (Real)0.0;
01582 afSubd[1] = (Real)0.0;
01583 return true;
01584 }
01585
01586 fSum = Math<Real>::FAbs(afDiag[1]) + Math<Real>::FAbs(afDiag[2]);
01587 if (Math<Real>::FAbs(afSubd[1]) + fSum == fSum)
01588 {
01589
01590
01591
01592
01593
01594
01595
01596
01597 fSum = afDiag[0] + afDiag[1];
01598 fDiff = afDiag[0] - afDiag[1];
01599 fDiscr = Math<Real>::Sqrt(fDiff*fDiff +
01600 ((Real)4.0)*afSubd[0]*afSubd[0]);
01601 fEValue0 = ((Real)0.5)*(fSum - fDiscr);
01602 fEValue1 = ((Real)0.5)*(fSum + fDiscr);
01603
01604
01605 if (fDiff >= (Real)0.0)
01606 {
01607 fCos = afSubd[0];
01608 fSin = afDiag[0] - fEValue0;
01609 }
01610 else
01611 {
01612 fCos = afDiag[1] - fEValue0;
01613 fSin = afSubd[0];
01614 }
01615 fTmp = Math<Real>::InvSqrt(fCos*fCos + fSin*fSin);
01616 fCos *= fTmp;
01617 fSin *= fTmp;
01618
01619
01620
01621 for (iRow = 0; iRow < 3; iRow++)
01622 {
01623 fTmp = m_afEntry[1+3*iRow];
01624 m_afEntry[1+3*iRow] = fSin*m_afEntry[0+3*iRow] + fCos*fTmp;
01625 m_afEntry[0+3*iRow] = fCos*m_afEntry[0+3*iRow] - fSin*fTmp;
01626 }
01627
01628
01629 afDiag[0] = fEValue0;
01630 afDiag[1] = fEValue1;
01631 afSubd[0] = (Real)0.0;
01632 afSubd[1] = (Real)0.0;
01633 return true;
01634 }
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646 Real fRatio = (afDiag[1]-afDiag[0])/(((Real)2.0f)*afSubd[0]);
01647 Real fRoot = Math<Real>::Sqrt((Real)1.0 + fRatio*fRatio);
01648 Real fB = afSubd[1];
01649 Real fA = afDiag[2] - afDiag[0];
01650 if (fRatio >= (Real)0.0)
01651 {
01652 fA += afSubd[0]/(fRatio + fRoot);
01653 }
01654 else
01655 {
01656 fA += afSubd[0]/(fRatio - fRoot);
01657 }
01658
01659
01660 if (Math<Real>::FAbs(fB) >= Math<Real>::FAbs(fA))
01661 {
01662 fRatio = fA/fB;
01663 fSin = Math<Real>::InvSqrt((Real)1.0 + fRatio*fRatio);
01664 fCos = fRatio*fSin;
01665 }
01666 else
01667 {
01668 fRatio = fB/fA;
01669 fCos = Math<Real>::InvSqrt((Real)1.0 + fRatio*fRatio);
01670 fSin = fRatio*fCos;
01671 }
01672
01673
01674
01675 for (iRow = 0; iRow < 3; iRow++)
01676 {
01677 fTmp = m_afEntry[2+3*iRow];
01678 m_afEntry[2+3*iRow] = fSin*m_afEntry[1+3*iRow]+fCos*fTmp;
01679 m_afEntry[1+3*iRow] = fCos*m_afEntry[1+3*iRow]-fSin*fTmp;
01680 }
01681
01682
01683
01684
01685 Real fTmp0 = (afDiag[1] - afDiag[2])*fSin +
01686 ((Real)2.0)*afSubd[1]*fCos;
01687 Real fTmp1 = fCos*afSubd[0];
01688 fB = fSin*afSubd[0];
01689 fA = fCos*fTmp0 - afSubd[1];
01690 fTmp0 *= fSin;
01691
01692
01693
01694 if (Math<Real>::FAbs(fB) >= Math<Real>::FAbs(fA))
01695 {
01696 fRatio = fA/fB;
01697 fRoot = Math<Real>::Sqrt((Real)1.0 + fRatio*fRatio);
01698 afSubd[1] = fB*fRoot;
01699 fSin = ((Real)1.0)/fRoot;
01700 fCos = fRatio*fSin;
01701 }
01702 else
01703 {
01704 fRatio = fB/fA;
01705 fRoot = Math<Real>::Sqrt((Real)1.0 + fRatio*fRatio);
01706 afSubd[1] = fA*fRoot;
01707 fCos = ((Real)1.0)/fRoot;
01708 fSin = fRatio*fCos;
01709 }
01710
01711
01712
01713 for (iRow = 0; iRow < 3; iRow++)
01714 {
01715 fTmp = m_afEntry[1+3*iRow];
01716 m_afEntry[1+3*iRow] = fSin*m_afEntry[0+3*iRow]+fCos*fTmp;
01717 m_afEntry[0+3*iRow] = fCos*m_afEntry[0+3*iRow]-fSin*fTmp;
01718 }
01719
01720
01721 Real fTmp2 = afDiag[1] - fTmp0;
01722 afDiag[2] += fTmp0;
01723 fTmp0 = (afDiag[0] - fTmp2)*fSin + ((Real)2.0)*fTmp1*fCos;
01724 afSubd[0] = fCos*fTmp0 - fTmp1;
01725 fTmp0 *= fSin;
01726 afDiag[1] = fTmp2 + fTmp0;
01727 afDiag[0] -= fTmp0;
01728 }
01729 return false;
01730 }
01731
01732 template <class Real>
01733 void Matrix3<Real>::Bidiagonalize (Matrix3& rkA, Matrix3& rkL, Matrix3& rkR)
01734 {
01735 Real afV[3], afW[3];
01736 Real fLength, fSign, fT1, fInvT1, fT2;
01737 bool bIdentity;
01738
01739
01740 fLength = Math<Real>::Sqrt(rkA[0][0]*rkA[0][0] + rkA[1][0]*rkA[1][0] +
01741 rkA[2][0]*rkA[2][0]);
01742 if (fLength > (Real)0.0)
01743 {
01744 fSign = (rkA[0][0] > (Real)0.0 ? (Real)1.0 : -(Real)1.0);
01745 fT1 = rkA[0][0] + fSign*fLength;
01746 fInvT1 = ((Real)1.0)/fT1;
01747 afV[1] = rkA[1][0]*fInvT1;
01748 afV[2] = rkA[2][0]*fInvT1;
01749
01750 fT2 = -((Real)2.0)/(((Real)1.0)+afV[1]*afV[1]+afV[2]*afV[2]);
01751 afW[0] = fT2*(rkA[0][0]+rkA[1][0]*afV[1]+rkA[2][0]*afV[2]);
01752 afW[1] = fT2*(rkA[0][1]+rkA[1][1]*afV[1]+rkA[2][1]*afV[2]);
01753 afW[2] = fT2*(rkA[0][2]+rkA[1][2]*afV[1]+rkA[2][2]*afV[2]);
01754 rkA[0][0] += afW[0];
01755 rkA[0][1] += afW[1];
01756 rkA[0][2] += afW[2];
01757 rkA[1][1] += afV[1]*afW[1];
01758 rkA[1][2] += afV[1]*afW[2];
01759 rkA[2][1] += afV[2]*afW[1];
01760 rkA[2][2] += afV[2]*afW[2];
01761
01762 rkL[0][0] = ((Real)1.0)+fT2;
01763 rkL[0][1] = fT2*afV[1];
01764 rkL[1][0] = rkL[0][1];
01765 rkL[0][2] = fT2*afV[2];
01766 rkL[2][0] = rkL[0][2];
01767 rkL[1][1] = ((Real)1.0)+fT2*afV[1]*afV[1];
01768 rkL[1][2] = fT2*afV[1]*afV[2];
01769 rkL[2][1] = rkL[1][2];
01770 rkL[2][2] = ((Real)1.0)+fT2*afV[2]*afV[2];
01771 bIdentity = false;
01772 }
01773 else
01774 {
01775 rkL = Matrix3::IDENTITY;
01776 bIdentity = true;
01777 }
01778
01779
01780 fLength = Math<Real>::Sqrt(rkA[0][1]*rkA[0][1]+rkA[0][2]*rkA[0][2]);
01781 if (fLength > (Real)0.0)
01782 {
01783 fSign = (rkA[0][1] > (Real)0.0 ? (Real)1.0 : -(Real)1.0);
01784 fT1 = rkA[0][1] + fSign*fLength;
01785 afV[2] = rkA[0][2]/fT1;
01786
01787 fT2 = -((Real)2.0)/(((Real)1.0)+afV[2]*afV[2]);
01788 afW[0] = fT2*(rkA[0][1]+rkA[0][2]*afV[2]);
01789 afW[1] = fT2*(rkA[1][1]+rkA[1][2]*afV[2]);
01790 afW[2] = fT2*(rkA[2][1]+rkA[2][2]*afV[2]);
01791 rkA[0][1] += afW[0];
01792 rkA[1][1] += afW[1];
01793 rkA[1][2] += afW[1]*afV[2];
01794 rkA[2][1] += afW[2];
01795 rkA[2][2] += afW[2]*afV[2];
01796
01797 rkR[0][0] = (Real)1.0;
01798 rkR[0][1] = (Real)0.0;
01799 rkR[1][0] = (Real)0.0;
01800 rkR[0][2] = (Real)0.0;
01801 rkR[2][0] = (Real)0.0;
01802 rkR[1][1] = ((Real)1.0)+fT2;
01803 rkR[1][2] = fT2*afV[2];
01804 rkR[2][1] = rkR[1][2];
01805 rkR[2][2] = ((Real)1.0)+fT2*afV[2]*afV[2];
01806 }
01807 else
01808 {
01809 rkR = Matrix3::IDENTITY;
01810 }
01811
01812
01813 fLength = Math<Real>::Sqrt(rkA[1][1]*rkA[1][1]+rkA[2][1]*rkA[2][1]);
01814 if (fLength > (Real)0.0)
01815 {
01816 fSign = (rkA[1][1] > (Real)0.0 ? (Real)1.0 : -(Real)1.0);
01817 fT1 = rkA[1][1] + fSign*fLength;
01818 afV[2] = rkA[2][1]/fT1;
01819
01820 fT2 = -((Real)2.0)/(((Real)1.0)+afV[2]*afV[2]);
01821 afW[1] = fT2*(rkA[1][1]+rkA[2][1]*afV[2]);
01822 afW[2] = fT2*(rkA[1][2]+rkA[2][2]*afV[2]);
01823 rkA[1][1] += afW[1];
01824 rkA[1][2] += afW[2];
01825 rkA[2][2] += afV[2]*afW[2];
01826
01827 Real fA = ((Real)1.0)+fT2;
01828 Real fB = fT2*afV[2];
01829 Real fC = ((Real)1.0)+fB*afV[2];
01830
01831 if (bIdentity)
01832 {
01833 rkL[0][0] = (Real)1.0;
01834 rkL[0][1] = (Real)0.0;
01835 rkL[1][0] = (Real)0.0;
01836 rkL[0][2] = (Real)0.0;
01837 rkL[2][0] = (Real)0.0;
01838 rkL[1][1] = fA;
01839 rkL[1][2] = fB;
01840 rkL[2][1] = fB;
01841 rkL[2][2] = fC;
01842 }
01843 else
01844 {
01845 for (int iRow = 0; iRow < 3; iRow++)
01846 {
01847 Real fTmp0 = rkL[iRow][1];
01848 Real fTmp1 = rkL[iRow][2];
01849 rkL[iRow][1] = fA*fTmp0+fB*fTmp1;
01850 rkL[iRow][2] = fB*fTmp0+fC*fTmp1;
01851 }
01852 }
01853 }
01854 }
01855
01856 template <class Real>
01857 void Matrix3<Real>::GolubKahanStep (Matrix3& rkA, Matrix3& rkL, Matrix3& rkR)
01858 {
01859 Real fT11 = rkA[0][1]*rkA[0][1]+rkA[1][1]*rkA[1][1];
01860 Real fT22 = rkA[1][2]*rkA[1][2]+rkA[2][2]*rkA[2][2];
01861 Real fT12 = rkA[1][1]*rkA[1][2];
01862 Real fTrace = fT11+fT22;
01863 Real fDiff = fT11-fT22;
01864 Real fDiscr = Math<Real>::Sqrt(fDiff*fDiff+((Real)4.0)*fT12*fT12);
01865 Real fRoot1 = ((Real)0.5)*(fTrace+fDiscr);
01866 Real fRoot2 = ((Real)0.5)*(fTrace-fDiscr);
01867
01868
01869 Real fY = rkA[0][0] - (Math<Real>::FAbs(fRoot1-fT22) <=
01870 Math<Real>::FAbs(fRoot2-fT22) ? fRoot1 : fRoot2);
01871 Real fZ = rkA[0][1];
01872 Real fInvLength = Math<Real>::InvSqrt(fY*fY+fZ*fZ);
01873 Real fSin = fZ*fInvLength;
01874 Real fCos = -fY*fInvLength;
01875
01876 Real fTmp0 = rkA[0][0];
01877 Real fTmp1 = rkA[0][1];
01878 rkA[0][0] = fCos*fTmp0-fSin*fTmp1;
01879 rkA[0][1] = fSin*fTmp0+fCos*fTmp1;
01880 rkA[1][0] = -fSin*rkA[1][1];
01881 rkA[1][1] *= fCos;
01882
01883 int iRow;
01884 for (iRow = 0; iRow < 3; iRow++)
01885 {
01886 fTmp0 = rkR[0][iRow];
01887 fTmp1 = rkR[1][iRow];
01888 rkR[0][iRow] = fCos*fTmp0-fSin*fTmp1;
01889 rkR[1][iRow] = fSin*fTmp0+fCos*fTmp1;
01890 }
01891
01892
01893 fY = rkA[0][0];
01894 fZ = rkA[1][0];
01895 fInvLength = Math<Real>::InvSqrt(fY*fY+fZ*fZ);
01896 fSin = fZ*fInvLength;
01897 fCos = -fY*fInvLength;
01898
01899 rkA[0][0] = fCos*rkA[0][0]-fSin*rkA[1][0];
01900 fTmp0 = rkA[0][1];
01901 fTmp1 = rkA[1][1];
01902 rkA[0][1] = fCos*fTmp0-fSin*fTmp1;
01903 rkA[1][1] = fSin*fTmp0+fCos*fTmp1;
01904 rkA[0][2] = -fSin*rkA[1][2];
01905 rkA[1][2] *= fCos;
01906
01907 int iCol;
01908 for (iCol = 0; iCol < 3; iCol++)
01909 {
01910 fTmp0 = rkL[iCol][0];
01911 fTmp1 = rkL[iCol][1];
01912 rkL[iCol][0] = fCos*fTmp0-fSin*fTmp1;
01913 rkL[iCol][1] = fSin*fTmp0+fCos*fTmp1;
01914 }
01915
01916
01917 fY = rkA[0][1];
01918 fZ = rkA[0][2];
01919 fInvLength = Math<Real>::InvSqrt(fY*fY+fZ*fZ);
01920 fSin = fZ*fInvLength;
01921 fCos = -fY*fInvLength;
01922
01923 rkA[0][1] = fCos*rkA[0][1]-fSin*rkA[0][2];
01924 fTmp0 = rkA[1][1];
01925 fTmp1 = rkA[1][2];
01926 rkA[1][1] = fCos*fTmp0-fSin*fTmp1;
01927 rkA[1][2] = fSin*fTmp0+fCos*fTmp1;
01928 rkA[2][1] = -fSin*rkA[2][2];
01929 rkA[2][2] *= fCos;
01930
01931 for (iRow = 0; iRow < 3; iRow++)
01932 {
01933 fTmp0 = rkR[1][iRow];
01934 fTmp1 = rkR[2][iRow];
01935 rkR[1][iRow] = fCos*fTmp0-fSin*fTmp1;
01936 rkR[2][iRow] = fSin*fTmp0+fCos*fTmp1;
01937 }
01938
01939
01940 fY = rkA[1][1];
01941 fZ = rkA[2][1];
01942 fInvLength = Math<Real>::InvSqrt(fY*fY+fZ*fZ);
01943 fSin = fZ*fInvLength;
01944 fCos = -fY*fInvLength;
01945
01946 rkA[1][1] = fCos*rkA[1][1]-fSin*rkA[2][1];
01947 fTmp0 = rkA[1][2];
01948 fTmp1 = rkA[2][2];
01949 rkA[1][2] = fCos*fTmp0-fSin*fTmp1;
01950 rkA[2][2] = fSin*fTmp0+fCos*fTmp1;
01951
01952 for (iCol = 0; iCol < 3; iCol++)
01953 {
01954 fTmp0 = rkL[iCol][1];
01955 fTmp1 = rkL[iCol][2];
01956 rkL[iCol][1] = fCos*fTmp0-fSin*fTmp1;
01957 rkL[iCol][2] = fSin*fTmp0+fCos*fTmp1;
01958 }
01959 }
01960
01961 template <class Real>
01962 void Matrix3<Real>::SingularValueDecomposition (Matrix3& rkL, Matrix3& rkS,
01963 Matrix3& rkR) const
01964 {
01965 int iRow, iCol;
01966
01967 Matrix3 kA = *this;
01968 Bidiagonalize(kA,rkL,rkR);
01969 rkS.MakeZero();
01970
01971 const int iMax = 32;
01972 const Real fEpsilon = (Real)1e-04;
01973 for (int i = 0; i < iMax; i++)
01974 {
01975 Real fTmp, fTmp0, fTmp1;
01976 Real fSin0, fCos0, fTan0;
01977 Real fSin1, fCos1, fTan1;
01978
01979 bool bTest1 = (Math<Real>::FAbs(kA[0][1]) <=
01980 fEpsilon*(Math<Real>::FAbs(kA[0][0]) +
01981 Math<Real>::FAbs(kA[1][1])));
01982 bool bTest2 = (Math<Real>::FAbs(kA[1][2]) <=
01983 fEpsilon*(Math<Real>::FAbs(kA[1][1]) +
01984 Math<Real>::FAbs(kA[2][2])));
01985 if (bTest1)
01986 {
01987 if (bTest2)
01988 {
01989 rkS[0][0] = kA[0][0];
01990 rkS[1][1] = kA[1][1];
01991 rkS[2][2] = kA[2][2];
01992 break;
01993 }
01994 else
01995 {
01996
01997 fTmp = (kA[1][1]*kA[1][1] - kA[2][2]*kA[2][2] +
01998 kA[1][2]*kA[1][2])/(kA[1][2]*kA[2][2]);
01999 fTan0 = ((Real)0.5)*(fTmp + Math<Real>::Sqrt(fTmp*fTmp +
02000 ((Real)4.0)));
02001 fCos0 = Math<Real>::InvSqrt(((Real)1.0)+fTan0*fTan0);
02002 fSin0 = fTan0*fCos0;
02003
02004 for (iCol = 0; iCol < 3; iCol++)
02005 {
02006 fTmp0 = rkL[iCol][1];
02007 fTmp1 = rkL[iCol][2];
02008 rkL[iCol][1] = fCos0*fTmp0-fSin0*fTmp1;
02009 rkL[iCol][2] = fSin0*fTmp0+fCos0*fTmp1;
02010 }
02011
02012 fTan1 = (kA[1][2]-kA[2][2]*fTan0)/kA[1][1];
02013 fCos1 = Math<Real>::InvSqrt(((Real)1.0)+fTan1*fTan1);
02014 fSin1 = -fTan1*fCos1;
02015
02016 for (iRow = 0; iRow < 3; iRow++)
02017 {
02018 fTmp0 = rkR[1][iRow];
02019 fTmp1 = rkR[2][iRow];
02020 rkR[1][iRow] = fCos1*fTmp0-fSin1*fTmp1;
02021 rkR[2][iRow] = fSin1*fTmp0+fCos1*fTmp1;
02022 }
02023
02024 rkS[0][0] = kA[0][0];
02025 rkS[1][1] = fCos0*fCos1*kA[1][1] -
02026 fSin1*(fCos0*kA[1][2]-fSin0*kA[2][2]);
02027 rkS[2][2] = fSin0*fSin1*kA[1][1] +
02028 fCos1*(fSin0*kA[1][2]+fCos0*kA[2][2]);
02029 break;
02030 }
02031 }
02032 else
02033 {
02034 if (bTest2)
02035 {
02036
02037 fTmp = (kA[0][0]*kA[0][0] + kA[1][1]*kA[1][1] -
02038 kA[0][1]*kA[0][1])/(kA[0][1]*kA[1][1]);
02039 fTan0 = ((Real)0.5)*(-fTmp + Math<Real>::Sqrt(fTmp*fTmp +
02040 ((Real)4.0)));
02041 fCos0 = Math<Real>::InvSqrt(((Real)1.0)+fTan0*fTan0);
02042 fSin0 = fTan0*fCos0;
02043
02044 for (iCol = 0; iCol < 3; iCol++)
02045 {
02046 fTmp0 = rkL[iCol][0];
02047 fTmp1 = rkL[iCol][1];
02048 rkL[iCol][0] = fCos0*fTmp0-fSin0*fTmp1;
02049 rkL[iCol][1] = fSin0*fTmp0+fCos0*fTmp1;
02050 }
02051
02052 fTan1 = (kA[0][1]-kA[1][1]*fTan0)/kA[0][0];
02053 fCos1 = Math<Real>::InvSqrt(((Real)1.0)+fTan1*fTan1);
02054 fSin1 = -fTan1*fCos1;
02055
02056 for (iRow = 0; iRow < 3; iRow++)
02057 {
02058 fTmp0 = rkR[0][iRow];
02059 fTmp1 = rkR[1][iRow];
02060 rkR[0][iRow] = fCos1*fTmp0-fSin1*fTmp1;
02061 rkR[1][iRow] = fSin1*fTmp0+fCos1*fTmp1;
02062 }
02063
02064 rkS[0][0] = fCos0*fCos1*kA[0][0] -
02065 fSin1*(fCos0*kA[0][1]-fSin0*kA[1][1]);
02066 rkS[1][1] = fSin0*fSin1*kA[0][0] +
02067 fCos1*(fSin0*kA[0][1]+fCos0*kA[1][1]);
02068 rkS[2][2] = kA[2][2];
02069 break;
02070 }
02071 else
02072 {
02073 GolubKahanStep(kA,rkL,rkR);
02074 }
02075 }
02076 }
02077
02078
02079 for (iRow = 0; iRow < 3; iRow++)
02080 {
02081 if (rkS[iRow][iRow] < (Real)0.0)
02082 {
02083 rkS[iRow][iRow] = -rkS[iRow][iRow];
02084 for (iCol = 0; iCol < 3; iCol++)
02085 rkR[iRow][iCol] = -rkR[iRow][iCol];
02086 }
02087 }
02088 }
02089
02090 template <class Real>
02091 void Matrix3<Real>::SingularValueComposition (const Matrix3& rkL,
02092 const Matrix3& rkS, const Matrix3& rkR)
02093 {
02094 *this = rkL*(rkS*rkR);
02095 }
02096
02097 template <class Real>
02098 void Matrix3<Real>::QDUDecomposition (Matrix3& rkQ, Matrix3& rkD,
02099 Matrix3& rkU) const
02100 {
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123 Real fInvLength = Math<Real>::InvSqrt(m_afEntry[0]*m_afEntry[0] +
02124 m_afEntry[3]*m_afEntry[3] + m_afEntry[6]*m_afEntry[6]);
02125 rkQ[0][0] = m_afEntry[0]*fInvLength;
02126 rkQ[1][0] = m_afEntry[3]*fInvLength;
02127 rkQ[2][0] = m_afEntry[6]*fInvLength;
02128
02129 Real fDot = rkQ[0][0]*m_afEntry[1] + rkQ[1][0]*m_afEntry[4] +
02130 rkQ[2][0]*m_afEntry[7];
02131 rkQ[0][1] = m_afEntry[1]-fDot*rkQ[0][0];
02132 rkQ[1][1] = m_afEntry[4]-fDot*rkQ[1][0];
02133 rkQ[2][1] = m_afEntry[7]-fDot*rkQ[2][0];
02134 fInvLength = Math<Real>::InvSqrt(rkQ[0][1]*rkQ[0][1] +
02135 rkQ[1][1]*rkQ[1][1] + rkQ[2][1]*rkQ[2][1]);
02136 rkQ[0][1] *= fInvLength;
02137 rkQ[1][1] *= fInvLength;
02138 rkQ[2][1] *= fInvLength;
02139
02140 fDot = rkQ[0][0]*m_afEntry[2] + rkQ[1][0]*m_afEntry[5] +
02141 rkQ[2][0]*m_afEntry[8];
02142 rkQ[0][2] = m_afEntry[2]-fDot*rkQ[0][0];
02143 rkQ[1][2] = m_afEntry[5]-fDot*rkQ[1][0];
02144 rkQ[2][2] = m_afEntry[8]-fDot*rkQ[2][0];
02145 fDot = rkQ[0][1]*m_afEntry[2] + rkQ[1][1]*m_afEntry[5] +
02146 rkQ[2][1]*m_afEntry[8];
02147 rkQ[0][2] -= fDot*rkQ[0][1];
02148 rkQ[1][2] -= fDot*rkQ[1][1];
02149 rkQ[2][2] -= fDot*rkQ[2][1];
02150 fInvLength = Math<Real>::InvSqrt(rkQ[0][2]*rkQ[0][2] +
02151 rkQ[1][2]*rkQ[1][2] + rkQ[2][2]*rkQ[2][2]);
02152 rkQ[0][2] *= fInvLength;
02153 rkQ[1][2] *= fInvLength;
02154 rkQ[2][2] *= fInvLength;
02155
02156
02157 Real fDet = rkQ[0][0]*rkQ[1][1]*rkQ[2][2] + rkQ[0][1]*rkQ[1][2]*rkQ[2][0]
02158 + rkQ[0][2]*rkQ[1][0]*rkQ[2][1] - rkQ[0][2]*rkQ[1][1]*rkQ[2][0]
02159 - rkQ[0][1]*rkQ[1][0]*rkQ[2][2] - rkQ[0][0]*rkQ[1][2]*rkQ[2][1];
02160
02161 if (fDet < (Real)0.0)
02162 {
02163 for (int iRow = 0; iRow < 3; iRow++)
02164 {
02165 for (int iCol = 0; iCol < 3; iCol++)
02166 {
02167 rkQ[iRow][iCol] = -rkQ[iRow][iCol];
02168 }
02169 }
02170 }
02171
02172
02173 Matrix3 kR;
02174 kR[0][0] = rkQ[0][0]*m_afEntry[0] + rkQ[1][0]*m_afEntry[3] +
02175 rkQ[2][0]*m_afEntry[6];
02176 kR[0][1] = rkQ[0][0]*m_afEntry[1] + rkQ[1][0]*m_afEntry[4] +
02177 rkQ[2][0]*m_afEntry[7];
02178 kR[1][1] = rkQ[0][1]*m_afEntry[1] + rkQ[1][1]*m_afEntry[4] +
02179 rkQ[2][1]*m_afEntry[7];
02180 kR[0][2] = rkQ[0][0]*m_afEntry[2] + rkQ[1][0]*m_afEntry[5] +
02181 rkQ[2][0]*m_afEntry[8];
02182 kR[1][2] = rkQ[0][1]*m_afEntry[2] + rkQ[1][1]*m_afEntry[5] +
02183 rkQ[2][1]*m_afEntry[8];
02184 kR[2][2] = rkQ[0][2]*m_afEntry[2] + rkQ[1][2]*m_afEntry[5] +
02185 rkQ[2][2]*m_afEntry[8];
02186
02187
02188 rkD.MakeDiagonal(kR[0][0],kR[1][1],kR[2][2]);
02189
02190
02191 Real fInvD0 = ((Real)1.0)/rkD[0][0];
02192 rkU[0][0] = (Real)1.0;
02193 rkU[0][1] = kR[0][1]*fInvD0;
02194 rkU[0][2] = kR[0][2]*fInvD0;
02195 rkU[1][0] = (Real)0.0;
02196 rkU[1][1] = (Real)1.0;
02197 rkU[1][2] = kR[1][2]/rkD[1][1];
02198 rkU[2][0] = (Real)0.0;
02199 rkU[2][1] = (Real)0.0;
02200 rkU[2][2] = (Real)1.0;
02201 }
02202
02203 template <class Real>
02204 Matrix3<Real> operator* (Real fScalar, const Matrix3<Real>& rkM)
02205 {
02206 return rkM*fScalar;
02207 }
02208
02209 template <class Real>
02210 Vector3<Real> operator* (const Vector3<Real>& rkV, const Matrix3<Real>& rkM)
02211 {
02212 return Vector3<Real>(
02213 rkV[0]*rkM[0][0] + rkV[1]*rkM[1][0] + rkV[2]*rkM[2][0],
02214 rkV[0]*rkM[0][1] + rkV[1]*rkM[1][1] + rkV[2]*rkM[2][1],
02215 rkV[0]*rkM[0][2] + rkV[1]*rkM[1][2] + rkV[2]*rkM[2][2]);
02216 }
02217
02218 }