Matrix.cpp

Go to the documentation of this file.
00001 /**<!-------------------------------------------------------------------->
00002    @file   Matrix.cpp
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 #include "Matrix.h"
00025 #include <iostream>
00026 
00027 
00028 //@name Routines which generate specific-purpose transformation matrices
00029 //@{---------------------------------------------------------------------
00030 
00031 // @returns the scale matrix described by the vector
00032 Matrix4x4 getScaleMat(const Vector3 &v) {
00033    return Matrix4x4(v[0], 0, 0, 0, 
00034                     0, v[1], 0, 0, 
00035                     0, 0, v[2], 0, 
00036                     0, 0, 0, 1);
00037 }
00038 
00039 // @returns the translation matrix described by the vector
00040 Matrix4x4 getTransMat(const Vector3 &v) {
00041    return Matrix4x4(1, 0, 0, v[0], 
00042                     0, 1, 0, v[1], 
00043                     0, 0, 1, v[2], 
00044                     0, 0, 0, 1);
00045 }
00046 
00047 // @returns the rotation matrix about the x axis by the specified angle
00048 Matrix4x4 getRotXMat (const real_t radians) {
00049    const real_t cosTheta = cos(radians);
00050    const real_t sinTheta = sin(radians);
00051    
00052    return Matrix4x4(1, 0, 0, 0, 
00053                     0, cosTheta, -sinTheta, 0, 
00054                     0, sinTheta, cosTheta, 0, 
00055                     0, 0, 0, 1);
00056 }
00057 
00058 // @returns the rotation matrix about the y axis by the specified angle
00059 Matrix4x4 getRotYMat (const real_t radians) {
00060    const real_t cosTheta = cos(radians);
00061    const real_t sinTheta = sin(radians);
00062 
00063    return Matrix4x4(cosTheta, 0, sinTheta, 0, 
00064                     0, 1, 0, 0, 
00065                     -sinTheta, 0, cosTheta, 0, 
00066                     0, 0, 0, 1);
00067 }
00068 
00069 // @returns the rotation matrix about the z axis by the specified angle
00070 Matrix4x4 getRotZMat (const real_t radians) {
00071    const real_t cosTheta = cos(radians);
00072    const real_t sinTheta = sin(radians);
00073 
00074    return Matrix4x4(cosTheta, -sinTheta, 0, 0, 
00075                     sinTheta, cosTheta, 0, 0, 
00076                     0, 0, 1, 0, 
00077                     0, 0, 0, 1);
00078 }
00079 
00080 // @returns the rotation matrix around the vector and point by the specified angle
00081 Matrix4x4 getRotMat  (const Point3 &p, const Vector3 &v, const real_t a) {
00082    // Translate to origin from point p
00083    const real_t vZ = v[2];
00084    const real_t vX = v[0];
00085    const real_t theta = atan2(vZ, vX);
00086    const real_t phi   = -atan2(v[1], sqrt(vX * vX + vZ * vZ));
00087    
00088    const Matrix4x4 &transToOrigin = getInvTransMat(Vector3(p[0], p[1], p[2]));
00089    const Matrix4x4 &A = getRotYMat(theta);
00090    const Matrix4x4 &B = getRotZMat(phi);
00091    const Matrix4x4 &C = getRotXMat(a);
00092    const Matrix4x4 &invA = getInvRotYMat(theta);
00093    const Matrix4x4 &invB = getInvRotZMat(phi);
00094    const Matrix4x4 &transBack = getTransMat(Vector3(p[0], p[1], p[2]));
00095    
00096    return transBack * invA * invB * C * B * A * transToOrigin;
00097 }
00098 
00099 
00100 // @returns the inverse scale matrix described by the vector
00101 Matrix4x4 getInvScaleMat(const Vector3 &v) {
00102    if (v[0] != 0 && v[1] != 0 && v[2] != 0) {
00103       return Matrix4x4(1.0f / v[0], 0, 0, 0, 
00104                        0, 1.0f / v[1], 0, 0, 
00105                        0, 0, 1.0f / v[2], 0, 
00106                        0, 0, 0, 1);
00107    }
00108 
00109    cerr << "\nError: " << "Divide by zero in getInvScaleMat()" << endl << endl; 
00110    return Matrix4x4();
00111 }
00112 
00113 // @returns the inverse translation matrix described by the vector
00114 Matrix4x4 getInvTransMat(const Vector3 &v) {
00115    return Matrix4x4(1, 0, 0, -v[0], 
00116                     0, 1, 0, -v[1], 
00117                     0, 0, 1, -v[2], 
00118                     0, 0, 0, 1);
00119 }
00120 
00121 // @returns the inverse rotation matrix about the x axis by the specified angle
00122 Matrix4x4 getInvRotXMat (const real_t radians) {
00123    const real_t cosTheta = cos(radians);
00124    const real_t sinTheta = sin(radians);
00125 
00126    return Matrix4x4(1, 0, 0, 0, 
00127                     0, cosTheta, sinTheta, 0, 
00128                     0, -sinTheta, cosTheta, 0, 
00129                     0, 0, 0, 1);
00130 }
00131 
00132 // @returns the inverse rotation matrix about the y axis by the specified angle
00133 Matrix4x4 getInvRotYMat (const real_t radians) {
00134    const real_t cosTheta = cos(radians);
00135    const real_t sinTheta = sin(radians);
00136 
00137    return Matrix4x4(cosTheta, 0, -sinTheta, 0, 
00138                     0, 1, 0, 0, 
00139                     sinTheta, 0, cosTheta, 0, 
00140                     0, 0, 0, 1);
00141 }
00142 
00143 // @returns the inverse rotation matrix about the z axis by the specified angle
00144 Matrix4x4 getInvRotZMat (const real_t radians) {
00145    const real_t cosTheta = cos(radians);
00146    const real_t sinTheta = sin(radians);
00147 
00148    return Matrix4x4(cosTheta, sinTheta, 0, 0, 
00149                     -sinTheta, cosTheta, 0, 0, 
00150                     0, 0, 1, 0, 
00151                     0, 0, 0, 1);
00152 }
00153 
00154 // @returns the inverse rotation matrix around the vector and point by the specified angle
00155 Matrix4x4 getInvRotMat  (const Point3 &p, const Vector3 &v, const real_t a) {
00156    const real_t vZ = v[2];
00157    const real_t vX = v[0];
00158    const real_t theta = atan2(vZ, vX);
00159    const real_t phi   = -atan2(v[1], sqrt(vX * vX + vZ * vZ));
00160    
00161    const Matrix4x4 &transToOrigin = getInvTransMat(Vector3(p[0], p[1], p[2]));
00162    const Matrix4x4 &A = getRotYMat(theta);
00163    const Matrix4x4 &B = getRotZMat(phi);
00164    const Matrix4x4 &C = getRotXMat(a);
00165    const Matrix4x4 &invA = getInvRotYMat(theta);
00166    const Matrix4x4 &invB = getInvRotZMat(phi);
00167    const Matrix4x4 &transBack = getTransMat(Vector3(p[0], p[1], p[2]));
00168    
00169    return transBack * (invA * invB * C * B * A).getTranspose() * transToOrigin;
00170 }
00171 
00172 //@}---------------------------------------------------------------------
00173 
00174 template class Matrix<4, 4, real_t>;
00175 

Generated on 28 Feb 2009 for Milton by doxygen 1.5.6