00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _BASE_MATRIX3_
00026 #define _BASE_MATRIX3_
00027
00028 #include <iostream>
00029
00030 #include <base/base>
00031 #include <base/Object>
00032 #include <base/Vector3>
00033
00034
00035 #define MATRIX3_ACCESS(r,c) (3*(c-1)+r-1)
00036
00037
00038 namespace base {
00039
00040 class Serializer;
00041 class Matrix3;
00042
00043
00044
00045
00046 struct M3V3mul {
00047 const Matrix3& m;
00048 const Vector3& v;
00049
00050 M3V3mul(const Matrix3& mm, const Vector3& vv) : m(mm), v(vv) {}
00051
00052 operator Vector3() const;
00053 };
00054
00055 struct M3V3mulV3add {
00056 const Matrix3& m;
00057 const Vector3& v;
00058 const Vector3& v2;
00059
00060 M3V3mulV3add(const M3V3mul& mv, const Vector3& vv) : m(mv.m), v(mv.v), v2(vv) {}
00061
00062 operator Vector3() const;
00063 };
00064
00065
00066
00067
00068
00069
00070 class Matrix3
00071 {
00072
00073 public:
00074 Matrix3() { setIdentity(); }
00075 Matrix3(const Matrix3& m) { this->operator=(m); }
00076 Matrix3(const Real& s) { setDiag(s); }
00077 Matrix3(Real e11, Real e12, Real e13,
00078 Real e21, Real e22, Real e23,
00079 Real e31, Real e32, Real e33)
00080 {
00081 e(1,1)=e11; e(1,2)=e12; e(1,3)=e13;
00082 e(2,1)=e21; e(2,2)=e22; e(2,3)=e23;
00083 e(3,1)=e31; e(3,2)=e32; e(3,3)=e33;
00084 }
00085 ~Matrix3() {}
00086
00087
00088 Matrix3& setIdentity() throw()
00089 {
00090 setDiag(Real(1)); return *this;
00091 }
00092
00093 Matrix3& setZero() throw()
00094 {
00095 setDiag(Real(0)); return *this;
00096 }
00097
00098
00099 Real& e(Int row, Int col) throw()
00100 {
00101 Assertm( !((row < 1) || (row > 3) || (col < 1) || (col > 3)), "matrix row and col within bounds (debug only check)");
00102 return m[MATRIX3_ACCESS(row,col)];
00103 }
00104
00105 const Real& e(Int row, Int col) const throw()
00106 {
00107 Assertm( !((row < 1) || (row > 3) || (col < 1) || (col > 3)), "matrix row and col within bounds (debug only check)");
00108 return m[MATRIX3_ACCESS(row,col)];
00109 }
00110
00111 Real& at(Int row, Int col) throw(std::out_of_range)
00112 {
00113 if ((row < 1) || (row > 3) || (col < 1) || (col > 3))
00114 throw std::out_of_range(Exception("matrix row or col out of bounds"));
00115
00116 return m[MATRIX3_ACCESS(row,col)];
00117 }
00118
00119 const Real& at(Int row, Int col) const throw(std::out_of_range)
00120 {
00121 if ((row < 1) || (row > 3) || (col < 1) || (col > 3))
00122 throw std::out_of_range(Exception("matrix row or col out of bounds"));
00123
00124 return m[MATRIX3_ACCESS(row,col)];
00125 }
00126
00127 Real& operator()(Int row, Int col) throw()
00128 {
00129 #ifdef DEBUG
00130 return at(row,col);
00131 #else
00132 return e(row,col);
00133 #endif
00134 }
00135
00136 const Real& operator()(Int row, Int col) const throw()
00137 {
00138 #ifdef DEBUG
00139 return at(row,col);
00140 #else
00141 return e(row,col);
00142 #endif
00143 }
00144
00145
00146
00147
00148
00149 Vector3 row(Int row) const
00150 { return Vector3(e(row,1),e(row,2),e(row,3)); }
00151
00152 Vector3 column(Int col) const
00153 { return Vector3(e(1,col),e(2,col),e(3,col)); }
00154
00155 void setRow(Int row, const Vector3& r) throw()
00156 { e(row,1)=r.x; e(row,2)=r.y; e(row,3)=r.z; }
00157
00158 void setColumn(Int col, const Vector3& c) throw()
00159 { e(1,col)=c.x; e(2,col)=c.y; e(3,col)=c.z; }
00160
00161 void swapColumns(Int col1, Int col2) throw(std::out_of_range)
00162 {
00163 if ((col1 < 1) || (col1 > 3) || (col2 < 1) || (col2 > 3))
00164 throw std::out_of_range(Exception("matrix col out of bounds"));
00165
00166 Vector3 tmp(column(col1));
00167 setColumn(col1,column(col2));
00168 setColumn(col2,tmp);
00169 }
00170
00171 void swapRows(Int row1, Int row2) throw(std::out_of_range)
00172 {
00173 if ((row1 < 1) || (row1 > 3) || (row2 < 1) || (row2 > 3))
00174 throw std::out_of_range(Exception("matrix row out of bounds"));
00175
00176 Vector3 tmp(row(row1));
00177 setRow(row1,row(row2));
00178 setRow(row2,tmp);
00179 }
00180
00181
00182 Vector3 operator[](Int r) const
00183 { return row(r); }
00184
00185
00186 int index(Int row, Int col) const throw()
00187 { return MATRIX3_ACCESS(row,col); }
00188
00189 Matrix3& operator=(const Matrix3& src) throw()
00190 {
00191 if (&src != this)
00192 for(int i=0; i<9; i++)
00193 m[i] = src.m[i];
00194 return *this;
00195 }
00196
00197
00198 bool operator==(const Matrix3& m1) const throw()
00199 {
00200 for(int i=0; i<9; i++)
00201 if (m1.m[i]!=m[i]) return false;
00202 return true;
00203 }
00204
00205 bool equals(const Matrix3& m1, Real epsilon = consts::epsilon) const throw()
00206 {
00207 for(int i=0; i<9; i++)
00208 if (!base::equals(m1.m[i],m[i],epsilon)) return false;
00209 return true;
00210 }
00211
00212
00213 Matrix3& transpose();
00214 Matrix3& invert();
00215 Matrix3& negate() throw();
00216
00217
00218 void setOrthonormalBasisOf(const Vector3& v);
00219
00220
00221
00222 void decomposeLUP(Matrix3& L, Matrix3& U, Vector3& Pi) const;
00223
00224
00225 Vector3 solve(const Vector3& b) const;
00226
00227
00228
00229 Int eigenJacobi(Matrix3& vout, Vector3& dout, Int maxIter=50) const;
00230
00231 Matrix3& operator*=(const Matrix3& m2);
00232 Matrix3& operator+=(const Matrix3& m2);
00233 Matrix3& operator-=(const Matrix3& m2);
00234 Matrix3& operator*=(const Real& s);
00235 Matrix3& operator/=(const Real& s);
00236
00237
00238 const Real* c_array() const { return m; }
00239 Real* c_array() { return m; }
00240
00241
00242 static Vector3 solveLUP(const Matrix3& L, const Matrix3& U, const Vector3& Pi, const Vector3& b);
00243
00244 static void decomposeLUP(const Matrix3& A, Matrix3& L, Matrix3& U, Vector3& Pi)
00245 { A.decomposeLUP(L,U,Pi); }
00246
00247
00248 static Vector3 matrixMulVector(const Matrix3& m, const Vector3& v);
00249 static Vector3 matrixMulVectorAddVector(const Matrix3& m, const Vector3& v, const Vector3& v2);
00250
00251 void serialize(Serializer& s);
00252
00253 private:
00254 Real m[9];
00255
00256 void setDiag(const Real& d)
00257 {
00258 m[0] = d;
00259 m[1] = Real(0);
00260 m[2] = Real(0);
00261 m[3] = Real(0);
00262 m[4] = d;
00263 m[5] = Real(0);
00264 m[6] = Real(0);
00265 m[7] = Real(0);
00266 m[8] = d;
00267 }
00268
00269 };
00270
00271
00272
00273
00274
00275 inline Matrix3 operator*(const Matrix3& m1, const Matrix3& m2)
00276 { Matrix3 r(m1); return r *= m2; }
00277
00278 inline Matrix3 operator+(const Matrix3& m1, const Matrix3& m2)
00279 { Matrix3 r(m1); return r += m2; }
00280
00281 inline Matrix3 operator-(const Matrix3& m1, const Matrix3& m2)
00282 { Matrix3 r(m1); return r -= m2; }
00283
00284 inline Matrix3 operator-(const Matrix3& m1)
00285 { Matrix3 r(m1); return r.negate(); }
00286
00287 inline Matrix3 operator*(const Matrix3& m1, const Real& s)
00288 { Matrix3 r(m1); return r *= s; }
00289
00290 inline Matrix3 operator*(const Real& s, const Matrix3& m1)
00291 { Matrix3 r(m1); return r *= s; }
00292
00293 inline Matrix3 operator/(const Matrix3& m1, const Real& s)
00294 { Matrix3 r(m1); return r /= s; }
00295
00296 inline Matrix3 transpose(const Matrix3& m)
00297 { Matrix3 r(m); return r.transpose(); }
00298
00299 inline Matrix3 inverse(const Matrix3& m)
00300 { Matrix3 r(m); return r.invert(); }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 inline M3V3mulV3add operator+(const M3V3mul& mv, const Vector3& vv)
00314 { return M3V3mulV3add(mv,vv); }
00315
00316 inline M3V3mul operator*(const Matrix3& mm, const Vector3& vv)
00317 { return M3V3mul(mm,vv); }
00318
00319 inline M3V3mul::operator Vector3() const
00320 { return Matrix3::matrixMulVector(m,v); }
00321
00322 inline M3V3mulV3add::operator Vector3() const
00323 { return Matrix3::matrixMulVectorAddVector(m,v,v2); }
00324
00325
00326 std::ostream& operator<<(std::ostream& out, const Matrix3& m);
00327
00328
00329 }
00330
00331 #endif
00332