$search
00001 /* 00002 James R. Diebel 00003 Stanford University 00004 00005 Started: 3 December 2004 00006 00007 mat3x3.cc - implementation for basic 3x3 matrix class 00008 00009 Depends on vec3d.hh 00010 */ 00011 00012 #include "bmtk/mat3x3.hh" 00013 00014 namespace bmtk { 00015 00017 // Constructors // 00019 00020 // identity matrix 00021 Mat3x3::Mat3x3() { 00022 x[0] = x[4] = x[8] = 1.0f; 00023 x[1] = x[2] = x[3] = x[5] = x[6] = x[7] = 0; 00024 r[0].x = &x[0]; r[1].x = &x[3]; r[2].x = &x[6]; 00025 } 00026 00027 // infinite matrix in case of inverse of singular matrix 00028 Mat3x3::Mat3x3(bool inf) { 00029 if (inf) x[0] = x[1] = x[2] = x[3] = x[4] = x[5] = x[6] = x[7] = x[8] = 1e16; 00030 else x[0] = x[1] = x[2] = x[3] = x[4] = x[5] = x[6] = x[7] = x[8] = -1e16; 00031 r[0].x = &x[0]; r[1].x = &x[3]; r[2].x = &x[6]; 00032 } 00033 00034 // each value passed 00035 Mat3x3::Mat3x3(float x11, float x12, float x13, 00036 float x21, float x22, float x23, 00037 float x31, float x32, float x33) { 00038 x[0] = x11; x[1] = x12; x[2] = x13; 00039 x[3] = x21; x[4] = x22; x[5] = x23; 00040 x[6] = x31; x[7] = x32; x[8] = x33; 00041 r[0].x = &x[0]; r[1].x = &x[3]; r[2].x = &x[6]; 00042 } 00043 00044 // scalar multiply of identity matrix 00045 Mat3x3::Mat3x3(const float a) { 00046 x[0] = x[4] = x[8] = a; 00047 x[1] = x[2] = x[3] = x[5] = x[6] = x[7] = 0; 00048 r[0].x = &x[0]; r[1].x = &x[3]; r[2].x = &x[6]; 00049 } 00050 00051 Mat3x3::Mat3x3(const float* x_) { 00052 x[0] = x_[0]; x[1] = x_[1]; x[2] = x_[2]; 00053 x[3] = x_[3]; x[4] = x_[4]; x[5] = x_[5]; 00054 x[6] = x_[6]; x[7] = x_[7]; x[8] = x_[8]; 00055 r[0].x = &x[0]; r[1].x = &x[3]; r[2].x = &x[6]; 00056 } 00057 00058 // diagonal matrix defined by vector 00059 Mat3x3::Mat3x3(const Vec3d& v) { 00060 x[0] = v.x[0]; x[4] = v.x[1]; x[8] = v.x[2]; 00061 x[1] = x[2] = x[3] = x[5] = x[6] = x[7] = 0; 00062 r[0].x = &x[0]; r[1].x = &x[3]; r[2].x = &x[6]; 00063 } 00064 00065 // matrix formed as outer product of two vectors 00066 Mat3x3::Mat3x3(const Vec3d& v0, const Vec3d& v1) { 00067 x[0] = v0.x[0]*v1.x[0]; x[1] = v0.x[0]*v1.x[1]; x[2] = v0.x[0]*v1.x[2]; 00068 x[3] = v0.x[1]*v1.x[0]; x[4] = v0.x[1]*v1.x[1]; x[5] = v0.x[1]*v1.x[2]; 00069 x[6] = v0.x[2]*v1.x[0]; x[7] = v0.x[2]*v1.x[1]; x[8] = v0.x[2]*v1.x[2]; 00070 r[0].x = &x[0]; r[1].x = &x[3]; r[2].x = &x[6]; 00071 } 00072 00073 // columns of matrix passed as vectors 00074 Mat3x3::Mat3x3(const Vec3d& v0, const Vec3d& v1, const Vec3d& v2) { 00075 x[0] = v0.x[0]; x[3] = v0.x[1]; x[6] = v0.x[2]; 00076 x[1] = v1.x[0]; x[4] = v1.x[1]; x[7] = v1.x[2]; 00077 x[2] = v2.x[0]; x[5] = v2.x[1]; x[8] = v2.x[2]; 00078 r[0].x = &x[0]; r[1].x = &x[3]; r[2].x = &x[6]; 00079 } 00080 00081 Mat3x3::Mat3x3(const Vec3d& v0, const Vec3d& v1, const Vec3d& v2, 00082 const Vec3d& l) { 00083 x[0] = l.x[0]*v0.x[0]*v0.x[0]+l.x[1]*v1.x[0]*v1.x[0]+l.x[2]*v2.x[0]*v2.x[0]; 00084 x[3] = l.x[0]*v0.x[1]*v0.x[0]+l.x[1]*v1.x[1]*v1.x[0]+l.x[2]*v2.x[1]*v2.x[0]; 00085 x[4] = l.x[0]*v0.x[1]*v0.x[1]+l.x[1]*v1.x[1]*v1.x[1]+l.x[2]*v2.x[1]*v2.x[1]; 00086 x[6] = l.x[0]*v0.x[2]*v0.x[0]+l.x[1]*v1.x[2]*v1.x[0]+l.x[2]*v2.x[2]*v2.x[0]; 00087 x[7] = l.x[0]*v0.x[2]*v0.x[1]+l.x[1]*v1.x[2]*v1.x[1]+l.x[2]*v2.x[2]*v2.x[1]; 00088 x[8] = l.x[0]*v0.x[2]*v0.x[2]+l.x[1]*v1.x[2]*v1.x[2]+l.x[2]*v2.x[2]*v2.x[2]; 00089 x[1] = x[3]; x[2] = x[6]; x[5] = x[7]; 00090 r[0].x = &x[0]; r[1].x = &x[3]; r[2].x = &x[6]; 00091 } 00093 // Assignments // 00095 00096 // Assign an entire matrix 00097 Mat3x3 Mat3x3::operator = (const Mat3x3& m) { 00098 x[0] = m.x[0]; x[1] = m.x[1]; x[2] = m.x[2]; 00099 x[3] = m.x[3]; x[4] = m.x[4]; x[5] = m.x[5]; 00100 x[6] = m.x[6]; x[7] = m.x[7]; x[8] = m.x[8]; 00101 return *this; 00102 } 00103 00104 // Reference operator: zero-based square bracket referencing 00105 Row1x3 Mat3x3::operator [] (const int index) const { 00106 if (index < 0 || index > 2) cerr << "Index our of bounds" << endl << flush; 00107 return r[index]; 00108 } 00109 Row1x3& Mat3x3::operator [] (const int index) { 00110 if (index < 0 || index > 2) cerr << "Index our of bounds" << endl << flush; 00111 return r[index]; 00112 } 00113 float Row1x3::operator [] (const int index) const { 00114 if (index < 0 || index > 2) cerr << "Index our of bounds" << endl << flush; 00115 return x[index]; 00116 } 00117 float& Row1x3::operator [] (const int index) { 00118 if (index < 0 || index > 2) cerr << "Index our of bounds" << endl << flush; 00119 return x[index]; 00120 } 00121 00123 // Addition, subtraction, multiplication, division // 00125 00126 // <matrix> +/- <matrix> 00127 Mat3x3 Mat3x3::operator + (const Mat3x3& m) const { 00128 return Mat3x3(x[0]+m.x[0],x[1]+m.x[1],x[2]+m.x[2], 00129 x[3]+m.x[3],x[4]+m.x[4],x[5]+m.x[5], 00130 x[6]+m.x[6],x[7]+m.x[7],x[8]+m.x[8]); 00131 } 00132 void Mat3x3::operator += (const Mat3x3& m) { 00133 x[0] += m.x[0]; x[1] += m.x[1]; x[2] += m.x[2]; 00134 x[3] += m.x[3]; x[4] += m.x[4]; x[5] += m.x[5]; 00135 x[6] += m.x[6]; x[7] += m.x[7]; x[8] += m.x[8]; 00136 } 00137 Mat3x3 Mat3x3::operator - (const Mat3x3& m) const { 00138 return Mat3x3(x[0]-m.x[0],x[1]-m.x[1],x[2]-m.x[2], 00139 x[3]-m.x[3],x[4]-m.x[4],x[5]-m.x[5], 00140 x[6]-m.x[6],x[7]-m.x[7],x[8]-m.x[8]); 00141 } 00142 void Mat3x3::operator -= (const Mat3x3& m) { 00143 x[0] -= m.x[0]; x[1] -= m.x[1]; x[2] -= m.x[2]; 00144 x[3] -= m.x[3]; x[4] -= m.x[4]; x[5] -= m.x[5]; 00145 x[6] -= m.x[6]; x[7] -= m.x[7]; x[8] -= m.x[8]; 00146 } 00147 00148 // <matrix> *// <scalar> 00149 Mat3x3 Mat3x3::operator * (const float a) const { 00150 return Mat3x3(x[0]*a,x[1]*a,x[2]*a, 00151 x[3]*a,x[4]*a,x[5]*a, 00152 x[6]*a,x[7]*a,x[8]*a); 00153 } 00154 void Mat3x3::operator *= (const float a) { 00155 x[0] *= a; x[1] *= a; x[2] *= a; 00156 x[3] *= a; x[4] *= a; x[5] *= a; 00157 x[6] *= a; x[7] *= a; x[8] *= a; 00158 } 00159 Mat3x3 Mat3x3::operator / (const float a) const { 00160 return Mat3x3(x[0]/a,x[1]/a,x[2]/a, 00161 x[3]/a,x[4]/a,x[5]/a, 00162 x[6]/a,x[7]/a,x[8]/a); 00163 } 00164 void Mat3x3::operator /= (const float a) { 00165 x[0] /= a; x[1] /= a; x[2] /= a; 00166 x[3] /= a; x[4] /= a; x[5] /= a; 00167 x[6] /= a; x[7] /= a; x[8] /= a; 00168 } 00169 Mat3x3 operator * (const float a, const Mat3x3 &m) { 00170 return Mat3x3(a*m.x[0],a*m.x[1],a*m.x[2], 00171 a*m.x[3],a*m.x[4],a*m.x[5], 00172 a*m.x[6],a*m.x[7],a*m.x[8]); 00173 } 00174 00175 // <matrix> * <vector> 00176 Vec3d Mat3x3::operator * (const Vec3d& v) const { 00177 return Vec3d(x[0]*v.x[0]+x[1]*v.x[1]+x[2]*v.x[2], 00178 x[3]*v.x[0]+x[4]*v.x[1]+x[5]*v.x[2], 00179 x[6]*v.x[0]+x[7]*v.x[1]+x[8]*v.x[2]); 00180 } 00181 Vec3d operator * (const Vec3d& v, const Mat3x3& m) { 00182 return Vec3d(m.x[0]*v.x[0]+m.x[3]*v.x[1]+m.x[6]*v.x[2], 00183 m.x[1]*v.x[0]+m.x[4]*v.x[1]+m.x[7]*v.x[2], 00184 m.x[2]*v.x[0]+m.x[5]*v.x[1]+m.x[8]*v.x[2]); 00185 } 00186 void operator *= (Vec3d& v, const Mat3x3& m) { 00187 float v0 = m.x[0]*v.x[0]+m.x[3]*v.x[1]+m.x[6]*v.x[2]; 00188 float v1 = m.x[1]*v.x[0]+m.x[4]*v.x[1]+m.x[7]*v.x[2]; 00189 float v2 = m.x[2]*v.x[0]+m.x[5]*v.x[1]+m.x[8]*v.x[2]; 00190 v.x[0] = v0; v.x[1] = v1; v.x[2] = v2; 00191 } 00192 00193 // <matrix> * <matrix> 00194 Mat3x3 Mat3x3::operator * (const Mat3x3& m) const { 00195 return Mat3x3(x[0]*m.x[0]+x[1]*m.x[3]+x[2]*m.x[6], 00196 x[0]*m.x[1]+x[1]*m.x[4]+x[2]*m.x[7], 00197 x[0]*m.x[2]+x[1]*m.x[5]+x[2]*m.x[8], 00198 x[3]*m.x[0]+x[4]*m.x[3]+x[5]*m.x[6], 00199 x[3]*m.x[1]+x[4]*m.x[4]+x[5]*m.x[7], 00200 x[3]*m.x[2]+x[4]*m.x[5]+x[5]*m.x[8], 00201 x[6]*m.x[0]+x[7]*m.x[3]+x[8]*m.x[6], 00202 x[6]*m.x[1]+x[7]*m.x[4]+x[8]*m.x[7], 00203 x[6]*m.x[2]+x[7]*m.x[5]+x[8]*m.x[8]); 00204 } 00205 void Mat3x3::operator *= (const Mat3x3& m) { 00206 float y[9]; 00207 y[0] = x[0]; y[1] = x[1]; y[2] = x[2]; 00208 y[3] = x[3]; y[4] = x[4]; y[5] = x[5]; 00209 y[6] = x[6]; y[7] = x[7]; y[8] = x[8]; 00210 x[0] = y[0]*m.x[0]+y[1]*m.x[3]+y[2]*m.x[6]; 00211 x[1] = y[0]*m.x[1]+y[1]*m.x[4]+y[2]*m.x[7]; 00212 x[2] = y[0]*m.x[2]+y[1]*m.x[5]+y[2]*m.x[8]; 00213 x[3] = y[3]*m.x[0]+y[4]*m.x[3]+y[5]*m.x[6]; 00214 x[4] = y[3]*m.x[1]+y[4]*m.x[4]+y[5]*m.x[7]; 00215 x[5] = y[3]*m.x[2]+y[4]*m.x[5]+y[5]*m.x[8]; 00216 x[6] = y[6]*m.x[0]+y[7]*m.x[3]+y[8]*m.x[6]; 00217 x[7] = y[6]*m.x[1]+y[7]*m.x[4]+y[8]*m.x[7]; 00218 x[8] = y[6]*m.x[2]+y[7]*m.x[5]+y[8]*m.x[8]; 00219 } 00220 00222 // Determinant, inverse, transpose, etc. // 00224 00225 // Determinant 00226 float Mat3x3::det() const { 00227 return (x[0]*(x[4]*x[8] - x[7]*x[5]) - 00228 x[1]*(x[3]*x[8] - x[6]*x[5]) + 00229 x[2]*(x[3]*x[7] - x[6]*x[4])); 00230 } 00231 00232 // Inverse 00233 Mat3x3 Mat3x3::inv() const { 00234 float d = det(); 00235 if (d != 0.0f) { 00236 Mat3x3 minv((x[4] * x[8] - x[5] * x[7]), 00237 (x[2] * x[7] - x[1] * x[8]), 00238 (x[1] * x[5] - x[2] * x[4]), 00239 (x[5] * x[6] - x[3] * x[8]), 00240 (x[0] * x[8] - x[2] * x[6]), 00241 (x[2] * x[3] - x[0] * x[5]), 00242 (x[3] * x[7] - x[4] * x[6]), 00243 (x[1] * x[6] - x[0] * x[7]), 00244 (x[0] * x[4] - x[1] * x[3])); 00245 minv /= d; 00246 return minv; 00247 } 00248 else { 00249 cout << "Warning: matrix singular, inverse set to 1e16" << endl << flush; 00250 return Mat3x3(true); 00251 } 00252 } 00253 00254 // Transpose 00255 void Mat3x3::transIt() { 00256 float temp; 00257 temp = x[1]; x[1] = x[3]; x[3] = temp; 00258 temp = x[2]; x[2] = x[6]; x[6] = temp; 00259 temp = x[5]; x[5] = x[7]; x[7] = temp; 00260 } 00261 Mat3x3 Mat3x3::trans() const { 00262 return Mat3x3(x[0],x[3],x[6],x[1],x[4],x[7],x[2],x[5],x[8]); 00263 } 00264 00265 // Outer product 00266 Mat3x3 Mat3x3::outer(const Vec3d& v0, const Vec3d& v1) { 00267 return Mat3x3(v0,v1); 00268 } 00269 00270 // Eigenvector, eigenvalue reconstruction 00271 Mat3x3 Mat3x3::eigenReconst(const Vec3d& v0, const Vec3d& v1, 00272 const Vec3d& v2, const Vec3d& l) { 00273 return Mat3x3(v0,v1,v2,l); 00274 } 00275 00277 // Output functions // 00279 void Mat3x3::print() { 00280 cout << "[" << x[0] << " " << x[1] << " " << x[2] << "]" << endl 00281 << "[" << x[3] << " " << x[4] << " " << x[5] << "]" << endl 00282 << "[" << x[6] << " " << x[7] << " " << x[8] << "]" << endl; 00283 } 00284 00285 // Define << operator to handle output to screen 00286 ostream& operator << (ostream& os, const Mat3x3& m) { 00287 return os << "[" << m.x[0] << " " << m.x[1] << " " << m.x[2] << "]" << endl 00288 << "[" << m.x[3] << " " << m.x[4] << " " << m.x[5] << "]" << endl 00289 << "[" << m.x[6] << " " << m.x[7] << " " << m.x[8] << "]" << endl; 00290 } 00291 00292 } // namespace bmtk