src/rcrt/math/Matrix4D.h

Go to the documentation of this file.
00001 #ifndef MATRIX4D_H_
00002 #define MATRIX4D_H_
00003 
00004 #include <cmath>
00005 #include <iostream>
00006 #include "Vec3D.h"
00007 #include "Vec4D.h"
00008 #include "HCoord4D.h"
00009 
00010 namespace rcrt
00011 {
00012 
00013 class Matrix4D
00014 {
00015         friend std::ostream& operator<<(std::ostream& out, const Matrix4D& m);
00016         
00017 private:
00018         float values[4][4];//[row][column]
00019         void assign(const Matrix4D& mat);
00020         inline static void swap(float mat[4][4], int& i, int& ci);
00021         inline static void div(float mat[4][4], int& i, float& factor);
00022         inline static void res(float mat[4][4], int& i, int& b, float& factor);
00023         
00024 public:
00025         Matrix4D();
00026         Matrix4D(float x);
00027         Matrix4D(const Matrix4D& mat);
00028         virtual ~Matrix4D();
00029         
00030         const Matrix4D& operator= (const Matrix4D& mat);
00031         const Matrix4D& operator= (float mat[4][4]);
00032         Matrix4D operator+ (const Matrix4D& mat) const;
00033         Matrix4D operator- (const Matrix4D& mat) const;
00034         Matrix4D operator* (const Matrix4D& mat) const;
00035         HCoord4D operator* (const HCoord4D& coords) const;
00036         Point3D operator* (const Point3D& p) const;
00037         Vec3D operator* (const Vec3D& p) const;
00038         Matrix4D operator* (const float f) const;
00039         Matrix4D operator/ (const float f) const;
00040         
00045         Vec4D operator[] (const int& i) const;
00046         
00047         Matrix4D transpose() const;
00048         Matrix4D inverse() const;
00049         
00050         static Matrix4D identity()
00051         {
00052                 Matrix4D m;
00053                 for (int i = 0; i < 4; ++i)
00054                         for (int j = 0; j < 4; ++j)
00055                                 m.values[i][j] = i == j ? 1 : 0;
00056                 
00057                 return m;
00058         }
00059         
00060         static Matrix4D rotation(float angle, const Vec3D& axis)
00061         {
00062                 Matrix4D m;
00063                 float c = cos(angle);
00064                 float s = sin(angle);
00065                 float cm = 1-c;
00066                 float xycm = axis.x()*axis.y()*cm;
00067                 float xzcm = axis.x()*axis.z()*cm;
00068                 float yzcm = axis.z()*axis.y()*cm;
00069                 float zs = axis.z() * s;
00070                 float ys = axis.y() * s;
00071                 float xs = axis.x() * s;
00072                 m.values[0][0] = axis.x()*axis.x()*cm + c;
00073                 m.values[0][1] = xycm - zs;
00074                 m.values[0][2] = xzcm + ys;
00075                 m.values[0][3] = 0;
00076                 
00077                 m.values[1][0] = xycm + zs;
00078                 m.values[1][1] = axis.y()*axis.y()*cm + c;
00079                 m.values[1][2] = yzcm - xs;
00080                 m.values[1][3] = 0;
00081                 
00082                 m.values[2][0] = xzcm - ys;
00083                 m.values[2][1] = yzcm + xs;
00084                 m.values[2][2] = axis.z()*axis.z()*cm + c;
00085                 m.values[2][3] = 0;
00086                 
00087                 for(int i = 0; i < 3; i++)
00088                         m.values[3][i] = 0;
00089                 
00090                 m.values[3][3] = 1;
00091                 
00092                 return m;
00093         }
00094         
00095         static Matrix4D translation(const Vec3D& vec)
00096         {
00097                 Matrix4D m;
00098                 for (int i = 0; i < 3; ++i)
00099                         for (int j = 0; j < 3; ++j)
00100                                 m.values[i][j] = i == j ? 1 : 0;
00101                 m.values[0][3] = vec.x();
00102                 m.values[1][3] = vec.y();
00103                 m.values[2][3] = vec.z();
00104                 m.values[3][3] = 1;
00105                 
00106                 return m;
00107         }
00108         
00109         static Matrix4D getOrthoNormalBasis(const Vec3D& n, const Vec3D& v) {
00110                 Matrix4D onb;
00111                 
00112                 onb.values[0][2] = n.x();
00113                 onb.values[1][2] = n.y();
00114                 onb.values[2][2] = n.z();
00115                 
00116                 Vec3D vp = v*(v*n)/(n*n);
00117                 Vec3D t = (v-vp).normalize();
00118                 
00119                 Vec3D b = (t.crossP(n)).normalize();
00120                 //Vector3.cross(onb.w, onb.u, onb.v);
00121                 
00122                 onb.values[0][1] = t.x();
00123                 onb.values[1][1] = t.y();
00124                 onb.values[2][1] = t.z();
00125                 
00126                 onb.values[0][0] = b.x();
00127                 onb.values[1][0] = b.y();
00128                 onb.values[2][0] = b.z();
00129                 onb.values[3][3] = 1;
00130                 
00131                 return onb;
00132         }
00133         
00134 };
00135 
00136 inline std::ostream& operator<<(std::ostream& out, const Matrix4D& m)
00137 {
00138         out<<"Matrix4D:"<<std::endl;
00139         out<<"/ "<<m.values[0][0]<<" "<<m.values[0][1]<<" "<<m.values[0][2]<<" "<<m.values[0][3]<<" \\"<<std::endl;;
00140         out<<"| "<<m.values[1][0]<<" "<<m.values[1][1]<<" "<<m.values[1][2]<<" "<<m.values[1][3]<<" |"<<std::endl;;
00141         out<<"| "<<m.values[2][0]<<" "<<m.values[2][1]<<" "<<m.values[2][2]<<" "<<m.values[2][3]<<" |"<<std::endl;;
00142         out<<"\\ "<<m.values[3][0]<<" "<<m.values[3][1]<<" "<<m.values[3][2]<<" "<<m.values[3][3]<<" /"<<std::endl;;
00143         return out;
00144 }
00145 
00146 }
00147 
00148 #endif /*MATRIX4D_H_*/

Generated on Thu Jan 31 19:26:19 2008 for RenderingCompetitionRayTracer by  doxygen 1.5.3