Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members

Matrix33.h

00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004     (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright (c) 2000-2005 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 -----------------------------------------------------------------------------
00024 */
00025 #ifndef __MATRIX33_H__
00026 #define __MATRIX33_H__
00027 
00028 
00029 #include "peonstdafx.h"
00030 #include "Vector3.h"
00031 
00032 
00033 // NB All code adapted from Wild Magic 0.2 Matrix math (free source code)
00034 // http://www.magic-software.com
00035 
00036 // NOTE.  The (x,y,z) coordinate system is assumed to be right-handed.
00037 // Coordinate axis rotation matrices are of the form
00038 //   RX =    1       0       0
00039 //           0     cos(t) -sin(t)
00040 //           0     sin(t)  cos(t)
00041 // where t > 0 indicates a counterclockwise rotation in the yz-plane
00042 //   RY =  cos(t)    0     sin(t)
00043 //           0       1       0
00044 //        -sin(t)    0     cos(t)
00045 // where t > 0 indicates a counterclockwise rotation in the zx-plane
00046 //   RZ =  cos(t) -sin(t)    0
00047 //         sin(t)  cos(t)    0
00048 //           0       0       1
00049 // where t > 0 indicates a counterclockwise rotation in the xy-plane.
00050 
00051 namespace peon
00052 {
00060     class _PeonExport Matrix33
00061     {
00062     public:
00067                 inline Matrix33 () {};
00068         inline explicit Matrix33 (const Real arr[3][3])
00069                 {
00070                         memcpy(m,arr,9*sizeof(Real));
00071                 }
00072         inline Matrix33 (const Matrix33& rkMatrix)
00073                 {
00074                         memcpy(m,rkMatrix.m,9*sizeof(Real));
00075                 }
00076         Matrix33 (Real fEntry00, Real fEntry01, Real fEntry02,
00077                     Real fEntry10, Real fEntry11, Real fEntry12,
00078                     Real fEntry20, Real fEntry21, Real fEntry22)
00079                 {
00080                         m[0][0] = fEntry00;
00081                         m[0][1] = fEntry01;
00082                         m[0][2] = fEntry02;
00083                         m[1][0] = fEntry10;
00084                         m[1][1] = fEntry11;
00085                         m[1][2] = fEntry12;
00086                         m[2][0] = fEntry20;
00087                         m[2][1] = fEntry21;
00088                         m[2][2] = fEntry22;
00089                 }
00090 
00091         // member access, allows use of construct mat[r][c]
00092         inline Real* operator[] (size_t iRow) const
00093                 {
00094                         return (Real*)m[iRow];
00095                 }
00096         /*inline operator Real* ()
00097                 {
00098                         return (Real*)m[0];
00099                 }*/
00100         Vector3 GetColumn (size_t iCol) const;
00101         void SetColumn(size_t iCol, const Vector3& vec);
00102         void FromAxes(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis);
00103 
00104         // assignment and comparison
00105         inline Matrix33& operator= (const Matrix33& rkMatrix)
00106                 {
00107                         memcpy(m,rkMatrix.m,9*sizeof(Real));
00108                         return *this;
00109                 }
00110         bool operator== (const Matrix33& rkMatrix) const;
00111         inline bool operator!= (const Matrix33& rkMatrix) const
00112                 {
00113                         return !operator==(rkMatrix);
00114                 }
00115 
00116         // arithmetic operations
00117         Matrix33 operator+ (const Matrix33& rkMatrix) const;
00118         Matrix33 operator- (const Matrix33& rkMatrix) const;
00119         Matrix33 operator* (const Matrix33& rkMatrix) const;
00120         Matrix33 operator- () const;
00121 
00122         // matrix * vector [3x3 * 3x1 = 3x1]
00123         Vector3 operator* (const Vector3& rkVector) const;
00124 
00125         // vector * matrix [1x3 * 3x3 = 1x3]
00126         _PeonExport friend Vector3 operator* (const Vector3& rkVector,
00127             const Matrix33& rkMatrix);
00128 
00129         // matrix * scalar
00130         Matrix33 operator* (Real fScalar) const;
00131 
00132         // scalar * matrix
00133         _PeonExport friend Matrix33 operator* (Real fScalar, const Matrix33& rkMatrix);
00134 
00135         // utilities
00136         Matrix33 Transpose () const;
00137         bool Inverse (Matrix33& rkInverse, Real fTolerance = 1e-06) const;
00138         Matrix33 Inverse (Real fTolerance = 1e-06) const;
00139         Real Determinant () const;
00140 
00141         // singular value decomposition
00142         void SingularValueDecomposition (Matrix33& rkL, Vector3& rkS,
00143             Matrix33& rkR) const;
00144         void SingularValueComposition (const Matrix33& rkL,
00145             const Vector3& rkS, const Matrix33& rkR);
00146 
00147         // Gram-Schmidt orthonormalization (applied to columns of rotation matrix)
00148         void Orthonormalize ();
00149 
00150         // orthogonal Q, diagonal D, upper triangular U stored as (u01,u02,u12)
00151         void QDUDecomposition (Matrix33& rkQ, Vector3& rkD,
00152             Vector3& rkU) const;
00153 
00154         Real SpectralNorm () const;
00155 
00156         // matrix must be orthonormal
00157         void ToAxisAngle (Vector3& rkAxis, Radian& rfAngle) const;
00158                 inline void ToAxisAngle (Vector3& rkAxis, Degree& rfAngle) const {
00159                         Radian r;
00160                         ToAxisAngle ( rkAxis, r );
00161                         rfAngle = r;
00162                 }
00163         void FromAxisAngle (const Vector3& rkAxis, const Radian& fRadians);
00164 #ifndef OGRE_FORCE_ANGLE_TYPES
00165         inline void ToAxisAngle (Vector3& rkAxis, Real& rfRadians) const {
00166                         Radian r;
00167                         ToAxisAngle ( rkAxis, r );
00168                         rfRadians = r.valueRadians();
00169                 }
00170         inline void FromAxisAngle (const Vector3& rkAxis, Real fRadians) {
00171                         FromAxisAngle ( rkAxis, Radian(fRadians) );
00172                 }
00173 #endif//OGRE_FORCE_ANGLE_TYPES
00174 
00175         // The matrix must be orthonormal.  The decomposition is yaw*pitch*roll
00176         // where yaw is rotation about the Up vector, pitch is rotation about the
00177         // Right axis, and roll is rotation about the Direction axis.
00178         bool ToEulerAnglesXYZ (Radian& rfYAngle, Radian& rfPAngle,
00179             Radian& rfRAngle) const;
00180         bool ToEulerAnglesXZY (Radian& rfYAngle, Radian& rfPAngle,
00181             Radian& rfRAngle) const;
00182         bool ToEulerAnglesYXZ (Radian& rfYAngle, Radian& rfPAngle,
00183             Radian& rfRAngle) const;
00184         bool ToEulerAnglesYZX (Radian& rfYAngle, Radian& rfPAngle,
00185             Radian& rfRAngle) const;
00186         bool ToEulerAnglesZXY (Radian& rfYAngle, Radian& rfPAngle,
00187             Radian& rfRAngle) const;
00188         bool ToEulerAnglesZYX (Radian& rfYAngle, Radian& rfPAngle,
00189             Radian& rfRAngle) const;
00190         void FromEulerAnglesXYZ (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
00191         void FromEulerAnglesXZY (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
00192         void FromEulerAnglesYXZ (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
00193         void FromEulerAnglesYZX (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
00194         void FromEulerAnglesZXY (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
00195         void FromEulerAnglesZYX (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
00196 #ifndef OGRE_FORCE_ANGLE_TYPES
00197         inline bool ToEulerAnglesXYZ (float& rfYAngle, float& rfPAngle,
00198             float& rfRAngle) const {
00199                         Radian y, p, r;
00200                         bool b = ToEulerAnglesXYZ(y,p,r);
00201                         rfYAngle = y.valueRadians();
00202                         rfPAngle = p.valueRadians();
00203                         rfRAngle = r.valueRadians();
00204                         return b;
00205                 }
00206         inline bool ToEulerAnglesXZY (float& rfYAngle, float& rfPAngle,
00207             float& rfRAngle) const {
00208                         Radian y, p, r;
00209                         bool b = ToEulerAnglesXZY(y,p,r);
00210                         rfYAngle = y.valueRadians();
00211                         rfPAngle = p.valueRadians();
00212                         rfRAngle = r.valueRadians();
00213                         return b;
00214                 }
00215         inline bool ToEulerAnglesYXZ (float& rfYAngle, float& rfPAngle,
00216             float& rfRAngle) const {
00217                         Radian y, p, r;
00218                         bool b = ToEulerAnglesYXZ(y,p,r);
00219                         rfYAngle = y.valueRadians();
00220                         rfPAngle = p.valueRadians();
00221                         rfRAngle = r.valueRadians();
00222                         return b;
00223                 }
00224         inline bool ToEulerAnglesYZX (float& rfYAngle, float& rfPAngle,
00225             float& rfRAngle) const {
00226                         Radian y, p, r;
00227                         bool b = ToEulerAnglesYZX(y,p,r);
00228                         rfYAngle = y.valueRadians();
00229                         rfPAngle = p.valueRadians();
00230                         rfRAngle = r.valueRadians();
00231                         return b;
00232                 }
00233         inline bool ToEulerAnglesZXY (float& rfYAngle, float& rfPAngle,
00234             float& rfRAngle) const {
00235                         Radian y, p, r;
00236                         bool b = ToEulerAnglesZXY(y,p,r);
00237                         rfYAngle = y.valueRadians();
00238                         rfPAngle = p.valueRadians();
00239                         rfRAngle = r.valueRadians();
00240                         return b;
00241                 }
00242         inline bool ToEulerAnglesZYX (float& rfYAngle, float& rfPAngle,
00243             float& rfRAngle) const {
00244                         Radian y, p, r;
00245                         bool b = ToEulerAnglesZYX(y,p,r);
00246                         rfYAngle = y.valueRadians();
00247                         rfPAngle = p.valueRadians();
00248                         rfRAngle = r.valueRadians();
00249                         return b;
00250                 }
00251         inline void FromEulerAnglesXYZ (float fYAngle, float fPAngle, float fRAngle) {
00252                         FromEulerAnglesXYZ ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) );
00253                 }
00254         inline void FromEulerAnglesXZY (float fYAngle, float fPAngle, float fRAngle) {
00255                         FromEulerAnglesXZY ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) );
00256                 }
00257         inline void FromEulerAnglesYXZ (float fYAngle, float fPAngle, float fRAngle) {
00258                         FromEulerAnglesYXZ ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) );
00259                 }
00260         inline void FromEulerAnglesYZX (float fYAngle, float fPAngle, float fRAngle) {
00261                         FromEulerAnglesYZX ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) );
00262                 }
00263         inline void FromEulerAnglesZXY (float fYAngle, float fPAngle, float fRAngle) {
00264                         FromEulerAnglesZXY ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) );
00265                 }
00266         inline void FromEulerAnglesZYX (float fYAngle, float fPAngle, float fRAngle) {
00267                         FromEulerAnglesZYX ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) );
00268                 }
00269 #endif//OGRE_FORCE_ANGLE_TYPES
00270         // eigensolver, matrix must be symmetric
00271         void EigenSolveSymmetric (Real afEigenvalue[3],
00272             Vector3 akEigenvector[3]) const;
00273 
00274         static void TensorProduct (const Vector3& rkU, const Vector3& rkV,
00275             Matrix33& rkProduct);
00276 
00277         static const Real EPSILON;
00278         static const Matrix33 ZERO;
00279         static const Matrix33 IDENTITY;
00280 
00281     protected:
00282         // support for eigensolver
00283         void Tridiagonal (Real afDiag[3], Real afSubDiag[3]);
00284         bool QLAlgorithm (Real afDiag[3], Real afSubDiag[3]);
00285 
00286         // support for singular value decomposition
00287         static const Real ms_fSvdEpsilon;
00288         static const unsigned int ms_iSvdMaxIterations;
00289         static void Bidiagonalize (Matrix33& kA, Matrix33& kL,
00290             Matrix33& kR);
00291         static void GolubKahanStep (Matrix33& kA, Matrix33& kL,
00292             Matrix33& kR);
00293 
00294         // support for spectral norm
00295         static Real MaxCubicRoot (Real afCoeff[3]);
00296 
00297         Real m[3][3];
00298 
00299         // for faster access
00300         friend class Matrix44;
00301     };
00302 }
00303 #endif

Generated on Wed Nov 9 09:37:05 2005 for Peon by  doxygen 1.4.3