Matrix.h

Go to the documentation of this file.
00001 /**<!-------------------------------------------------------------------->
00002    @class  Matrix
00003    @author Travis Fischer (fisch0920@gmail.com)
00004    @date   Fall 2008
00005    
00006    @brief
00007       Provides basic functionality for a templated, arbitrarily-sized matrix
00008    
00009    A Matrix is templated to store M rows and N columns of data of 
00010    type T.  If left off, T will default to a "real_t" data type. Also, if N 
00011    is not specified, the template will default to a square MxM matrix.
00012    
00013    Included in this definition are typedefs for the most commonly used 
00014    matrices (4x4, 3x3, etc), and these can be thought of as shortcuts to 
00015    reference their associated Matrix templates.  For example, 
00016    Matrix4x4 can be used to refer to Matrix<4, 4, real_t>.
00017    
00018    A Matrix stores each of its M rows internally as an 
00019    N-length Vector called rows which has been defined as:
00020    
00021       Vector<N, T> rows[M];
00022    <!-------------------------------------------------------------------->**/
00023 
00024 #ifndef MATRIX_H_
00025 #define MATRIX_H_
00026 
00027 #include <common/math/Point.h>
00028 #include <ostream>
00029 
00030 #define MATRIX_NO_ELEMENTS    (M * N)
00031 #define MATRIX_SIZE           (sizeof(T) * MATRIX_NO_ELEMENTS)
00032 
00033 /**
00034  * @brief
00035  *    A Matrix is templated to store M rows and N columns of data of 
00036  * type T.  If left off, T will default to a "real_t" data type. Also, if N 
00037  * is not specified, the template will default to a square MxM matrix.
00038  * 
00039  * Included in this definition are typedefs for the most commonly used 
00040  * matrices (4x4, 3x3, etc), and these can be thought of as shortcuts to 
00041  * reference their associated Matrix templates.  For example, 
00042  * Matrix4x4 can be used to refer to Matrix<4, 4, real_t>.
00043  * 
00044  * A Matrix stores each of its M rows internally as an 
00045  * N-length Vector.
00046  */
00047 template <unsigned M, unsigned N = M, typename T = real_t>
00048 struct Matrix {
00049    
00050    /// Underlying data, where each row is stored in a separate Vector
00051    Vector<N, T> rows[M];
00052    
00053    
00054    ///@name Constructors
00055    //@{-----------------------------------------------------------------
00056    
00057    /// Expects arguments in row-major order
00058    inline Matrix(const T *srcData);
00059    
00060    /// Constructs a zero Matrix
00061    inline Matrix();
00062    
00063    /// Copy Constructor
00064    inline Matrix(const Matrix<M, N, T> &m);
00065    
00066    
00067    //@}-----------------------------------------------------------------
00068    ///@name Static convenience constructors to generate common matrices
00069    //@{-----------------------------------------------------------------
00070    
00071    /// Generates a matrix full of zeroes
00072    static inline Matrix zero() {
00073       return Matrix<M, N, T>();
00074    }
00075    
00076    /// Generates an identity matrix
00077    static Matrix identity() {
00078       return Matrix<M, N, T>::diagonal(1);
00079    }
00080    
00081    /// Generates a diagonal matrix with the value specified
00082    static Matrix diagonal(T diagonalValue) {
00083       T d[MATRIX_NO_ELEMENTS];
00084       
00085       memset(d, 0, MATRIX_SIZE);
00086       
00087       for(unsigned i = M; i--;)
00088          d[i * N + i] = diagonalValue;
00089       
00090       return Matrix<M, N, T>(d);
00091    }
00092    
00093    
00094    //@}-----------------------------------------------------------------
00095    ///@name Accessor Operators
00096    //@{-----------------------------------------------------------------
00097    
00098    /// @returns a const reference to the row at the given index
00099    inline const Vector<N, T>   &operator[](const unsigned rowIndex) const;
00100    /// @returns a       reference to the row at the given index
00101    /// @note changes to the returned vector will affect this matrix
00102    inline       Vector<N, T>   &operator[](const unsigned rowIndex);
00103    
00104    /// @returns a const pointer to the raw, underlying data
00105    ///    (row-major, M*N-length array of type T)
00106    inline const T *operator*() const;
00107    /// @returns a pointer to the raw, underlying data
00108    ///    (row-major, M*N-length array of type T)
00109    inline       T *operator*();
00110    
00111    
00112    //@}-----------------------------------------------------------------
00113    ///@name Equality Operators
00114    //@{-----------------------------------------------------------------
00115    
00116    inline       bool       operator==(const Matrix<M, N, T> &m) const;
00117    inline       bool       operator!=(const Matrix<M, N, T> &m) const;
00118    
00119    
00120    //@}-----------------------------------------------------------------
00121    ///@name Mutator Operators
00122    //@{-----------------------------------------------------------------
00123    
00124    inline       Matrix<M, N, T> &operator =(const Matrix<M, N, T> &m);
00125    inline       Matrix<M, N, T> &operator+=(const Matrix<M, N, T> &rhs);
00126    inline       Matrix<M, N, T> &operator-=(const Matrix<M, N, T> &rhs);
00127    inline       Matrix<M, N, T> &operator*=(const Matrix<M, N, T> &rhs);
00128    
00129    
00130    //@}-----------------------------------------------------------------
00131    ///@name Scalar Mutator Operators
00132    //@{-----------------------------------------------------------------
00133    
00134    inline       Matrix<M, N, T> &operator*=(const T &scale);
00135    inline       Matrix<M, N, T> &operator/=(const T &scale);
00136    
00137    
00138    //@}-----------------------------------------------------------------
00139    ///@name Arithmetic Operators
00140    //@{-----------------------------------------------------------------
00141    
00142    inline       Matrix<M, N, T>  operator+ (const Matrix<M, N, T> &rhs) const;
00143    inline       Matrix<M, N, T>  operator- (const Matrix<M, N, T> &rhs) const;
00144    
00145    /// MxN (square) matrix * MxN (square) matrix yields an MxN (square) matrix
00146    inline       Matrix<M, N, T>  operator* (const Matrix<M, N, T> &rhs) const;
00147    
00148    /// MxN matrix * N-length column vector yields an M-length vector
00149    /// @note this method returns an M-length Vector. Make sure you understand why.
00150    inline       Point<M, T>      operator* (const Point<N, T> &rhs) const;
00151    inline       Vector<M, T>     operator* (const Vector<N, T> &rhs) const;
00152    inline       Vector<M - 1, T> operator* (const Vector<N - 1, T> &rhs) const;
00153    
00154    
00155    //@}-----------------------------------------------------------------
00156    ///@name Scalar Arithmetic Operators
00157    //@{-----------------------------------------------------------------
00158    
00159    inline       Matrix<M, N, T>  operator* (const T &scale) const;
00160    inline       Matrix<M, N, T>  operator/ (const T &scale) const;
00161    
00162    
00163    //@}-----------------------------------------------------------------
00164    ///@name More Complex Functionality
00165    //@{-----------------------------------------------------------------
00166    
00167    /// @returns whether or not this Matrix is diagonal
00168    inline bool isDiagonal() const;
00169    
00170    /// @returns a Vector containing the index'th row of this matrix
00171    /// @note Modifying the Vector returned will directly affect this Matrix's data
00172    inline Vector<N, T> &row(unsigned index);
00173    
00174    /// @returns a Vector containing the index'th row of this matrix
00175    /// @note Modifying the Vector returned will Not affect this Matrix's data
00176    inline Vector<N, T>  row(unsigned index) const;
00177    
00178    /// @returns a Vector containing the index'th column of this matrix
00179    /// @note Modifying the Vector returned will Not affect this Matrix's data
00180    inline Vector<M, T>  col(unsigned index) const;
00181    
00182    /// Sets the index'th column of this matrix to the given Vector
00183    inline Matrix<M, N, T> &setCol(unsigned index,
00184                                        const Vector<M, T> &vec);
00185    
00186    /// @returns the transpose of this matrix
00187    const Matrix<M, N, T> getTranspose() const;
00188    
00189    /**
00190     * Fills the data provided with the transpose of this matrix (since OpenGL 
00191     * matrices are stored in column-major format).
00192     */
00193    void fillGLMatrix(T *bufferToFill) const;
00194    
00195    /**
00196     * @returns true if this matrix is strictly upper-triangular. An upper-
00197     *    triangular matrix contains only zeros below its diagonal (but may 
00198     *    contain non-zero values on and above its diagonal).
00199     * 
00200     * Example 4x4 upper triangular matrix:
00201     *    [ 1 2 3 4 ] 
00202     *    [ 0 5 6 7 ]
00203     *    [ 0 0 0 8 ] 
00204     *    [ 0 0 0 9 ]
00205     *
00206     * Example 4x4 non upper triangular matrix:
00207     *    [ 1 2 3 4 ]
00208     *    [ 0 5 6 7 ]
00209     *    [ 8 0 0 9 ]
00210     *    [ 0 0 0 0 ]
00211     */
00212    bool isUpperTriangular() const;
00213    
00214    /**
00215     * @returns true if this matrix is strictly lower-triangular. An lower-
00216     *    triangular matrix contains only zeros above its diagonal (but may 
00217     *    contain non-zero values on and below its diagonal).
00218     * 
00219     * Example 4x4  triangular matrix:
00220     *    [ 1 0 0 0 ] 
00221     *    [ 2 3 0 0 ]
00222     *    [ 4 5 0 0 ] 
00223     *    [ 6 7 8 9 ]
00224     *
00225     * Example 4x4 non upper triangular matrix:
00226     *    [ 1 0 0 2 ]
00227     *    [ 3 4 0 5 ]
00228     *    [ 6 7 8 0 ]
00229     *    [ 0 0 0 0 ]
00230     */
00231    bool isLowerTriangular() const;
00232    
00233    /// @returns the inverse of this matrix, assuming it exists
00234    Matrix<M, N, T> getInverse() const;
00235    
00236    /// @returns the determinant of this matrix
00237    T getDeterminant() const;
00238    
00239    /// Cleans up a matrix (0's out entries that are less than epsilon)
00240    void cleanup();
00241    
00242    /// Convenience Constructor
00243    explicit Matrix(const T &v0,      const T &v1 = 0,  const T &v2 = 0, 
00244                    const T &v3 = 0,  const T &v4 = 0,  const T &v5 = 0, 
00245                    const T &v6 = 0,  const T &v7 = 0,  const T &v8 = 0, 
00246                    const T &v9 = 0,  const T &v10 = 0, const T &v11 = 0, 
00247                    const T &v12 = 0, const T &v13 = 0, const T &v14 = 0, 
00248                    const T &v15 = 0);
00249 
00250    //@}-----------------------------------------------------------------
00251 };
00252 
00253 
00254 /// Standard 4x4 matrix of real_ts
00255 typedef Matrix<4, 4> Matrix4x4;
00256 
00257 /// Standard 3x3 matrix of real_ts
00258 typedef Matrix<3, 3> Matrix3x3;
00259 
00260 /// Standard 2x2 matrix of real_ts
00261 typedef Matrix<2, 2> Matrix2x2;
00262 
00263 
00264 ///@name Extra operators where Matrix is on right-hand side
00265 //@{-----------------------------------------------------------------------------
00266 
00267 /// 1xM row vector * MxN matrix yields a 1xN vector
00268 template <unsigned M, unsigned N, typename T>
00269    inline Vector<N, T>    operator* (const Vector<M, T> &lhs, const Matrix<M, N, T> &rhs);
00270 
00271 /// @returns the MxN matrix resulting from multiplying a scalar by an MxN matrix
00272 template <unsigned M, unsigned N, typename T>
00273    inline Matrix<M, N, T> operator* (const T &scale, const Matrix<M, N, T> &rhs);
00274 
00275 /// Prints a Matrix to an output stream
00276 template <unsigned M, unsigned N, typename T>
00277    inline std::ostream        &operator<<(std::ostream &os, const Matrix<M, N, T> &m);
00278 
00279 //@}-----------------------------------------------------------------------------
00280 
00281 
00282 /* Include inline implementations */
00283 #include <common/math/Matrix.inl>
00284 
00285 /* The following global functions are not templated, so they will be found in 
00286  * Matrix.cpp
00287  */
00288 
00289 ///@name Routines which generate specific-purpose transformation matrices
00290 //@{-----------------------------------------------------------------------------
00291 
00292 /// @returns the scale matrix described by the vector
00293 extern Matrix4x4 getScaleMat(const Vector3 &v);
00294 /// @returns the translation matrix described by the vector
00295 extern Matrix4x4 getTransMat(const Vector3 &v);
00296 /// @returns the rotation matrix about the x axis by the specified angle
00297 extern Matrix4x4 getRotXMat (const real_t radians);
00298 /// @returns the rotation matrix about the y axis by the specified angle
00299 extern Matrix4x4 getRotYMat (const real_t radians);
00300 /// @returns the rotation matrix about the z axis by the specified angle
00301 extern Matrix4x4 getRotZMat (const real_t radians);
00302 /// @returns the rotation matrix around the vector and point by the specified angle
00303 extern Matrix4x4 getRotMat  (const Point3 &p, const Vector3 &v, const real_t a);
00304 
00305 //@}-----------------------------------------------------------------------------
00306 ///@name Routines which generate specific-purpose inverse transformation matrices
00307 //@{-----------------------------------------------------------------------------
00308 
00309 /// @returns the inverse scale matrix described by the vector
00310 extern Matrix4x4 getInvScaleMat(const Vector3 &v);
00311 /// @returns the inverse translation matrix described by the vector
00312 extern Matrix4x4 getInvTransMat(const Vector3 &v);
00313 /// @returns the inverse rotation matrix about the x axis by the specified angle
00314 extern Matrix4x4 getInvRotXMat (const real_t radians);
00315 /// @returns the inverse rotation matrix about the y axis by the specified angle
00316 extern Matrix4x4 getInvRotYMat (const real_t radians);
00317 /// @returns the inverse rotation matrix about the z axis by the specified angle
00318 extern Matrix4x4 getInvRotZMat (const real_t radians);
00319 /// @returns the inverse rotation matrix around the vector and point by the specified angle
00320 extern Matrix4x4 getInvRotMat  (const Point3 &p, const Vector3 &v, const real_t a);
00321 
00322 //@}-----------------------------------------------------------------------------
00323 
00324 #endif // MATRIX_H_
00325 

Generated on 28 Feb 2009 for Milton by doxygen 1.5.6