00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _LIB_NUMERICS_3D_OMATRIX_H_
00018 #define _LIB_NUMERICS_3D_OMATRIX_H_ 1
00019
00029 #include <lib/numerics/3d/vector3.h>
00030
00031 namespace NUM
00032 {
00033
00049 template<typename T=dbl>class OMatrix
00050 {
00051 private:
00053 T m[3][4];
00054
00055 inline void _copy(const OMatrix &a)
00056 {
00057 for(int i=0; i<3; i++)
00058 { m[i][0]=a.m[i][0]; m[i][1]=a.m[i][1];
00059 m[i][2]=a.m[i][2]; m[i][3]=a.m[i][3]; }
00060 }
00061 inline void _zero()
00062 { for(int i=0; i<3; i++)
00063 { m[i][0]=0; m[i][1]=0; m[i][2]=0; m[i][3]=0; } }
00064 inline void _identity()
00065 { for(short int r=0; r<3; r++) for(short int c=0; c<4; c++)
00066 m[r][c]=(r==c ? 1 : 0); }
00067 public:
00069 enum _Add { Add };
00070 enum _Sub { Sub };
00071 enum _Mul { Mul };
00072 enum _Div { Div };
00073 enum _Null { Null };
00074 enum _Ident { Ident, Identity };
00075 enum _Scale { Scale };
00076 enum _Translate { Translate };
00077 enum _Rotate { Rotate };
00078 enum _Invers { Invers };
00079 enum _Transpose { Transpose };
00080
00081 public:
00083 inline OMatrix() {}
00085 inline OMatrix(const OMatrix &a) { _copy(a); }
00087 inline OMatrix(enum _Null) { _zero(); }
00089 inline OMatrix(enum _Ident) { _identity(); }
00091 inline OMatrix(T m00,T m01,T m02,T m03,
00092 T m10,T m11,T m12,T m13,
00093 T m20,T m21,T m22,T m23,
00094 T m30,T m31,T m32,T m33)
00095 {
00096 m[0][0]=m00; m[0][1]=m01; m[0][2]=m02; m[0][3]=m03;
00097 m[1][0]=m10; m[1][1]=m11; m[1][2]=m12; m[1][3]=m13;
00098 m[2][0]=m20; m[2][1]=m21; m[2][2]=m22; m[2][3]=m23;
00099 m[3][0]=m30; m[3][1]=m31; m[3][2]=m32; m[3][3]=m33;
00100 }
00102 inline OMatrix(enum _Add,const OMatrix<T> &a,const OMatrix<T> &b)
00103 {
00104 for(int i=0; i<3; i++)
00105 { m[i][0]=a.m[i][0]+b.m[i][0]; m[i][1]=a.m[i][1]+b.m[i][1];
00106 m[i][2]=a.m[i][2]+b.m[i][2]; m[i][3]=a.m[i][3]+b.m[i][3]; }
00107 }
00109 inline OMatrix(enum _Sub,const OMatrix<T> &a,const OMatrix<T> &b)
00110 {
00111 for(int i=0; i<3; i++)
00112 { m[i][0]=a.m[i][0]-b.m[i][0]; m[i][1]=a.m[i][1]-b.m[i][1];
00113 m[i][2]=a.m[i][2]-b.m[i][2]; m[i][3]=a.m[i][3]-b.m[i][3]; }
00114 }
00116 inline OMatrix(enum _Mul,const OMatrix<T> &a,T b)
00117 {
00118 for(int i=0; i<3; i++)
00119 { m[i][0]=a.m[i][0]*b; m[i][1]=a.m[i][1]*b;
00120 m[i][2]=a.m[i][2]*b; m[i][3]=a.m[i][3]*b; }
00121 }
00123 inline OMatrix(enum _Div,const OMatrix<T> &a,T b)
00124 {
00125 for(int i=0; i<3; i++)
00126 { m[i][0]=a.m[i][0]/b; m[i][1]=a.m[i][1]/b;
00127 m[i][2]=a.m[i][2]/b; m[i][3]=a.m[i][3]/b; }
00128 }
00130 OMatrix(enum _Mul,const OMatrix<T> &a,const OMatrix<T> &b);
00132 inline OMatrix(enum _Scale,T f)
00133 {
00134 for(short int r=0; r<3; r++) for(short int c=0; c<4; c++)
00135 m[r][c]=(r==c ? f : 0);
00136 }
00138 inline OMatrix(enum _Scale,const Vector3<T> &f)
00139 {
00140 for(short int r=0; r<3; r++) for(short int c=0; c<4; c++)
00141 m[r][c]=(r==c ? f[r] : 0);
00142 }
00144 inline OMatrix(enum _Translate,const Vector3<T> &d)
00145 {
00146 for(short int r=0; r<3; r++)
00147 { for(short int c=0; c<3; c++) m[r][c]=(r==c ? 1 : 0);
00148 m[r][3]=d[r]; }
00149 }
00151 OMatrix(enum _Rotate,const Vector3<T> &axis,T angle);
00153 OMatrix(enum _Invers,const OMatrix<T> &a);
00156 OMatrix(enum _Transpose,const OMatrix<T> &a)
00157 {
00158 for(short int r=0; r<3; r++)
00159 { for(short int c=0; c<3; c++) m[r][c]=a.m[c][r];
00160 m[r][3]=a.m[r][3]; }
00161 }
00163 inline ~OMatrix() {}
00164
00167 inline T *operator[](int r) { return(m[r]); }
00168 inline const T *operator[](int r) const { return(m[r]); }
00169
00171 inline int nrows() const
00172 { return(3); }
00174 inline int ncols() const
00175 { return(4); }
00176
00178 inline OMatrix &operator=(const OMatrix &a)
00179 { _copy(a); return(*this); }
00180
00182 inline OMatrix &zero()
00183 { _zero(); }
00184
00186 inline OMatrix &identity()
00187 { _identity(); }
00188
00190 inline OMatrix &operator+=(const OMatrix &a)
00191 {
00192 for(int i=0; i<3; i++)
00193 { m[i][0]+=a.m[i][0]; m[i][1]+=a.m[i][1];
00194 m[i][2]+=a.m[i][2]; m[i][3]+=a.m[i][3]; }
00195 return(*this);
00196 }
00198 inline OMatrix &operator-=(const OMatrix &a)
00199 {
00200 for(int i=0; i<3; i++)
00201 { m[i][0]-=a.m[i][0]; m[i][1]-=a.m[i][1];
00202 m[i][2]-=a.m[i][2]; m[i][3]-=a.m[i][3]; }
00203 return(*this);
00204 }
00205
00207 inline OMatrix &operator*=(T a)
00208 {
00209 for(int i=0; i<3; i++)
00210 { m[i][0]*=a; m[i][1]*=a; m[i][2]*=a; m[i][3]*=a; }
00211 return(*this);
00212 }
00215 inline OMatrix &operator/=(T a)
00216 {
00217 for(int i=0; i<3; i++)
00218 { m[i][0]/=a; m[i][1]/=a; m[i][2]/=a; m[i][3]/=a; }
00219 return(*this);
00220 }
00221
00231 OMatrix &operator*=(const OMatrix &b);
00232
00259 OMatrix &operator/=(const OMatrix &a);
00260
00262 inline OMatrix &neg()
00263 {
00264 for(int i=0; i<3; i++)
00265 { m[i][0]=-m[i][0]; m[i][1]=-m[i][1];
00266 m[i][2]=-m[i][2]; m[i][3]=-m[i][3]; }
00267 return(*this);
00268 }
00269
00270
00271
00272
00281 inline OMatrix &transpose()
00282 {
00283 T tmp=m[0][1]; m[0][1]=m[1][0]; m[1][0]=tmp;
00284 tmp=m[0][2]; m[0][2]=m[2][0]; m[2][0]=tmp;
00285 tmp=m[1][2]; m[1][2]=m[2][1]; m[2][1]=tmp;
00286 }
00287
00290 inline T determinant() const
00291 { return(m[0][0] * ( m[1][1]*m[2][2] - m[1][2]*m[2][1] )
00292 + m[0][1] * ( m[2][0]*m[1][2] - m[1][0]*m[2][2] )
00293 + m[0][2] * ( m[1][0]*m[2][1] - m[1][1]*m[2][0] ) ); }
00294
00297 inline bool IsNull(T epsilon) const
00298 {
00299 for(short int r=0; r<3; r++) for(short int c=0; c<4; c++)
00300 if(fabs(m[r][c])>=epsilon) return(0);
00301 return(1);
00302 }
00303 };
00304
00305
00307 template<typename T>inline Vector3<T>::Vector3(
00308 _Mul,const OMatrix<T> &m,const Vector3<T> &b)
00309 {
00310 for(short int i=0; i<3; i++)
00311 { v[i] = m[i][0]*b[0] + m[i][1]*b[1] + m[i][2]*b[2] + m[i][3]; }
00312 }
00313
00315 template<typename T>inline Vector3<T>::Vector3(
00316 _TrafoDir,const OMatrix<T> &m,const Vector3<T> &b)
00317 {
00318 for(short int i=0; i<3; i++)
00319 { v[i] = m[i][0]*b[0] + m[i][1]*b[1] + m[i][2]*b[2]; }
00320 }
00321
00323 template<typename T>inline Vector3<T>::Vector3(
00324 _TrafoNorm,const Vector3<T> &a,const OMatrix<T> &m)
00325 {
00326 for(short int i=0; i<3; i++)
00327 { v[i] = m[0][i]*a[0] + m[1][i]*a[1] + m[2][i]*a[2]; }
00328 }
00329
00330
00331
00332
00334 template<typename T>inline OMatrix<T> operator+(
00335 const OMatrix<T> &a,const OMatrix<T> &b)
00336 {
00337 return(OMatrix<T>(OMatrix<T>::Add,a,b));
00338
00339
00340
00341
00342
00343 }
00345 template<typename T>inline OMatrix<T> operator-(
00346 const OMatrix<T> &a,const OMatrix<T> &b)
00347 { return(OMatrix<T>(OMatrix<T>::Sub,a,b)); }
00348
00350 template<typename T>inline OMatrix<T> operator*(const OMatrix<T> &a,T b)
00351 { return(OMatrix<T>(OMatrix<T>::Mul,a,b)); }
00353 template<typename T>inline OMatrix<T> operator*(T b,const OMatrix<T> &a)
00354 { return(OMatrix<T>(OMatrix<T>::Mul,a,b)); }
00355
00357 template<typename T>inline OMatrix<T> operator*(
00358 const OMatrix<T> &a,const OMatrix<T> &b)
00359 { return(OMatrix<T>(OMatrix<T>::Mul,a,b)); }
00360
00363 template<typename T>inline OMatrix<T> operator/(const OMatrix<T> &a,T b)
00364 { return(OMatrix<T>(a,b,OMatrix<T>::Div)); }
00365
00367 template<typename T>inline Vector3<T> operator*(
00368 const OMatrix<T> &a,const Vector3<T> &b)
00369 { return(Vector3<T>(Vector3<T>::Mul,a,b)); }
00370
00373 template<typename T>inline bool equal(const OMatrix<T> &a,const OMatrix<T> &b,
00374 T epsilon)
00375 {
00376 for(short int r=0; r<3; r++) for(short int c=0; c<4; c++)
00377 if(fabs(a[r][c]-b[r][c])>=epsilon) return(0);
00378 return(1);
00379 }
00380
00382 template<typename T>inline OMatrix<T> inverse(const OMatrix<T> &a)
00383 { return(OMatrix<T>(OMatrix<T>::Inverse,a)); }
00384
00386 template<typename T>inline OMatrix<T> transpose(const OMatrix<T> &a)
00387 { return(OMatrix<T>(OMatrix<T>::Transpose,a)); }
00388
00389 }
00390
00391 #endif