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 }