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 Matrix2<Real>::Matrix2 (bool bZero)
00022 {
00023 if (bZero)
00024 {
00025 MakeZero();
00026 }
00027 else
00028 {
00029 MakeIdentity();
00030 }
00031 }
00032
00033 template <class Real>
00034 Matrix2<Real>::Matrix2 (const Matrix2& 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 }
00041
00042 template <class Real>
00043 Matrix2<Real>::Matrix2 (Real fM00, Real fM01, Real fM10, Real fM11)
00044 {
00045 m_afEntry[0] = fM00;
00046 m_afEntry[1] = fM01;
00047 m_afEntry[2] = fM10;
00048 m_afEntry[3] = fM11;
00049 }
00050
00051 template <class Real>
00052 Matrix2<Real>::Matrix2 (const Real afEntry[4], bool bRowMajor)
00053 {
00054 if (bRowMajor)
00055 {
00056 m_afEntry[0] = afEntry[0];
00057 m_afEntry[1] = afEntry[1];
00058 m_afEntry[2] = afEntry[2];
00059 m_afEntry[3] = afEntry[3];
00060 }
00061 else
00062 {
00063 m_afEntry[0] = afEntry[0];
00064 m_afEntry[1] = afEntry[2];
00065 m_afEntry[2] = afEntry[1];
00066 m_afEntry[3] = afEntry[3];
00067 }
00068 }
00069
00070 template <class Real>
00071 Matrix2<Real>::Matrix2 (const Vector2<Real>& rkU, const Vector2<Real>& rkV,
00072 bool bColumns)
00073 {
00074 if (bColumns)
00075 {
00076 m_afEntry[0] = rkU[0];
00077 m_afEntry[1] = rkV[0];
00078 m_afEntry[2] = rkU[1];
00079 m_afEntry[3] = rkV[1];
00080 }
00081 else
00082 {
00083 m_afEntry[0] = rkU[0];
00084 m_afEntry[1] = rkU[1];
00085 m_afEntry[2] = rkV[0];
00086 m_afEntry[3] = rkV[1];
00087 }
00088 }
00089
00090 template <class Real>
00091 Matrix2<Real>::Matrix2 (const Vector2<Real>* akV, bool bColumns)
00092 {
00093 if (bColumns)
00094 {
00095 m_afEntry[0] = akV[0][0];
00096 m_afEntry[1] = akV[1][0];
00097 m_afEntry[2] = akV[0][1];
00098 m_afEntry[3] = akV[1][1];
00099 }
00100 else
00101 {
00102 m_afEntry[0] = akV[0][0];
00103 m_afEntry[1] = akV[0][1];
00104 m_afEntry[2] = akV[1][0];
00105 m_afEntry[3] = akV[1][1];
00106 }
00107 }
00108
00109 template <class Real>
00110 Matrix2<Real>::Matrix2 (Real fM00, Real fM11)
00111 {
00112 MakeDiagonal(fM00,fM11);
00113 }
00114
00115 template <class Real>
00116 Matrix2<Real>::Matrix2 (Real fAngle)
00117 {
00118 FromAngle(fAngle);
00119 }
00120
00121 template <class Real>
00122 Matrix2<Real>::Matrix2 (const Vector2<Real>& rkU, const Vector2<Real>& rkV)
00123 {
00124 MakeTensorProduct(rkU,rkV);
00125 }
00126
00127 template <class Real>
00128 Matrix2<Real>::operator const Real* () const
00129 {
00130 return m_afEntry;
00131 }
00132
00133 template <class Real>
00134 Matrix2<Real>::operator Real* ()
00135 {
00136 return m_afEntry;
00137 }
00138
00139 template <class Real>
00140 const Real* Matrix2<Real>::operator[] (int iRow) const
00141 {
00142 return &m_afEntry[2*iRow];
00143 }
00144
00145 template <class Real>
00146 Real* Matrix2<Real>::operator[] (int iRow)
00147 {
00148 return &m_afEntry[2*iRow];
00149 }
00150
00151 template <class Real>
00152 Real Matrix2<Real>::operator() (int iRow, int iCol) const
00153 {
00154 return m_afEntry[iCol + 2*iRow];
00155 }
00156
00157 template <class Real>
00158 Real& Matrix2<Real>::operator() (int iRow, int iCol)
00159 {
00160 return m_afEntry[iCol + 2*iRow];
00161 }
00162
00163 template <class Real>
00164 void Matrix2<Real>::MakeZero ()
00165 {
00166 m_afEntry[0] = (Real)0.0;
00167 m_afEntry[1] = (Real)0.0;
00168 m_afEntry[2] = (Real)0.0;
00169 m_afEntry[3] = (Real)0.0;
00170 }
00171
00172 template <class Real>
00173 void Matrix2<Real>::MakeIdentity ()
00174 {
00175 m_afEntry[0] = (Real)1.0;
00176 m_afEntry[1] = (Real)0.0;
00177 m_afEntry[2] = (Real)0.0;
00178 m_afEntry[3] = (Real)1.0;
00179 }
00180
00181 template <class Real>
00182 void Matrix2<Real>::MakeDiagonal (Real fM00, Real fM11)
00183 {
00184 m_afEntry[0] = fM00;
00185 m_afEntry[1] = (Real)0.0;
00186 m_afEntry[2] = (Real)0.0;
00187 m_afEntry[3] = fM11;
00188 }
00189
00190 template <class Real>
00191 void Matrix2<Real>::FromAngle (Real fAngle)
00192 {
00193 m_afEntry[0] = Math<Real>::Cos(fAngle);
00194 m_afEntry[2] = Math<Real>::Sin(fAngle);
00195 m_afEntry[1] = -m_afEntry[2];
00196 m_afEntry[3] = m_afEntry[0];
00197 }
00198
00199 template <class Real>
00200 void Matrix2<Real>::MakeTensorProduct (const Vector2<Real>& rkU,
00201 const Vector2<Real>& rkV)
00202 {
00203 m_afEntry[0] = rkU[0]*rkV[0];
00204 m_afEntry[1] = rkU[0]*rkV[1];
00205 m_afEntry[2] = rkU[1]*rkV[0];
00206 m_afEntry[3] = rkU[1]*rkV[1];
00207 }
00208
00209 template <class Real>
00210 void Matrix2<Real>::SetRow (int iRow, const Vector2<Real>& rkV)
00211 {
00212 int i0 = 2*iRow ,i1 = i0+1;
00213 m_afEntry[i0] = rkV[0];
00214 m_afEntry[i1] = rkV[1];
00215 }
00216
00217 template <class Real>
00218 Vector2<Real> Matrix2<Real>::GetRow (int iRow) const
00219 {
00220 int i0 = 2*iRow ,i1 = i0+1;
00221 return Vector2<Real>(m_afEntry[i0],m_afEntry[i1]);
00222 }
00223
00224 template <class Real>
00225 void Matrix2<Real>::SetColumn (int iCol, const Vector2<Real>& rkV)
00226 {
00227 m_afEntry[iCol] = rkV[0];
00228 m_afEntry[iCol+2] = rkV[1];
00229 }
00230
00231 template <class Real>
00232 Vector2<Real> Matrix2<Real>::GetColumn (int iCol) const
00233 {
00234 return Vector2<Real>(m_afEntry[iCol],m_afEntry[iCol+2]);
00235 }
00236
00237 template <class Real>
00238 void Matrix2<Real>::GetColumnMajor (Real* afCMajor) const
00239 {
00240 afCMajor[0] = m_afEntry[0];
00241 afCMajor[1] = m_afEntry[2];
00242 afCMajor[2] = m_afEntry[1];
00243 afCMajor[3] = m_afEntry[3];
00244 }
00245
00246 template <class Real>
00247 Matrix2<Real>& Matrix2<Real>::operator= (const Matrix2& rkM)
00248 {
00249 m_afEntry[0] = rkM.m_afEntry[0];
00250 m_afEntry[1] = rkM.m_afEntry[1];
00251 m_afEntry[2] = rkM.m_afEntry[2];
00252 m_afEntry[3] = rkM.m_afEntry[3];
00253 return *this;
00254 }
00255
00256 template <class Real>
00257 int Matrix2<Real>::CompareArrays (const Matrix2& rkM) const
00258 {
00259 return memcmp(m_afEntry,rkM.m_afEntry,4*sizeof(Real));
00260 }
00261
00262 template <class Real>
00263 bool Matrix2<Real>::operator== (const Matrix2& rkM) const
00264 {
00265 return CompareArrays(rkM) == 0;
00266 }
00267
00268 template <class Real>
00269 bool Matrix2<Real>::operator!= (const Matrix2& rkM) const
00270 {
00271 return CompareArrays(rkM) != 0;
00272 }
00273
00274 template <class Real>
00275 bool Matrix2<Real>::operator< (const Matrix2& rkM) const
00276 {
00277 return CompareArrays(rkM) < 0;
00278 }
00279
00280 template <class Real>
00281 bool Matrix2<Real>::operator<= (const Matrix2& rkM) const
00282 {
00283 return CompareArrays(rkM) <= 0;
00284 }
00285
00286 template <class Real>
00287 bool Matrix2<Real>::operator> (const Matrix2& rkM) const
00288 {
00289 return CompareArrays(rkM) > 0;
00290 }
00291
00292 template <class Real>
00293 bool Matrix2<Real>::operator>= (const Matrix2& rkM) const
00294 {
00295 return CompareArrays(rkM) >= 0;
00296 }
00297
00298 template <class Real>
00299 Matrix2<Real> Matrix2<Real>::operator+ (const Matrix2& rkM) const
00300 {
00301 return Matrix2<Real>(
00302 m_afEntry[0] + rkM.m_afEntry[0],
00303 m_afEntry[1] + rkM.m_afEntry[1],
00304 m_afEntry[2] + rkM.m_afEntry[2],
00305 m_afEntry[3] + rkM.m_afEntry[3]);
00306 }
00307
00308 template <class Real>
00309 Matrix2<Real> Matrix2<Real>::operator- (const Matrix2& rkM) const
00310 {
00311 return Matrix2<Real>(
00312 m_afEntry[0] - rkM.m_afEntry[0],
00313 m_afEntry[1] - rkM.m_afEntry[1],
00314 m_afEntry[2] - rkM.m_afEntry[2],
00315 m_afEntry[3] - rkM.m_afEntry[3]);
00316 }
00317
00318 template <class Real>
00319 Matrix2<Real> Matrix2<Real>::operator* (const Matrix2& rkM) const
00320 {
00321 return Matrix2<Real>(
00322 m_afEntry[0]*rkM.m_afEntry[0] + m_afEntry[1]*rkM.m_afEntry[2],
00323 m_afEntry[0]*rkM.m_afEntry[1] + m_afEntry[1]*rkM.m_afEntry[3],
00324 m_afEntry[2]*rkM.m_afEntry[0] + m_afEntry[3]*rkM.m_afEntry[2],
00325 m_afEntry[2]*rkM.m_afEntry[1] + m_afEntry[3]*rkM.m_afEntry[3]);
00326 }
00327
00328 template <class Real>
00329 Matrix2<Real> Matrix2<Real>::operator* (Real fScalar) const
00330 {
00331 return Matrix2<Real>(
00332 fScalar*m_afEntry[0],
00333 fScalar*m_afEntry[1],
00334 fScalar*m_afEntry[2],
00335 fScalar*m_afEntry[3]);
00336 }
00337
00338 template <class Real>
00339 Matrix2<Real> Matrix2<Real>::operator/ (Real fScalar) const
00340 {
00341 if (fScalar != (Real)0.0)
00342 {
00343 Real fInvScalar = ((Real)1.0)/fScalar;
00344 return Matrix2<Real>(
00345 fInvScalar*m_afEntry[0],
00346 fInvScalar*m_afEntry[1],
00347 fInvScalar*m_afEntry[2],
00348 fInvScalar*m_afEntry[3]);
00349 }
00350
00351 return Matrix2<Real>(
00352 Math<Real>::MAX_REAL,
00353 Math<Real>::MAX_REAL,
00354 Math<Real>::MAX_REAL,
00355 Math<Real>::MAX_REAL);
00356 }
00357
00358 template <class Real>
00359 Matrix2<Real> Matrix2<Real>::operator- () const
00360 {
00361 return Matrix2<Real>(
00362 -m_afEntry[0],
00363 -m_afEntry[1],
00364 -m_afEntry[2],
00365 -m_afEntry[3]);
00366 }
00367
00368 template <class Real>
00369 Matrix2<Real>& Matrix2<Real>::operator+= (const Matrix2& rkM)
00370 {
00371 m_afEntry[0] += rkM.m_afEntry[0];
00372 m_afEntry[1] += rkM.m_afEntry[1];
00373 m_afEntry[2] += rkM.m_afEntry[2];
00374 m_afEntry[3] += rkM.m_afEntry[3];
00375 return *this;
00376 }
00377
00378 template <class Real>
00379 Matrix2<Real>& Matrix2<Real>::operator-= (const Matrix2& rkM)
00380 {
00381 m_afEntry[0] -= rkM.m_afEntry[0];
00382 m_afEntry[1] -= rkM.m_afEntry[1];
00383 m_afEntry[2] -= rkM.m_afEntry[2];
00384 m_afEntry[3] -= rkM.m_afEntry[3];
00385 return *this;
00386 }
00387
00388 template <class Real>
00389 Matrix2<Real>& Matrix2<Real>::operator*= (Real fScalar)
00390 {
00391 m_afEntry[0] *= fScalar;
00392 m_afEntry[1] *= fScalar;
00393 m_afEntry[2] *= fScalar;
00394 m_afEntry[3] *= fScalar;
00395 return *this;
00396 }
00397
00398 template <class Real>
00399 Matrix2<Real>& Matrix2<Real>::operator/= (Real fScalar)
00400 {
00401 if (fScalar != (Real)0.0)
00402 {
00403 Real fInvScalar = ((Real)1.0)/fScalar;
00404 m_afEntry[0] *= fInvScalar;
00405 m_afEntry[1] *= fInvScalar;
00406 m_afEntry[2] *= fInvScalar;
00407 m_afEntry[3] *= fInvScalar;
00408 }
00409 else
00410 {
00411 m_afEntry[0] = Math<Real>::MAX_REAL;
00412 m_afEntry[1] = Math<Real>::MAX_REAL;
00413 m_afEntry[2] = Math<Real>::MAX_REAL;
00414 m_afEntry[3] = Math<Real>::MAX_REAL;
00415 }
00416
00417 return *this;
00418 }
00419
00420 template <class Real>
00421 Vector2<Real> Matrix2<Real>::operator* (const Vector2<Real>& rkV) const
00422 {
00423 return Vector2<Real>(
00424 m_afEntry[0]*rkV[0] + m_afEntry[1]*rkV[1],
00425 m_afEntry[2]*rkV[0] + m_afEntry[3]*rkV[1]);
00426 }
00427
00428 template <class Real>
00429 Matrix2<Real> Matrix2<Real>::Transpose () const
00430 {
00431 return Matrix2<Real>(
00432 m_afEntry[0],
00433 m_afEntry[2],
00434 m_afEntry[1],
00435 m_afEntry[3]);
00436 }
00437
00438 template <class Real>
00439 Matrix2<Real> Matrix2<Real>::TransposeTimes (const Matrix2& rkM) const
00440 {
00441
00442 return Matrix2<Real>(
00443 m_afEntry[0]*rkM.m_afEntry[0] + m_afEntry[2]*rkM.m_afEntry[2],
00444 m_afEntry[0]*rkM.m_afEntry[1] + m_afEntry[2]*rkM.m_afEntry[3],
00445 m_afEntry[1]*rkM.m_afEntry[0] + m_afEntry[3]*rkM.m_afEntry[2],
00446 m_afEntry[1]*rkM.m_afEntry[1] + m_afEntry[3]*rkM.m_afEntry[3]);
00447 }
00448
00449 template <class Real>
00450 Matrix2<Real> Matrix2<Real>::TimesTranspose (const Matrix2& rkM) const
00451 {
00452
00453 return Matrix2<Real>(
00454 m_afEntry[0]*rkM.m_afEntry[0] + m_afEntry[1]*rkM.m_afEntry[1],
00455 m_afEntry[0]*rkM.m_afEntry[2] + m_afEntry[1]*rkM.m_afEntry[3],
00456 m_afEntry[2]*rkM.m_afEntry[0] + m_afEntry[3]*rkM.m_afEntry[1],
00457 m_afEntry[2]*rkM.m_afEntry[2] + m_afEntry[3]*rkM.m_afEntry[3]);
00458 }
00459
00460 template <class Real>
00461 Matrix2<Real> Matrix2<Real>::Inverse () const
00462 {
00463 Matrix2<Real> kInverse;
00464
00465 Real fDet = m_afEntry[0]*m_afEntry[3] - m_afEntry[1]*m_afEntry[2];
00466 if (Math<Real>::FAbs(fDet) > Math<Real>::ZERO_TOLERANCE)
00467 {
00468 Real fInvDet = ((Real)1.0)/fDet;
00469 kInverse.m_afEntry[0] = m_afEntry[3]*fInvDet;
00470 kInverse.m_afEntry[1] = -m_afEntry[1]*fInvDet;
00471 kInverse.m_afEntry[2] = -m_afEntry[2]*fInvDet;
00472 kInverse.m_afEntry[3] = m_afEntry[0]*fInvDet;
00473 }
00474 else
00475 {
00476 kInverse.m_afEntry[0] = (Real)0.0;
00477 kInverse.m_afEntry[1] = (Real)0.0;
00478 kInverse.m_afEntry[2] = (Real)0.0;
00479 kInverse.m_afEntry[3] = (Real)0.0;
00480 }
00481
00482 return kInverse;
00483 }
00484
00485 template <class Real>
00486 Matrix2<Real> Matrix2<Real>::Adjoint () const
00487 {
00488 return Matrix2<Real>(
00489 m_afEntry[3],
00490 -m_afEntry[1],
00491 -m_afEntry[2],
00492 m_afEntry[0]);
00493 }
00494
00495 template <class Real>
00496 Real Matrix2<Real>::Determinant () const
00497 {
00498 return m_afEntry[0]*m_afEntry[3] - m_afEntry[1]*m_afEntry[2];
00499 }
00500
00501 template <class Real>
00502 Real Matrix2<Real>::QForm (const Vector2<Real>& rkU,
00503 const Vector2<Real>& rkV) const
00504 {
00505 return rkU.Dot((*this)*rkV);
00506 }
00507
00508 template <class Real>
00509 void Matrix2<Real>::ToAngle (Real& rfAngle) const
00510 {
00511
00512 rfAngle = Math<Real>::ATan2(m_afEntry[2],m_afEntry[0]);
00513 }
00514
00515 template <class Real>
00516 void Matrix2<Real>::Orthonormalize ()
00517 {
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528 Real fInvLength = Math<Real>::InvSqrt(m_afEntry[0]*m_afEntry[0] +
00529 m_afEntry[2]*m_afEntry[2]);
00530
00531 m_afEntry[0] *= fInvLength;
00532 m_afEntry[2] *= fInvLength;
00533
00534
00535 Real fDot0 = m_afEntry[0]*m_afEntry[1] + m_afEntry[2]*m_afEntry[3];
00536 m_afEntry[1] -= fDot0*m_afEntry[0];
00537 m_afEntry[3] -= fDot0*m_afEntry[2];
00538
00539 fInvLength = Math<Real>::InvSqrt(m_afEntry[1]*m_afEntry[1] +
00540 m_afEntry[3]*m_afEntry[3]);
00541
00542 m_afEntry[1] *= fInvLength;
00543 m_afEntry[3] *= fInvLength;
00544 }
00545
00546 template <class Real>
00547 void Matrix2<Real>::EigenDecomposition (Matrix2& rkRot, Matrix2& rkDiag) const
00548 {
00549 Real fTrace = m_afEntry[0] + m_afEntry[3];
00550 Real fDiff = m_afEntry[0] - m_afEntry[3];
00551 Real fDiscr = Math<Real>::Sqrt(fDiff*fDiff +
00552 ((Real)4.0)*m_afEntry[1]*m_afEntry[1]);
00553 Real fEVal0 = ((Real)0.5)*(fTrace-fDiscr);
00554 Real fEVal1 = ((Real)0.5)*(fTrace+fDiscr);
00555 rkDiag.MakeDiagonal(fEVal0,fEVal1);
00556
00557 Real fCos, fSin;
00558 if (fDiff >= (Real)0.0)
00559 {
00560 fCos = m_afEntry[1];
00561 fSin = fEVal0 - m_afEntry[0];
00562 }
00563 else
00564 {
00565 fCos = fEVal0 - m_afEntry[3];
00566 fSin = m_afEntry[1];
00567 }
00568 Real fTmp = Math<Real>::InvSqrt(fCos*fCos + fSin*fSin);
00569 fCos *= fTmp;
00570 fSin *= fTmp;
00571
00572 rkRot.m_afEntry[0] = fCos;
00573 rkRot.m_afEntry[1] = -fSin;
00574 rkRot.m_afEntry[2] = fSin;
00575 rkRot.m_afEntry[3] = fCos;
00576 }
00577
00578 template <class Real>
00579 Matrix2<Real> operator* (Real fScalar, const Matrix2<Real>& rkM)
00580 {
00581 return rkM*fScalar;
00582 }
00583
00584 template <class Real>
00585 Vector2<Real> operator* (const Vector2<Real>& rkV, const Matrix2<Real>& rkM)
00586 {
00587 return Vector2<Real>(
00588 rkV[0]*rkM[0][0] + rkV[1]*rkM[1][0],
00589 rkV[0]*rkM[0][1] + rkV[1]*rkM[1][1]);
00590 }
00591
00592 }
00593