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 #include <base/Matrix4>
00026
00027 #include <base/Serializer>
00028
00029 using base::Matrix4;
00030 using base::Vector4;
00031 using base::Matrix3;
00032
00033 using std::ostream;
00034
00035
00036 inline static void exchange(Real& a, Real& b)
00037 {
00038 Real t(a);
00039 a = b;
00040 b = t;
00041 }
00042
00043
00044 inline static void rcswap4(Real m[], Int r, Int c)
00045 {
00046 Real* rcp = &m[MATRIX4_ACCESS(r,c)];
00047 Real* crp = &m[MATRIX4_ACCESS(c,r)];
00048 exchange(*rcp, *crp);
00049 }
00050
00051
00052 void Matrix4::setToTranslation(const Vector3& trans)
00053 {
00054 setDiag(Real(1));
00055 e(1,4) = trans.x;
00056 e(2,4) = trans.y;
00057 e(3,4) = trans.z;
00058 }
00059
00060 void Matrix4::setTranslationComponent(const Vector3& trans)
00061 {
00062 e(1,4) = trans.x;
00063 e(2,4) = trans.y;
00064 e(3,4) = trans.z;
00065 }
00066
00067 void Matrix4::setRotationAboutZ(Real angle)
00068 {
00069 Real cosa = cos(angle);
00070 Real sina = sin(angle);
00071 setDiag(Real(1));
00072 e(1,1)=cosa; e(1,2)=-sina;
00073 e(2,1)=sina; e(2,2)=cosa;
00074 }
00075
00076
00077 Matrix4& Matrix4::transpose()
00078 {
00079 rcswap4(m,1,2); rcswap4(m,1,3); rcswap4(m,1,4);
00080 rcswap4(m,2,3); rcswap4(m,2,4);
00081 rcswap4(m,3,4);
00082
00083 return *this;
00084 }
00085
00086
00087 Matrix4& Matrix4::invert()
00088 {
00089
00090 Matrix4 I;
00091 Matrix4 X, A(*this);
00092 Vector4 x;
00093
00094 Matrix4 L,U;
00095 Vector4 Pi;
00096
00097 A.decomposeLUP(L,U,Pi);
00098
00099 for(int c=1; c<=4; c++) {
00100 x = solveLUP(L,U,Pi,I.column(c));
00101 for(int r=1; r<=4; r++) X.e(r,c) = x[r];
00102 }
00103
00104 return (*this = X);
00105
00106 }
00107
00108
00109 void Matrix4::decomposeLUP(Matrix4& L, Matrix4& U, Vector4& Pi) const
00110 {
00111 Real p,a;
00112 int kp,i,j,k;
00113 Matrix4 AA(*this);
00114
00115 for(i=1; i<=4; i++) Pi[i] = i;
00116 for(k=1; k<=4-1; k++) {
00117 p = Real(0); kp = 1;
00118 for(i=k; i<=4; i++) {
00119 a = Real(base::abs(AA.e(i,k)));
00120 if ( a > p ) {
00121 p = a;
00122 kp = i;
00123 }
00124 }
00125 if (p == Real(0))
00126 throw std::invalid_argument(Exception("matrix is singular"));
00127
00128 exchange(Pi[k],Pi[kp]);
00129 for(i=1; i<=4;i++) exchange(AA.e(k,i),AA.e(kp,i));
00130
00131 for(i=k+1; i<=4;i++) {
00132 AA.e(i,k) /= AA.e(k,k);
00133 for(j=k+1; j<=4; j++)
00134 AA.e(i,j) -= AA.e(i,k)*AA.e(k,j);
00135 }
00136 }
00137
00138 for(i=1;i<=4;i++) {
00139 for(j=1;j<=4;j++)
00140 if (i>j) {
00141 L.e(i,j) = AA.e(i,j); U.e(i,j) = Real(0);
00142 }
00143 else {
00144 U.e(i,j) = AA.e(i,j); L.e(i,j) = Real(0);
00145 }
00146 L.e(i,i) = Real(1);
00147
00148 }
00149
00150 }
00151
00152
00153 Vector4 Matrix4::solve(const Vector4& b) const
00154 {
00155 Matrix4 L,U;
00156 Vector4 Pi;
00157
00158 decomposeLUP(L,U,Pi);
00159 return solveLUP(L,U,Pi,b);
00160 }
00161
00162
00163 Matrix4& Matrix4::negate() throw()
00164 {
00165 for(int i=0; i<16; i++)
00166 m[i]=-m[i];
00167 return *this;
00168 }
00169
00170
00171
00172
00173
00174 Matrix4& Matrix4::operator*=(const Matrix4& m2)
00175 {
00176
00177 Matrix4 tmp;
00178
00179 for(int row=1; row<=4; row++)
00180 for(int col=1; col<=4; col++)
00181 tmp.e(row,col) = (e(row,1) * m2.e(1,col)) + (e(row,2) * m2.e(2,col))
00182 + (e(row,3) * m2.e(3,col)) + (e(row,4) * m2.e(4,col));
00183
00184 return (*this = tmp);
00185 }
00186
00187
00188 Matrix4& Matrix4::operator+=(const Matrix4& m2)
00189 {
00190 for(int i=0; i<16; i++)
00191 m[i] += m2.m[i];
00192 return (*this);
00193 }
00194
00195
00196 Matrix4& Matrix4::operator-=(const Matrix4& m2)
00197 {
00198 for(int i=0; i<16; i++)
00199 m[i] -= m2.m[i];
00200 return (*this);
00201 }
00202
00203
00204 Matrix4& Matrix4::operator*=(const Real& s)
00205 {
00206 for(int i=0; i<16; i++)
00207 m[i] *= s;
00208 return *this;
00209 }
00210
00211
00212 Matrix4& Matrix4::operator/=(const Real& s)
00213 {
00214 for(int i=0; i<16; i++)
00215 m[i] /= s;
00216 return *this;
00217 }
00218
00219
00220 Matrix4::operator Matrix3() const
00221 {
00222 Matrix3 r;
00223 r.e(1,1) = e(1,1); r.e(1,2)=e(1,2); r.e(1,3)=e(1,3);
00224 r.e(2,1) = e(2,1); r.e(2,2)=e(2,2); r.e(2,3)=e(2,3);
00225 r.e(3,1) = e(3,1); r.e(3,2)=e(3,2); r.e(3,3)=e(3,3);
00226 return r;
00227 }
00228
00229
00230 #ifdef USE_OSG
00231 Matrix4::operator osg::Matrix() const
00232 {
00233 #ifdef OSG_USE_DOUBLE_MATRICES
00234 typedef double osgreal;
00235 #else
00236 typedef float osgreal;
00237 #endif
00238
00239 osg::Matrix mat;
00240 osgreal* _mat = mat.ptr();
00241 for(Int e=0; e<16; e++)
00242 _mat[e] = m[e];
00243 return mat;
00244 }
00245 #endif
00246
00247
00248 Vector4 Matrix4::matrixMulVector(const Matrix4& m, const Vector4& v)
00249 { return Vector4(m.m[0]*v.x+m.m[4]*v.y+m.m[8]*v.z+m.m[12]*v.w,
00250 m.m[1]*v.x+m.m[5]*v.y+m.m[9]*v.z+m.m[13]*v.w,
00251 m.m[2]*v.x+m.m[6]*v.y+m.m[10]*v.z+m.m[14]*v.w,
00252 m.m[3]*v.x+m.m[7]*v.y+m.m[11]*v.z+m.m[15]*v.w);
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 Vector4 Matrix4::matrixMulVector(const Matrix4& m, const Vector3& v)
00265 { return Vector4(m.m[0]*v.x+m.m[4]*v.y+m.m[8]*v.z+m.m[12],
00266 m.m[1]*v.x+m.m[5]*v.y+m.m[9]*v.z+m.m[13],
00267 m.m[2]*v.x+m.m[6]*v.y+m.m[10]*v.z+m.m[14],
00268 m.m[3]*v.x+m.m[7]*v.y+m.m[11]*v.z+m.m[15]);
00269 }
00270
00271 Vector4 Matrix4::matrixMulVectorAddVector(const Matrix4& m, const Vector4& v, const Vector4& v2)
00272 { return Vector4(m.m[0]*v.x+m.m[4]*v.y+m.m[8]*v.z+m.m[12]*v.w+v2.x,
00273 m.m[1]*v.x+m.m[5]*v.y+m.m[9]*v.z+m.m[13]*v.w+v2.y,
00274 m.m[2]*v.x+m.m[6]*v.y+m.m[10]*v.z+m.m[14]*v.w+v2.z,
00275 m.m[3]*v.x+m.m[7]*v.y+m.m[11]*v.z+m.m[15]*v.w+v2.w);
00276 }
00277
00278
00279
00280 Vector4 Matrix4::solveLUP(const Matrix4& L, const Matrix4& U, const Vector4& Pi, const Vector4& b)
00281 {
00282 int i,j;
00283 Vector4 y, x;
00284 Real s;
00285
00286 for(i=1;i<=4;i++) {
00287 s = Real(0);
00288 for(j=1;j<=i-1;j++) s += L.e(i,j)*y[j];
00289 y[i] = b[int(Pi[i])] - s;
00290 }
00291
00292 for(i=4;i>=1;i--) {
00293 s = Real(0);
00294 for(j=i+1;j<=4;j++) s += U.e(i,j)*x[j];
00295 x[i] = (y[i] - s)/(U.e(i,i));
00296 }
00297 return x;
00298 }
00299
00300
00301 void Matrix4::serialize(Serializer& s)
00302 {
00303 for(Int i=0; i<15; i++)
00304 s(m[i]);
00305 }
00306
00307
00308
00309 ostream& base::operator<<(ostream& out, const Matrix4& m)
00310 {
00311 return out << m.e(1,1) << " " << m.e(1,2) << " " << m.e(1,3) << " " << m.e(1,4) << std::endl
00312 << m.e(2,1) << " " << m.e(2,2) << " " << m.e(2,3) << " " << m.e(2,4) << std::endl
00313 << m.e(3,1) << " " << m.e(3,2) << " " << m.e(3,3) << " " << m.e(3,4) << std::endl
00314 << m.e(4,1) << " " << m.e(4,2) << " " << m.e(4,3) << " " << m.e(4,4) << std::endl;
00315 }
00316
00317
00318
00319
00320
00321
00322