Wm4Matrix2.h

Go to the documentation of this file.
00001 // Wild Magic Source Code
00002 // David Eberly
00003 // http://www.geometrictools.com
00004 // Copyright (c) 1998-2007
00005 //
00006 // This library is free software; you can redistribute it and/or modify it
00007 // under the terms of the GNU Lesser General Public License as published by
00008 // the Free Software Foundation; either version 2.1 of the License, or (at
00009 // your option) any later version.  The license is available for reading at
00010 // either of the locations:
00011 //     http://www.gnu.org/copyleft/lgpl.html
00012 //     http://www.geometrictools.com/License/WildMagicLicense.pdf
00013 // The license applies to versions 0 through 4 of Wild Magic.
00014 //
00015 // Version: 4.0.1 (2006/08/19)
00016 
00017 #ifndef WM4MATRIX2_H
00018 #define WM4MATRIX2_H
00019 
00020 // Matrix operations are applied on the left.  For example, given a matrix M
00021 // and a vector V, matrix-times-vector is M*V.  That is, V is treated as a
00022 // column vector.  Some graphics APIs use V*M where V is treated as a row
00023 // vector.  In this context the "M" matrix is really a transpose of the M as
00024 // represented in Wild Magic.  Similarly, to apply two matrix operations M0
00025 // and M1, in that order, you compute M1*M0 so that the transform of a vector
00026 // is (M1*M0)*V = M1*(M0*V).  Some graphics APIs use M0*M1, but again these
00027 // matrices are the transpose of those as represented in Wild Magic.  You
00028 // must therefore be careful about how you interface the transformation code
00029 // with graphics APIS.
00030 //
00031 // For memory organization it might seem natural to chose Real[N][N] for the
00032 // matrix storage, but this can be a problem on a platform/console that
00033 // chooses to store the data in column-major rather than row-major format.
00034 // To avoid potential portability problems, the matrix is stored as Real[N*N]
00035 // and organized in row-major order.  That is, the entry of the matrix in row
00036 // r (0 <= r < N) and column c (0 <= c < N) is stored at index i = c+N*r
00037 // (0 <= i < N*N).
00038 
00039 // Rotation matrices are of the form
00040 //   R = cos(t) -sin(t)
00041 //       sin(t)  cos(t)
00042 // where t > 0 indicates a counterclockwise rotation in the xy-plane.
00043 
00044 #include "Wm4FoundationLIB.h"
00045 #include "Wm4Vector2.h"
00046 
00047 namespace Wm4
00048 {
00049 
00050 template <class Real>
00051 class Matrix2
00052 {
00053 public:
00054     // If bZero is true, create the zero matrix.  Otherwise, create the
00055     // identity matrix.
00056     Matrix2 (bool bZero = true);
00057 
00058     // copy constructor
00059     Matrix2 (const Matrix2& rkM);
00060 
00061     // input Mrc is in row r, column c.
00062     Matrix2 (Real fM00, Real fM01, Real fM10, Real fM11);
00063 
00064     // Create a matrix from an array of numbers.  The input array is
00065     // interpreted based on the Boolean input as
00066     //   true:  entry[0..3] = {m00,m01,m10,m11}  [row major]
00067     //   false: entry[0..3] = {m00,m10,m01,m11}  [column major]
00068     Matrix2 (const Real afEntry[4], bool bRowMajor);
00069 
00070     // Create matrices based on vector input.  The Boolean is interpreted as
00071     //   true: vectors are columns of the matrix
00072     //   false: vectors are rows of the matrix
00073     Matrix2 (const Vector2<Real>& rkU, const Vector2<Real>& rkV,
00074         bool bColumns);
00075     Matrix2 (const Vector2<Real>* akV, bool bColumns);
00076 
00077     // create a diagonal matrix
00078     Matrix2 (Real fM00, Real fM11);
00079 
00080     // create a rotation matrix (positive angle - counterclockwise)
00081     Matrix2 (Real fAngle);
00082 
00083     // create a tensor product U*V^T
00084     Matrix2 (const Vector2<Real>& rkU, const Vector2<Real>& rkV);
00085 
00086     // create various matrices
00087     void MakeZero ();
00088     void MakeIdentity ();
00089     void MakeDiagonal (Real fM00, Real fM11);
00090     void FromAngle (Real fAngle);
00091     void MakeTensorProduct (const Vector2<Real>& rkU,
00092         const Vector2<Real>& rkV);
00093 
00094     // member access
00095     operator const Real* () const;
00096     operator Real* ();
00097     const Real* operator[] (int iRow) const;
00098     Real* operator[] (int iRow);
00099     Real operator() (int iRow, int iCol) const;
00100     Real& operator() (int iRow, int iCol);
00101     void SetRow (int iRow, const Vector2<Real>& rkV);
00102     Vector2<Real> GetRow (int iRow) const;
00103     void SetColumn (int iCol, const Vector2<Real>& rkV);
00104     Vector2<Real> GetColumn (int iCol) const;
00105     void GetColumnMajor (Real* afCMajor) const;
00106 
00107     // assignment
00108     Matrix2& operator= (const Matrix2& rkM);
00109 
00110     // comparison
00111     bool operator== (const Matrix2& rkM) const;
00112     bool operator!= (const Matrix2& rkM) const;
00113     bool operator<  (const Matrix2& rkM) const;
00114     bool operator<= (const Matrix2& rkM) const;
00115     bool operator>  (const Matrix2& rkM) const;
00116     bool operator>= (const Matrix2& rkM) const;
00117 
00118     // arithmetic operations
00119     Matrix2 operator+ (const Matrix2& rkM) const;
00120     Matrix2 operator- (const Matrix2& rkM) const;
00121     Matrix2 operator* (const Matrix2& rkM) const;
00122     Matrix2 operator* (Real fScalar) const;
00123     Matrix2 operator/ (Real fScalar) const;
00124     Matrix2 operator- () const;
00125 
00126     // arithmetic updates
00127     Matrix2& operator+= (const Matrix2& rkM);
00128     Matrix2& operator-= (const Matrix2& rkM);
00129     Matrix2& operator*= (Real fScalar);
00130     Matrix2& operator/= (Real fScalar);
00131 
00132     // matrix times vector
00133     Vector2<Real> operator* (const Vector2<Real>& rkV) const;  // M * v
00134 
00135     // other operations
00136     Matrix2 Transpose () const;  // M^T
00137     Matrix2 TransposeTimes (const Matrix2& rkM) const;  // this^T * M
00138     Matrix2 TimesTranspose (const Matrix2& rkM) const;  // this * M^T
00139     Matrix2 Inverse () const;
00140     Matrix2 Adjoint () const;
00141     Real Determinant () const;
00142     Real QForm (const Vector2<Real>& rkU,
00143         const Vector2<Real>& rkV) const;  // u^T*M*v
00144 
00145     // The matrix must be a rotation for these functions to be valid.  The
00146     // last function uses Gram-Schmidt orthonormalization applied to the
00147     // columns of the rotation matrix.  The angle must be in radians, not
00148     // degrees.
00149     void ToAngle (Real& rfAngle) const;
00150     void Orthonormalize ();
00151 
00152     // The matrix must be symmetric.  Factor M = R * D * R^T where
00153     // R = [u0|u1] is a rotation matrix with columns u0 and u1 and
00154     // D = diag(d0,d1) is a diagonal matrix whose diagonal entries are d0 and
00155     // d1.  The eigenvector u[i] corresponds to eigenvector d[i].  The
00156     // eigenvalues are ordered as d0 <= d1.
00157     void EigenDecomposition (Matrix2& rkRot, Matrix2& rkDiag) const;
00158 
00159     WM4_FOUNDATION_ITEM static const Matrix2 ZERO;
00160     WM4_FOUNDATION_ITEM static const Matrix2 IDENTITY;
00161 
00162 private:
00163     // support for comparisons
00164     int CompareArrays (const Matrix2& rkM) const;
00165 
00166     // matrix stored in row-major order
00167     Real m_afEntry[4];
00168 };
00169 
00170 // c * M
00171 template <class Real>
00172 Matrix2<Real> operator* (Real fScalar, const Matrix2<Real>& rkM);
00173 
00174 // v^T * M
00175 template <class Real>
00176 Vector2<Real> operator* (const Vector2<Real>& rkV, const Matrix2<Real>& rkM);
00177 
00178 } //namespace Wm4
00179 
00180 #include "Wm4Matrix2.inl"
00181 
00182 namespace Wm4
00183 {
00184 typedef Matrix2<float> Matrix2f;
00185 typedef Matrix2<double> Matrix2d;
00186 }
00187 
00188 #endif

Generated on Wed Nov 23 19:01:05 2011 for FreeCAD by  doxygen 1.6.1