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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 #ifndef __VCGLIB_MATRIX44
00103 #define __VCGLIB_MATRIX44
00104
00105 #include <memory.h>
00106 #include <vcg/math/base.h>
00107 #include <vcg/space/point3.h>
00108 #include <vcg/space/point4.h>
00109 #include <vector>
00110 #include <iostream>
00111
00112
00113 namespace vcg {
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 template <class S>
00150 class Matrix44Diag:public Point4<S>{
00151 public:
00157 Matrix44Diag(const S & p0,const S & p1,const S & p2,const S & p3):Point4<S>(p0,p1,p2,p3){};
00158 Matrix44Diag( const Point4<S> & p ):Point4<S>(p){};
00159 };
00160
00161
00164 template <class T> class Matrix44 {
00165 protected:
00166 T _a[16];
00167
00168 public:
00169 typedef T ScalarType;
00170
00172
00176 Matrix44() {};
00177 ~Matrix44() {};
00178 Matrix44(const Matrix44 &m);
00179 Matrix44(const T v[]);
00180
00182 inline unsigned int ColumnsNumber() const
00183 {
00184 return 4;
00185 };
00186
00188 inline unsigned int RowsNumber() const
00189 {
00190 return 4;
00191 };
00192
00193 T &ElementAt(const int row, const int col);
00194 T ElementAt(const int row, const int col) const;
00195
00196
00197 T *V();
00198 const T *V() const ;
00199
00200 T *operator[](const int i);
00201 const T *operator[](const int i) const;
00202
00203
00204 Point4<T> GetColumn4(const int& i)const{
00205 assert(i>=0 && i<4);
00206 return Point4<T>(ElementAt(0,i),ElementAt(1,i),ElementAt(2,i),ElementAt(3,i));
00207
00208 }
00209
00210 Point3<T> GetColumn3(const int& i)const{
00211 assert(i>=0 && i<4);
00212 return Point3<T>(ElementAt(0,i),ElementAt(1,i),ElementAt(2,i));
00213 }
00214
00215 Point4<T> GetRow4(const int& i)const{
00216 assert(i>=0 && i<4);
00217 return Point4<T>(ElementAt(i,0),ElementAt(i,1),ElementAt(i,2),ElementAt(i,3));
00218
00219 }
00220
00221 Point3<T> GetRow3(const int& i)const{
00222 assert(i>=0 && i<4);
00223 return Point3<T>(ElementAt(i,0),ElementAt(i,1),ElementAt(i,2));
00224
00225 }
00226
00227 Matrix44 operator+(const Matrix44 &m) const;
00228 Matrix44 operator-(const Matrix44 &m) const;
00229 Matrix44 operator*(const Matrix44 &m) const;
00230 Matrix44 operator*(const Matrix44Diag<T> &m) const;
00231 Point4<T> operator*(const Point4<T> &v) const;
00232
00233 bool operator==(const Matrix44 &m) const;
00234 bool operator!= (const Matrix44 &m) const;
00235
00236 Matrix44 operator-() const;
00237 Matrix44 operator*(const T k) const;
00238 void operator+=(const Matrix44 &m);
00239 void operator-=(const Matrix44 &m);
00240 void operator*=( const Matrix44 & m );
00241 void operator*=( const T k );
00242
00243 template <class Matrix44Type>
00244 void ToMatrix(Matrix44Type & m) const {for(int i = 0; i < 16; i++) m.V()[i]=V()[i];}
00245
00246 void ToEulerAngles(T &alpha, T &beta, T &gamma);
00247
00248 template <class Matrix44Type>
00249 void FromMatrix(const Matrix44Type & m){for(int i = 0; i < 16; i++) V()[i]=m.V()[i];}
00250 void FromEulerAngles(T alpha, T beta, T gamma);
00251 void SetZero();
00252 void SetIdentity();
00253 void SetDiagonal(const T k);
00254 Matrix44 &SetScale(const T sx, const T sy, const T sz);
00255 Matrix44 &SetScale(const Point3<T> &t);
00256 Matrix44<T>& SetColumn(const unsigned int ii,const Point4<T> &t);
00257 Matrix44<T>& SetColumn(const unsigned int ii,const Point3<T> &t);
00258 Matrix44 &SetTranslate(const Point3<T> &t);
00259 Matrix44 &SetTranslate(const T sx, const T sy, const T sz);
00260 Matrix44 &SetShearXY(const T sz);
00261 Matrix44 &SetShearXZ(const T sy);
00262 Matrix44 &SetShearYZ(const T sx);
00263
00265 Matrix44 &SetRotateDeg(T AngleDeg, const Point3<T> & axis);
00266 Matrix44 &SetRotateRad(T AngleRad, const Point3<T> & axis);
00267
00268 T Determinant() const;
00269
00270 template <class Q> void Import(const Matrix44<Q> &m) {
00271 for(int i = 0; i < 16; i++)
00272 _a[i] = (T)(m.V()[i]);
00273 }
00274 template <class Q>
00275 static inline Matrix44 Construct( const Matrix44<Q> & b )
00276 {
00277 Matrix44<T> tmp; tmp.FromMatrix(b);
00278 return tmp;
00279 }
00280
00281 static inline const Matrix44 &Identity( )
00282 {
00283 static Matrix44<T> tmp; tmp.SetIdentity();
00284 return tmp;
00285 }
00286
00287
00288 Matrix44 transpose() const
00289 {
00290 Matrix44 res = *this;
00291 Transpose(res);
00292 return res;
00293 }
00294 void transposeInPlace() { Transpose(*this); }
00295
00296 void print() {
00297 unsigned int i, j, p;
00298 for (i=0, p=0; i<4; i++, p+=4)
00299 {
00300 std::cout << "[\t";
00301 for (j=0; j<4; j++)
00302 std::cout << _a[p+j] << "\t";
00303
00304 std::cout << "]\n";
00305 }
00306 std::cout << "\n";
00307 }
00308
00309 };
00310
00311
00313 template <class T> class LinearSolve: public Matrix44<T> {
00314 public:
00315 LinearSolve(const Matrix44<T> &m);
00316 Point4<T> Solve(const Point4<T> &b);
00318 T Determinant() const;
00319 protected:
00321 int index[4];
00323 T d;
00324 bool Decompose();
00325 };
00326
00327
00328
00329
00331 template <class T> Point3<T> operator*(const Matrix44<T> &m, const Point3<T> &p);
00332
00333 template <class T> Matrix44<T> &Transpose(Matrix44<T> &m);
00334
00335 template <class T> Matrix44<T> &Invert(Matrix44<T> &m);
00336 template <class T> Matrix44<T> Inverse(const Matrix44<T> &m);
00337
00338 typedef Matrix44<short> Matrix44s;
00339 typedef Matrix44<int> Matrix44i;
00340 typedef Matrix44<float> Matrix44f;
00341 typedef Matrix44<double> Matrix44d;
00342
00343
00344
00345 template <class T> Matrix44<T>::Matrix44(const Matrix44<T> &m) {
00346 memcpy((T *)_a, (T *)m._a, 16 * sizeof(T));
00347 }
00348
00349 template <class T> Matrix44<T>::Matrix44(const T v[]) {
00350 memcpy((T *)_a, v, 16 * sizeof(T));
00351 }
00352
00353 template <class T> T &Matrix44<T>::ElementAt(const int row, const int col) {
00354 assert(row >= 0 && row < 4);
00355 assert(col >= 0 && col < 4);
00356 return _a[(row<<2) + col];
00357 }
00358
00359 template <class T> T Matrix44<T>::ElementAt(const int row, const int col) const {
00360 assert(row >= 0 && row < 4);
00361 assert(col >= 0 && col < 4);
00362 return _a[(row<<2) + col];
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 template <class T> T *Matrix44<T>::operator[](const int i) {
00375 assert(i >= 0 && i < 4);
00376 return _a+i*4;
00377 }
00378
00379 template <class T> const T *Matrix44<T>::operator[](const int i) const {
00380 assert(i >= 0 && i < 4);
00381 return _a+i*4;
00382 }
00383 template <class T> T *Matrix44<T>::V() { return _a;}
00384 template <class T> const T *Matrix44<T>::V() const { return _a;}
00385
00386
00387 template <class T> Matrix44<T> Matrix44<T>::operator+(const Matrix44 &m) const {
00388 Matrix44<T> ret;
00389 for(int i = 0; i < 16; i++)
00390 ret.V()[i] = V()[i] + m.V()[i];
00391 return ret;
00392 }
00393
00394 template <class T> Matrix44<T> Matrix44<T>::operator-(const Matrix44 &m) const {
00395 Matrix44<T> ret;
00396 for(int i = 0; i < 16; i++)
00397 ret.V()[i] = V()[i] - m.V()[i];
00398 return ret;
00399 }
00400
00401 template <class T> Matrix44<T> Matrix44<T>::operator*(const Matrix44 &m) const {
00402 Matrix44 ret;
00403 for(int i = 0; i < 4; i++)
00404 for(int j = 0; j < 4; j++) {
00405 T t = 0.0;
00406 for(int k = 0; k < 4; k++)
00407 t += ElementAt(i, k) * m.ElementAt(k, j);
00408 ret.ElementAt(i, j) = t;
00409 }
00410 return ret;
00411 }
00412
00413 template <class T> Matrix44<T> Matrix44<T>::operator*(const Matrix44Diag<T> &m) const {
00414 Matrix44 ret = (*this);
00415 for(int i = 0; i < 4; ++i)
00416 for(int j = 0; j < 4; ++j)
00417 ret[i][j]*=m[i];
00418 return ret;
00419 }
00420
00421 template <class T> Point4<T> Matrix44<T>::operator*(const Point4<T> &v) const {
00422 Point4<T> ret;
00423 for(int i = 0; i < 4; i++){
00424 T t = 0.0;
00425 for(int k = 0; k < 4; k++)
00426 t += ElementAt(i,k) * v[k];
00427 ret[i] = t;
00428 }
00429 return ret;
00430 }
00431
00432
00433 template <class T> bool Matrix44<T>::operator==(const Matrix44 &m) const {
00434 for(int i = 0; i < 4; ++i)
00435 for(int j = 0; j < 4; ++j)
00436 if(ElementAt(i,j) != m.ElementAt(i,j))
00437 return false;
00438 return true;
00439 }
00440 template <class T> bool Matrix44<T>::operator!=(const Matrix44 &m) const {
00441 for(int i = 0; i < 4; ++i)
00442 for(int j = 0; j < 4; ++j)
00443 if(ElementAt(i,j) != m.ElementAt(i,j))
00444 return true;
00445 return false;
00446 }
00447
00448 template <class T> Matrix44<T> Matrix44<T>::operator-() const {
00449 Matrix44<T> res;
00450 for(int i = 0; i < 16; i++)
00451 res.V()[i] = -V()[i];
00452 return res;
00453 }
00454
00455 template <class T> Matrix44<T> Matrix44<T>::operator*(const T k) const {
00456 Matrix44<T> res;
00457 for(int i = 0; i < 16; i++)
00458 res.V()[i] =V()[i] * k;
00459 return res;
00460 }
00461
00462 template <class T> void Matrix44<T>::operator+=(const Matrix44 &m) {
00463 for(int i = 0; i < 16; i++)
00464 V()[i] += m.V()[i];
00465 }
00466 template <class T> void Matrix44<T>::operator-=(const Matrix44 &m) {
00467 for(int i = 0; i < 16; i++)
00468 V()[i] -= m.V()[i];
00469 }
00470 template <class T> void Matrix44<T>::operator*=( const Matrix44 & m ) {
00471 *this = *this *m;
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 }
00484
00485 template < class PointType , class T > void operator*=( std::vector<PointType> &vert, const Matrix44<T> & m ) {
00486 typename std::vector<PointType>::iterator ii;
00487 for(ii=vert.begin();ii!=vert.end();++ii)
00488 (*ii).P()=m * (*ii).P();
00489 }
00490
00491 template <class T> void Matrix44<T>::operator*=( const T k ) {
00492 for(int i = 0; i < 16; i++)
00493 _a[i] *= k;
00494 }
00495
00496 template <class T>
00497 void Matrix44<T>::ToEulerAngles(T &alpha, T &beta, T &gamma)
00498 {
00499 alpha = atan2(ElementAt(1,2), ElementAt(2,2));
00500 beta = asin(-ElementAt(0,2));
00501 gamma = atan2(ElementAt(0,1), ElementAt(0,0));
00502 }
00503
00504 template <class T>
00505 void Matrix44<T>::FromEulerAngles(T alpha, T beta, T gamma)
00506 {
00507 this->SetZero();
00508
00509 T cosalpha = cos(alpha);
00510 T cosbeta = cos(beta);
00511 T cosgamma = cos(gamma);
00512 T sinalpha = sin(alpha);
00513 T sinbeta = sin(beta);
00514 T singamma = sin(gamma);
00515
00516 ElementAt(0,0) = cosbeta * cosgamma;
00517 ElementAt(1,0) = -cosalpha * singamma + sinalpha * sinbeta * cosgamma;
00518 ElementAt(2,0) = sinalpha * singamma + cosalpha * sinbeta * cosgamma;
00519
00520 ElementAt(0,1) = cosbeta * singamma;
00521 ElementAt(1,1) = cosalpha * cosgamma + sinalpha * sinbeta * singamma;
00522 ElementAt(2,1) = -sinalpha * cosgamma + cosalpha * sinbeta * singamma;
00523
00524 ElementAt(0,2) = -sinbeta;
00525 ElementAt(1,2) = sinalpha * cosbeta;
00526 ElementAt(2,2) = cosalpha * cosbeta;
00527
00528 ElementAt(3,3) = 1;
00529 }
00530
00531 template <class T> void Matrix44<T>::SetZero() {
00532 memset((T *)_a, 0, 16 * sizeof(T));
00533 }
00534
00535 template <class T> void Matrix44<T>::SetIdentity() {
00536 SetDiagonal(1);
00537 }
00538
00539 template <class T> void Matrix44<T>::SetDiagonal(const T k) {
00540 SetZero();
00541 ElementAt(0, 0) = k;
00542 ElementAt(1, 1) = k;
00543 ElementAt(2, 2) = k;
00544 ElementAt(3, 3) = 1;
00545 }
00546
00547 template <class T> Matrix44<T> &Matrix44<T>::SetScale(const Point3<T> &t) {
00548 SetScale(t[0], t[1], t[2]);
00549 return *this;
00550 }
00551 template <class T> Matrix44<T> &Matrix44<T>::SetScale(const T sx, const T sy, const T sz) {
00552 SetZero();
00553 ElementAt(0, 0) = sx;
00554 ElementAt(1, 1) = sy;
00555 ElementAt(2, 2) = sz;
00556 ElementAt(3, 3) = 1;
00557 return *this;
00558 }
00559
00560 template <class T> Matrix44<T> &Matrix44<T>::SetTranslate(const Point3<T> &t) {
00561 SetTranslate(t[0], t[1], t[2]);
00562 return *this;
00563 }
00564 template <class T> Matrix44<T> &Matrix44<T>::SetTranslate(const T tx, const T ty, const T tz) {
00565 SetIdentity();
00566 ElementAt(0, 3) = tx;
00567 ElementAt(1, 3) = ty;
00568 ElementAt(2, 3) = tz;
00569 return *this;
00570 }
00571
00572 template <class T> Matrix44<T> &Matrix44<T>::SetColumn(const unsigned int ii,const Point3<T> &t) {
00573 assert((ii >= 0) && (ii < 4));
00574 ElementAt(0, ii) = t.X();
00575 ElementAt(1, ii) = t.Y();
00576 ElementAt(2, ii) = t.Z();
00577 return *this;
00578 }
00579
00580 template <class T> Matrix44<T> &Matrix44<T>::SetColumn(const unsigned int ii,const Point4<T> &t) {
00581 assert((ii >= 0) && (ii < 4));
00582 ElementAt(0, ii) = t.X();
00583 ElementAt(1, ii) = t.Y();
00584 ElementAt(2, ii) = t.Z();
00585 ElementAt(3, ii) = t.W();
00586 return *this;
00587 }
00588
00589
00590 template <class T> Matrix44<T> &Matrix44<T>::SetRotateDeg(T AngleDeg, const Point3<T> & axis) {
00591 return SetRotateRad(math::ToRad(AngleDeg),axis);
00592 }
00593
00594 template <class T> Matrix44<T> &Matrix44<T>::SetRotateRad(T AngleRad, const Point3<T> & axis) {
00595
00596 T c = math::Cos(AngleRad);
00597 T s = math::Sin(AngleRad);
00598 T q = 1-c;
00599 Point3<T> t = axis;
00600 t.Normalize();
00601 ElementAt(0,0) = t[0]*t[0]*q + c;
00602 ElementAt(0,1) = t[0]*t[1]*q - t[2]*s;
00603 ElementAt(0,2) = t[0]*t[2]*q + t[1]*s;
00604 ElementAt(0,3) = 0;
00605 ElementAt(1,0) = t[1]*t[0]*q + t[2]*s;
00606 ElementAt(1,1) = t[1]*t[1]*q + c;
00607 ElementAt(1,2) = t[1]*t[2]*q - t[0]*s;
00608 ElementAt(1,3) = 0;
00609 ElementAt(2,0) = t[2]*t[0]*q -t[1]*s;
00610 ElementAt(2,1) = t[2]*t[1]*q +t[0]*s;
00611 ElementAt(2,2) = t[2]*t[2]*q +c;
00612 ElementAt(2,3) = 0;
00613 ElementAt(3,0) = 0;
00614 ElementAt(3,1) = 0;
00615 ElementAt(3,2) = 0;
00616 ElementAt(3,3) = 1;
00617 return *this;
00618 }
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 template <class T> Matrix44<T> & Matrix44<T>:: SetShearXY( const T sh) {
00640 SetIdentity();
00641 ElementAt(0,1) = sh;
00642 return *this;
00643 }
00644
00645 template <class T> Matrix44<T> & Matrix44<T>:: SetShearXZ( const T sh) {
00646 SetIdentity();
00647 ElementAt(0,2) = sh;
00648 return *this;
00649 }
00650
00651 template <class T> Matrix44<T> &Matrix44<T>:: SetShearYZ( const T sh) {
00652 SetIdentity();
00653 ElementAt(1,2) = sh;
00654 return *this;
00655 }
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707 template <class T>
00708 bool Decompose(Matrix44<T> &M, Point3<T> &ScaleV, Point3<T> &ShearV, Point3<T> &RotV,Point3<T> &TranV)
00709 {
00710 if(!(M[3][0]==0 && M[3][1]==0 && M[3][2]==0 && M[3][3]==1) )
00711 return false;
00712 if(math::Abs(M.Determinant())<1e-10) return false;
00713
00714
00715 TranV=M.GetColumn3(3);
00716
00717
00718
00719 ScaleV[0]=Norm(M.GetColumn3(0));
00720 Point3<T> R[3];
00721 R[0]=M.GetColumn3(0);
00722 R[0].Normalize();
00723
00724 ShearV[0]=R[0]*M.GetColumn3(1);
00725 R[1]= M.GetColumn3(1)-R[0]*ShearV[0];
00726 assert(math::Abs(R[1]*R[0])<1e-10);
00727 ScaleV[1]=Norm(R[1]);
00728 R[1]=R[1]/ScaleV[1];
00729 ShearV[0]=ShearV[0]/ScaleV[1];
00730
00731 ShearV[1]=R[0]*M.GetColumn3(2);
00732 R[2]= M.GetColumn3(2)-R[0]*ShearV[1];
00733 assert(math::Abs(R[2]*R[0])<1e-10);
00734
00735 R[2] = R[2]-R[1]*(R[2]*R[1]);
00736 assert(math::Abs(R[2]*R[1])<1e-10);
00737 assert(math::Abs(R[2]*R[0])<1e-10);
00738
00739 ScaleV[2]=Norm(R[2]);
00740 ShearV[1]=ShearV[1]/ScaleV[2];
00741 R[2]=R[2]/ScaleV[2];
00742 assert(math::Abs(R[2]*R[1])<1e-10);
00743 assert(math::Abs(R[2]*R[0])<1e-10);
00744
00745 ShearV[2]=R[1]*M.GetColumn3(2);
00746 ShearV[2]=ShearV[2]/ScaleV[2];
00747 int i,j;
00748 for(i=0;i<3;++i)
00749 for(j=0;j<3;++j)
00750 M[i][j]=R[j][i];
00751
00752
00753
00754 double det=M.Determinant();
00755 if(math::Abs(det)<1e-10) return false;
00756 assert(math::Abs(math::Abs(det)-1.0)<1e-10);
00757 if(det<0) {
00758 ScaleV *= -1;
00759 M *= -1;
00760 }
00761
00762 double alpha,beta,gamma;
00763 beta=asin( M[0][2]);
00764 double cosbeta=cos(beta);
00765 if(math::Abs(cosbeta) > 1e-5)
00766 {
00767 alpha=asin(-M[1][2]/cosbeta);
00768 if((M[2][2]/cosbeta) < 0 ) alpha=M_PI-alpha;
00769 gamma=asin(-M[0][1]/cosbeta);
00770 if((M[0][0]/cosbeta)<0) gamma = M_PI-gamma;
00771 }
00772 else
00773 {
00774 alpha=asin(-M[1][0]);
00775 if(M[1][1]<0) alpha=M_PI-alpha;
00776 gamma=0;
00777 }
00778
00779 RotV[0]=math::ToDeg(alpha);
00780 RotV[1]=math::ToDeg(beta);
00781 RotV[2]=math::ToDeg(gamma);
00782
00783 return true;
00784 }
00785
00786
00787
00788
00789 template <class T> T Matrix44<T>::Determinant() const {
00790 LinearSolve<T> solve(*this);
00791 return solve.Determinant();
00792 }
00793
00794
00795 template <class T> Point3<T> operator*(const Matrix44<T> &m, const Point3<T> &p) {
00796 T w;
00797 Point3<T> s;
00798 s[0] = m.ElementAt(0, 0)*p[0] + m.ElementAt(0, 1)*p[1] + m.ElementAt(0, 2)*p[2] + m.ElementAt(0, 3);
00799 s[1] = m.ElementAt(1, 0)*p[0] + m.ElementAt(1, 1)*p[1] + m.ElementAt(1, 2)*p[2] + m.ElementAt(1, 3);
00800 s[2] = m.ElementAt(2, 0)*p[0] + m.ElementAt(2, 1)*p[1] + m.ElementAt(2, 2)*p[2] + m.ElementAt(2, 3);
00801 w = m.ElementAt(3, 0)*p[0] + m.ElementAt(3, 1)*p[1] + m.ElementAt(3, 2)*p[2] + m.ElementAt(3, 3);
00802 if(w!= 0) s /= w;
00803 return s;
00804 }
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817 template <class T> Matrix44<T> &Transpose(Matrix44<T> &m) {
00818 for(int i = 1; i < 4; i++)
00819 for(int j = 0; j < i; j++) {
00820 math::Swap(m.ElementAt(i, j), m.ElementAt(j, i));
00821 }
00822 return m;
00823 }
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836 template <class T> Matrix44<T> & Invert(Matrix44<T> &m) {
00837 LinearSolve<T> solve(m);
00838
00839 for(int j = 0; j < 4; j++) {
00840 Point4<T> col(0, 0, 0, 0);
00841 col[j] = 1.0;
00842 col = solve.Solve(col);
00843 for(int i = 0; i < 4; i++)
00844 m.ElementAt(i, j) = col[i];
00845 }
00846 return m;
00847 }
00848
00849 template <class T> Matrix44<T> Inverse(const Matrix44<T> &m) {
00850 LinearSolve<T> solve(m);
00851 Matrix44<T> res;
00852 for(int j = 0; j < 4; j++) {
00853 Point4<T> col(0, 0, 0, 0);
00854 col[j] = 1.0;
00855 col = solve.Solve(col);
00856 for(int i = 0; i < 4; i++)
00857 res.ElementAt(i, j) = col[i];
00858 }
00859 return res;
00860 }
00861
00862
00863
00864
00865
00866 template <class T> LinearSolve<T>::LinearSolve(const Matrix44<T> &m): Matrix44<T>(m) {
00867 if(!Decompose()) {
00868 for(int i = 0; i < 4; i++)
00869 index[i] = i;
00870 Matrix44<T>::SetZero();
00871 }
00872 }
00873
00874
00875 template <class T> T LinearSolve<T>::Determinant() const {
00876 T det = d;
00877 for(int j = 0; j < 4; j++)
00878 det *= this-> ElementAt(j, j);
00879 return det;
00880 }
00881
00882
00883
00884
00885 #define TINY 1e-100
00886
00887 template <class T> bool LinearSolve<T>::Decompose() {
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941 d = 1;
00942
00943 T scaling[4];
00944 int i,j,k;
00945
00946 for(i = 0; i < 4; i++) {
00947 T largest = 0.0;
00948 for(j = 0; j < 4; j++) {
00949 T t = math::Abs(this->ElementAt(i, j));
00950 if (t > largest) largest = t;
00951 }
00952
00953 if (largest == 0.0) {
00954 return false;
00955 }
00956 scaling[i] = (T)1.0 / largest;
00957 }
00958
00959 int imax = 0;
00960 for(j = 0; j < 4; j++) {
00961 for(i = 0; i < j; i++) {
00962 T sum = this->ElementAt(i,j);
00963 for(int k = 0; k < i; k++)
00964 sum -= this->ElementAt(i,k)*this->ElementAt(k,j);
00965 this->ElementAt(i,j) = sum;
00966 }
00967 T largest = 0.0;
00968 for(i = j; i < 4; i++) {
00969 T sum = this->ElementAt(i,j);
00970 for(k = 0; k < j; k++)
00971 sum -= this->ElementAt(i,k)*this->ElementAt(k,j);
00972 this->ElementAt(i,j) = sum;
00973 T t = scaling[i] * math::Abs(sum);
00974 if(t >= largest) {
00975 largest = t;
00976 imax = i;
00977 }
00978 }
00979 if (j != imax) {
00980 for (int k = 0; k < 4; k++) {
00981 T dum = this->ElementAt(imax,k);
00982 this->ElementAt(imax,k) = this->ElementAt(j,k);
00983 this->ElementAt(j,k) = dum;
00984 }
00985 d = -(d);
00986 scaling[imax] = scaling[j];
00987 }
00988 index[j]=imax;
00989 if (this->ElementAt(j,j) == 0.0) this->ElementAt(j,j) = (T)TINY;
00990 if (j != 3) {
00991 T dum = (T)1.0 / (this->ElementAt(j,j));
00992 for (i = j+1; i < 4; i++)
00993 this->ElementAt(i,j) *= dum;
00994 }
00995 }
00996 return true;
00997 }
00998
00999
01000 template <class T> Point4<T> LinearSolve<T>::Solve(const Point4<T> &b) {
01001 Point4<T> x(b);
01002 int first = -1, ip;
01003 for(int i = 0; i < 4; i++) {
01004 ip = index[i];
01005 T sum = x[ip];
01006 x[ip] = x[i];
01007 if(first!= -1)
01008 for(int j = first; j <= i-1; j++)
01009 sum -= this->ElementAt(i,j) * x[j];
01010 else
01011 if(sum) first = i;
01012 x[i] = sum;
01013 }
01014 for (int i = 3; i >= 0; i--) {
01015 T sum = x[i];
01016 for (int j = i+1; j < 4; j++)
01017 sum -= this->ElementAt(i, j) * x[j];
01018 x[i] = sum / this->ElementAt(i, i);
01019 }
01020 return x;
01021 }
01022
01023 }
01024 #endif
01025
01026