src/rcrt/math/Matrix4D.cpp

Go to the documentation of this file.
00001 #include "Matrix4D.h"
00002 
00003 using namespace std;
00004 
00005 namespace rcrt
00006 {
00007 
00008 
00009 Matrix4D::Matrix4D()
00010 {
00011         for (int i = 0; i < 4; i++)
00012                 for (int j = 0; j < 4; j++)
00013                         values[i][j] = 0;
00014 }
00015 
00016 
00017 Matrix4D::Matrix4D(float x)
00018 {
00019         for (int i = 0; i < 4; i++)
00020                 for (int j = 0; j < 4; j++)
00021                         values[i][j] = x;
00022 }
00023 
00024 
00025 Matrix4D::Matrix4D(const Matrix4D& mat)
00026 {
00027         assign(mat);
00028 }
00029 
00030 
00031 void Matrix4D::assign(const Matrix4D& mat)
00032 {
00033         if(&mat != this){
00034                 for (int i = 0; i < 4; i++)
00035                         for (int j = 0; j < 4; j++)
00036                                 values[i][j] = mat.values[i][j];
00037         }
00038 }
00039 
00040 const Matrix4D& Matrix4D::operator= (const Matrix4D& mat)
00041 {
00042         assign(mat);
00043         
00044         return *this;
00045 }
00046 
00047 const Matrix4D& Matrix4D::operator= (float mat[4][4])
00048 {
00049         for (int i = 0; i < 4; i++)
00050                 for (int j = 0; j < 4; j++)
00051                         values[i][j] = mat[i][j];
00052                 
00053         return *this;
00054 }
00055 
00056 
00057 Matrix4D Matrix4D::operator+ (const Matrix4D& mat) const
00058 {
00059         Matrix4D m;
00060         for (int i = 0; i < 4; i++)
00061                 for (int j = 0; j < 4; j++)
00062                         m.values[i][j] = values[i][j] + mat.values[i][j];
00063         
00064         return m;
00065 }
00066 
00067 
00068 Matrix4D Matrix4D::operator- (const Matrix4D& mat) const
00069 {
00070         Matrix4D m;
00071         for (int i = 0; i < 4; i++)
00072                 for (int j = 0; j < 4; j++)
00073                         m.values[i][j] = values[i][j] - mat.values[i][j];
00074         
00075         return m;
00076 }
00077 
00078 
00079 Matrix4D Matrix4D::operator* (const Matrix4D& mat) const
00080 {
00081         Matrix4D m;
00082         for (int i = 0; i < 4; i++)
00083                 for (int j = 0; j < 4; j++)
00084                         m.values[i][j] = values[i][0] * mat.values[0][j] +
00085                                                 values[i][1] * mat.values[1][j] +
00086                                                 values[i][2] * mat.values[2][j] +
00087                                                 values[i][3] * mat.values[3][j];
00088         
00089         return m;
00090 }
00091 
00092 
00093 HCoord4D Matrix4D::operator* (const HCoord4D& coord) const
00094 {
00095         float v[4];
00096         for(int i = 0; i < 4; i++)
00097                 v[i] = values[i][0] * coord.x() +
00098                         values[i][1] * coord.y() +
00099                         values[i][2] * coord.z() +
00100                         values[i][3] * coord.w();
00101         
00102         return HCoord4D(v[0], v[1], v[2], v[3]);
00103 }
00104 
00105 Point3D Matrix4D::operator* (const Point3D& p) const
00106 {
00107         float v[4];
00108         for(int i = 0; i < 4; i++)
00109                 v[i] = values[i][0] * p.x() +
00110                         values[i][1] * p.y() +
00111                         values[i][2] * p.z() +
00112                         values[i][3];
00113         float invW = 1/v[3];
00114         return Point3D(v[0]*invW, v[1]*invW, v[2]*invW);
00115 }
00116 
00117 Vec3D Matrix4D::operator* (const Vec3D& vec) const
00118 {
00119         float v[4];
00120         for(int i = 0; i < 4; i++)
00121                 v[i] = values[i][0] * vec.x() +
00122                         values[i][1] * vec.y() +
00123                         values[i][2] * vec.z();
00124         return Vec3D(v[0], v[1], v[2]);
00125 }
00126 
00127 Matrix4D Matrix4D::operator* (float f) const
00128 {
00129         Matrix4D m;
00130         for (int i = 0; i < 4; ++i)
00131                 for (int j = 0; j < 4; ++j)
00132                         m.values[i][j] = values[i][j] * f;
00133         
00134         return m;
00135 }
00136 
00137 
00138 Matrix4D Matrix4D::operator/ (float f) const
00139 {
00140         float g = 1/f;
00141         
00142         return *this * g;
00143 }
00144 
00145 
00146 
00147 Vec4D Matrix4D::operator[] (const int& i) const
00148 {
00149         return Vec4D(values[0][i], values[1][i], values[2][i], values[3][i]);
00150 }
00151 
00152 
00153 Matrix4D::~Matrix4D()
00154 {
00155 }
00156 
00157 
00158 Matrix4D Matrix4D::transpose() const
00159 {
00160         Matrix4D m;
00161         for (int i = 0; i < 4; ++i)
00162                 for (int j = 0; j < 4; ++j)
00163                         m.values[i][j] = values[j][i];
00164         
00165         return m;
00166 }
00167 
00168 void Matrix4D::swap(float mat[4][4], int& i, int& ci)
00169 {
00170         for(int k = 0; k < 4; k++){
00171                 float temp = mat[i][k];
00172                 mat[i][k] = mat[ci][k];
00173                 mat[ci][k] = temp;
00174         }
00175 }
00176 
00177 void Matrix4D::div(float mat[4][4], int& i, float& factor)
00178 {
00179         if(factor == 0){
00180                 cout<<"Error could not invert Matrix"<<endl;
00181                 exit(1);
00182         }
00183         float inv = 1.0f/factor;
00184         for(int k = 0; k < 4; k++){
00185                 mat[i][k] = mat[i][k]*inv;
00186         }
00187 }
00188 
00189 void Matrix4D::res(float mat[4][4], int& i, int& b, float& factor)
00190 {
00191         int j;
00192         for(j=0;j<4;++j)
00193         {
00194                 mat[i][j] -= mat[b][j]*factor;
00195         }
00196 }
00197 
00198 Matrix4D Matrix4D::inverse() const
00199 {
00200         Matrix4D ident = Matrix4D::identity();
00201         Matrix4D result(*this);
00202         for(int i=0;i<4;++i)
00203         {
00204                 float max=0;
00205                 int ci=0;
00206                 for(int k=i;k<4;++k)
00207                 {
00208                         if(fabs(result.values[k][i])>max)
00209                         {
00210                                 max=fabs(result.values[k][i]);
00211                                 ci=k;
00212                         }
00213                 }
00214                 if(max==0)
00215                 {
00216                         cout<<"Error could not invert Matrix"<<endl;
00217                         exit(1);
00218                 }
00219                 swap(result.values,i,ci);
00220                 swap(ident.values,i,ci);
00221                 float factor=result.values[i][i];
00222                 div(result.values,i,factor);
00223                 div(ident.values,i,factor);
00224                 for(int k=0;k<4;++k)
00225                 {
00226                         if(k!=i)
00227                         {
00228                                 factor=result.values[k][i];
00229                                 res(result.values,k,i,factor);
00230                                 res(ident.values,k,i,factor);
00231                         }
00232                 }
00233         }
00234         for(int i=0;i<4;++i)
00235                 for(int j=0;j<4;++j)
00236                         result.values[i][j]=ident.values[i][j];
00237         return result;
00238 }
00239 
00240 }

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