Sirikata
|
00001 /* Sirikata Utilities -- Math Library 00002 * Matrix3x3.hpp 00003 * 00004 * Copyright (c) 2009, Daniel Reiter Horn 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are 00009 * met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in 00014 * the documentation and/or other materials provided with the 00015 * distribution. 00016 * * Neither the name of Sirikata nor the names of its contributors may 00017 * be used to endorse or promote products derived from this software 00018 * without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00021 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00022 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00023 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 00024 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 #ifndef _MATRIX3X3_HPP_ 00033 #define _MATRIX3X3_HPP_ 00034 namespace Sirikata { 00035 class COLUMNS{}; 00036 class ROWS{}; 00037 00038 template <typename scalar> class Matrix3x3 { 00039 public: 00040 typedef Vector3<scalar> Vector3x; 00041 private: 00042 Vector3x mCol[3]; 00043 public: 00044 typedef scalar real; 00045 Matrix3x3(){} 00046 static const Matrix3x3& zero() { 00047 static Matrix3x3 zero_( 00048 Vector3x::zero(), 00049 Vector3x::zero(), 00050 Vector3x::zero(), 00051 COLUMNS() 00052 ); 00053 return zero_; 00054 } 00055 static const Matrix3x3& identity() { 00056 static Matrix3x3 identity (Vector3x::unitX(), 00057 Vector3x::unitY(), 00058 Vector3x::unitZ(), 00059 COLUMNS()); 00060 return identity; 00061 } 00062 Matrix3x3(const Vector3x&col1, const Vector3x&col2, const Vector3x&col3, COLUMNS c){ 00063 setCol(0,col1); 00064 setCol(1,col2); 00065 setCol(2,col3); 00066 } 00067 Matrix3x3(const Vector3x&row1, const Vector3x&row2, const Vector3x&row3, ROWS r){ 00068 setRow(0,row1); 00069 setRow(1,row2); 00070 setRow(2,row3); 00071 } 00072 const Vector3x& getCol(unsigned int which) const { 00073 assert(which<3); 00074 return mCol[which]; 00075 } 00076 void setCol(unsigned int which,const Vector3x &col) { 00077 assert(which<3); 00078 mCol[which]=col; 00079 } 00080 Vector3x getRow(unsigned int which) const { 00081 assert(which<3); 00082 return Vector3x(mCol[0][which], 00083 mCol[1][which], 00084 mCol[2][which]); 00085 } 00086 void setRow(unsigned int which, const Vector3x &row) { 00087 assert(which<3); 00088 mCol[0][which]=row[0]; 00089 mCol[1][which]=row[1]; 00090 mCol[2][which]=row[2]; 00091 } 00092 scalar&operator() (unsigned int row, unsigned int column) { 00093 return mCol[column][row]; 00094 } 00095 scalar operator() (unsigned int row, unsigned int column) const{ 00096 return mCol[column][row]; 00097 } 00098 template <typename T> Vector3<T> operator *(const Vector3<T>&other)const { 00099 return mCol[0]*other.x+mCol[1]*other.y+mCol[2]*other.z; 00100 } 00101 Matrix3x3 operator *(scalar other)const { 00102 return Matrix3x3(getCol(0)*other,getCol(1)*other,getCol(2)*other,COLUMNS()); 00103 } 00104 Matrix3x3 operator /(scalar other)const { 00105 return Matrix3x3(getCol(0)/other,getCol(1)/other,getCol(2)/other,COLUMNS()); 00106 } 00107 bool operator == (const Matrix3x3&other)const{ 00108 return getCol(0)==other.getCol(0)&&getCol(1)==other.getCol(1)&&getCol(2)==other.getCol(2); 00109 } 00110 bool operator != (const Matrix3x3&other)const{ 00111 return getCol(0)!=other.getCol(0) || getCol(1)!=other.getCol(1) || getCol(2)!=other.getCol(2); 00112 } 00113 Matrix3x3 operator+ (const Matrix3x3&other)const { 00114 return Matrix3x3(getCol(0)+other.getCol(0), 00115 getCol(1)+other.getCol(1), 00116 getCol(2)+other.getCol(2), 00117 COLUMNS()); 00118 } 00119 Matrix3x3 operator- (const Matrix3x3&other)const { 00120 return Matrix3x3(getCol(0)-other.getCol(0), 00121 getCol(1)-other.getCol(1), 00122 getCol(2)-other.getCol(2), 00123 COLUMNS()); 00124 } 00125 Matrix3x3 operator- ()const { 00126 return Matrix3x3(-getCol(0), 00127 -getCol(1), 00128 -getCol(2), 00129 COLUMNS()); 00130 } 00131 Matrix3x3& operator+= (const Matrix3x3&other) { 00132 mCol[0]+=other.getCol(0); 00133 mCol[1]+=other.getCol(1); 00134 mCol[2]+=other.getCol(2); 00135 return *this; 00136 } 00137 Matrix3x3& operator-= (const Matrix3x3&other) { 00138 mCol[0]-=other.getCol(0); 00139 mCol[1]-=other.getCol(1); 00140 mCol[2]-=other.getCol(2); 00141 return *this; 00142 } 00143 Matrix3x3 operator* (const Matrix3x3&other)const { 00144 Vector3<scalar> ocol0=other.getCol(0); 00145 Vector3<scalar> ocol1=other.getCol(1); 00146 Vector3<scalar> ocol2=other.getCol(2); 00147 return Matrix3x3(mCol[0]*ocol0.x+mCol[1]*ocol0.y+mCol[2]*ocol0.z, 00148 mCol[0]*ocol1.x+mCol[1]*ocol1.y+mCol[2]*ocol1.z, 00149 mCol[0]*ocol2.x+mCol[1]*ocol2.y+mCol[2]*ocol2.z, 00150 COLUMNS()); 00151 } 00152 Matrix3x3& operator*= (const Matrix3x3&other) { 00153 Vector3<scalar> ocol0=other.getCol(0); 00154 Vector3<scalar> ocol1=other.getCol(1); 00155 Vector3<scalar> ocol2=other.getCol(2); 00156 //cannot do this *= inplace 00157 ocol0=mCol[0]*ocol0.x+mCol[1]*ocol0.y+mCol[2]*ocol0.z; 00158 ocol1=mCol[0]*ocol1.x+mCol[1]*ocol1.y+mCol[2]*ocol1.z; 00159 ocol2=mCol[0]*ocol2.x+mCol[1]*ocol2.y+mCol[2]*ocol2.z; 00160 //have to copy back 00161 mCol[0]=ocol0; 00162 mCol[1]=ocol1; 00163 mCol[2]=ocol2; 00164 return *this; 00165 } 00166 Matrix3x3& operator*= (scalar other) { 00167 mCol[0]*=other; 00168 mCol[1]*=other; 00169 mCol[2]*=other; 00170 return *this; 00171 } 00172 Matrix3x3& operator/= (scalar other) { 00173 mCol[0]/=other; 00174 mCol[1]/=other; 00175 mCol[2]/=other; 00176 return *this; 00177 } 00178 Matrix3x3 transpose() const { 00179 return Matrix3x3(getCol(0), 00180 getCol(1), 00181 getCol(2), 00182 ROWS()); 00183 } 00184 Matrix3x3 inverse() const 00185 { 00186 Matrix3x3 inverted; 00187 inverted.setRow(0, Vector3x( 00188 (*this)(1,1)*(*this)(2,2) - (*this)(1,2)*(*this)(2,1), 00189 (*this)(0,2)*(*this)(2,1) - (*this)(0,1)*(*this)(2,2), 00190 (*this)(0,1)*(*this)(1,2) - (*this)(0,2)*(*this)(1,1))); 00191 inverted.setRow(1, Vector3x( 00192 (*this)(1,2)*(*this)(2,0) - (*this)(1,0)*(*this)(2,2), 00193 (*this)(0,0)*(*this)(2,2) - (*this)(0,2)*(*this)(2,0), 00194 (*this)(0,2)*(*this)(1,0) - (*this)(0,0)*(*this)(1,2))); 00195 inverted.setRow(2, Vector3x( 00196 (*this)(1,0)*(*this)(2,1) - (*this)(1,1)*(*this)(2,0), 00197 (*this)(0,1)*(*this)(2,0) - (*this)(0,0)*(*this)(2,1), 00198 (*this)(0,0)*(*this)(1,1) - (*this)(0,1)*(*this)(1,0))); 00199 00200 scalar fDet = 00201 (*this)(0,0)*inverted(0,0) + 00202 (*this)(0,1)*inverted(1,0)+ 00203 (*this)(0,2)*inverted(2,0); 00204 00205 scalar fInvDet = ((scalar)1.0)/fDet; 00206 for (size_t iRow = 0; iRow < 3; iRow++) 00207 for (size_t iCol = 0; iCol < 3; iCol++) 00208 inverted(iRow,iCol) *= fInvDet; 00209 00210 return inverted; 00211 } 00212 Matrix3x3 inverseTranspose() const { 00213 return inverse().transpose(); 00214 } 00216 double determinant() const { 00217 return mCol[0].x*(double)mCol[1].y*mCol[2].z- 00218 mCol[0].x*(double)mCol[2].y*mCol[1].z + 00219 mCol[1].x*(double)mCol[2].y*mCol[0].z - 00220 mCol[1].x*(double)mCol[0].y*mCol[2].z + 00221 mCol[2].x*(double)mCol[0].y*mCol[1].z - 00222 mCol[2].x*(double)mCol[1].y*mCol[0].z; 00223 } 00224 std::string toString() const { 00225 std::ostringstream os; 00226 os<<"{ col1:"<<mCol[0]<<" col2:"<<mCol[1]<<" col3:"<<mCol[2]<<'}'; 00227 return os.str(); 00228 } 00229 }; 00230 template<typename scalar> inline std::ostream& operator <<(std::ostream& os, const Matrix3x3<scalar> &rhs) { 00231 os<<"{ col1:"<<rhs.getCol(0)<<" col2:"<<rhs.getCol(1)<<" col3:"<<rhs.getCol(2)<<'}'; 00232 return os; 00233 } 00234 00235 template <typename T,typename S> Vector3<T> operator *(const Vector3<T>&vec, const Matrix3x3<S>&mat) { 00236 return Vector3<T>(mat.getCol(0).dot(vec), 00237 mat.getCol(1).dot(vec), 00238 mat.getCol(2).dot(vec)); 00239 } 00240 template <typename T> Matrix3x3<T> operator *(T other, const Matrix3x3<T>&mat) { 00241 return Matrix3x3<T>(mat.getCol(0)*other,mat.getCol(1)*other,mat.getCol(2)*other,COLUMNS()); 00242 } 00243 template <typename T> Matrix3x3<T> operator /(T other, const Matrix3x3<T>&mat) { 00244 return Matrix3x3<T>(other/mat.getCol(0),other/mat.getCol(1),other/mat.getCol(2),COLUMNS()); 00245 } 00246 00247 typedef Matrix3x3<float32> Matrix3x3f; 00248 typedef Matrix3x3<float64> Matrix3x3d; 00249 00250 } 00251 #endif