MeshKit  1.0
Mat4.cpp
Go to the documentation of this file.
00001 #include "std.h"
00002 #include "Mat4.h"
00003 
00004 Mat4 Mat4::identity(Vec4(1,0,0,0),Vec4(0,1,0,0),Vec4(0,0,1,0),Vec4(0,0,0,1));
00005 Mat4 Mat4::zero(Vec4(0,0,0,0),Vec4(0,0,0,0),Vec4(0,0,0,0),Vec4(0,0,0,0));
00006 Mat4 Mat4::unit(Vec4(1,1,1,1),Vec4(1,1,1,1),Vec4(1,1,1,1),Vec4(1,1,1,1));
00007 
00008 Mat4 Mat4::trans(double x, double y, double z)
00009 {
00010     return Mat4(Vec4(1,0,0,x),
00011                 Vec4(0,1,0,y),
00012                 Vec4(0,0,1,z),
00013                 Vec4(0,0,0,1));
00014 }
00015 
00016 Mat4 Mat4::scale(double x, double y, double z)
00017 {
00018     return Mat4(Vec4(x,0,0,0),
00019                 Vec4(0,y,0,0),
00020                 Vec4(0,0,z,0),
00021                 Vec4(0,0,0,1));
00022 }
00023 
00024 Mat4 Mat4::xrot(double a)
00025 {
00026     double c = cos(a);
00027     double s = sin(a);
00028 
00029     return Mat4(Vec4(1, 0, 0, 0),
00030                 Vec4(0, c,-s, 0),
00031                 Vec4(0, s, c, 0),
00032                 Vec4(0, 0, 0, 1));
00033 }
00034 
00035 Mat4 Mat4::yrot(double a)
00036 {
00037     double c = cos(a);
00038     double s = sin(a);
00039 
00040     return Mat4(Vec4(c, 0, s, 0),
00041                 Vec4(0, 1, 0, 0),
00042                 Vec4(-s,0, c, 0),
00043                 Vec4(0, 0, 0, 1));
00044 }
00045 
00046 Mat4 Mat4::zrot(double a)
00047 {
00048     double c = cos(a);
00049     double s = sin(a);
00050 
00051     return Mat4(Vec4(c,-s, 0, 0),
00052                 Vec4(s, c, 0, 0),
00053                 Vec4(0, 0, 1, 0),
00054                 Vec4(0, 0, 0, 1));
00055 }
00056 
00057 Mat4 Mat4::operator*(const Mat4& m) const
00058 {
00059     Mat4 A;
00060     int i,j;
00061 
00062     for(i=0;i<4;i++)
00063         for(j=0;j<4;j++)
00064             A(i,j) = row[i]*m.col(j);
00065 
00066     return A;
00067 }
00068 
00069 double Mat4::det() const
00070 {
00071     return row[0] * cross(row[1], row[2], row[3]);
00072 }
00073 
00074 Mat4 Mat4::transpose() const
00075 {
00076     return Mat4(col(0), col(1), col(2), col(3));
00077 }
00078 
00079 Mat4 Mat4::adjoint() const
00080 {
00081     Mat4 A;
00082 
00083     A.row[0] = cross( row[1], row[2], row[3]);
00084     A.row[1] = cross(-row[0], row[2], row[3]);
00085     A.row[2] = cross( row[0], row[1], row[3]);
00086     A.row[3] = cross(-row[0], row[1], row[2]);
00087         
00088     return A;
00089 }
00090 
00091 double Mat4::cramerInverse(Mat4& inv) const
00092 {
00093     Mat4 A = adjoint();
00094     double d = A.row[0] * row[0];
00095 
00096     if( d==0.0 )
00097         return 0.0;
00098 
00099     inv = A.transpose() / d;
00100     return d;
00101 }
00102 
00103 
00104 
00105 // Matrix inversion code for 4x4 matrices.
00106 // Originally ripped off and degeneralized from Paul's matrix library
00107 // for the view synthesis (Chen) software.
00108 //
00109 // Returns determinant of a, and b=a inverse.
00110 // If matrix is singular, returns 0 and leaves trash in b.
00111 //
00112 // Uses Gaussian elimination with partial pivoting.
00113 
00114 #define SWAP(a, b, t)   {t = a; a = b; b = t;}
00115 double Mat4::inverse(Mat4& B) const
00116 {
00117     Mat4 A(*this);
00118 
00119     int i, j, k;
00120     double max, t, det, pivot;
00121 
00122     /*---------- forward elimination ----------*/
00123 
00124     for (i=0; i<4; i++)                 /* put identity matrix in B */
00125         for (j=0; j<4; j++)
00126             B(i, j) = (double)(i==j);
00127 
00128     det = 1.0;
00129     for (i=0; i<4; i++) {               /* eliminate in column i, below diag */
00130         max = -1.;
00131         for (k=i; k<4; k++)             /* find pivot for column i */
00132             if (fabs(A(k, i)) > max) {
00133                 max = fabs(A(k, i));
00134                 j = k;
00135             }
00136         if (max<=0.) return 0.;         /* if no nonzero pivot, PUNT */
00137         if (j!=i) {                     /* swap rows i and j */
00138             for (k=i; k<4; k++)
00139                 SWAP(A(i, k), A(j, k), t);
00140             for (k=0; k<4; k++)
00141                 SWAP(B(i, k), B(j, k), t);
00142             det = -det;
00143         }
00144         pivot = A(i, i);
00145         det *= pivot;
00146         for (k=i+1; k<4; k++)           /* only do elems to right of pivot */
00147             A(i, k) /= pivot;
00148         for (k=0; k<4; k++)
00149             B(i, k) /= pivot;
00150         /* we know that A(i, i) will be set to 1, so don't bother to do it */
00151 
00152         for (j=i+1; j<4; j++) {         /* eliminate in rows below i */
00153             t = A(j, i);                /* we're gonna zero this guy */
00154             for (k=i+1; k<4; k++)       /* subtract scaled row i from row j */
00155                 A(j, k) -= A(i, k)*t;   /* (ignore k<=i, we know they're 0) */
00156             for (k=0; k<4; k++)
00157                 B(j, k) -= B(i, k)*t;
00158         }
00159     }
00160 
00161     /*---------- backward elimination ----------*/
00162 
00163     for (i=4-1; i>0; i--) {             /* eliminate in column i, above diag */
00164         for (j=0; j<i; j++) {           /* eliminate in rows above i */
00165             t = A(j, i);                /* we're gonna zero this guy */
00166             for (k=0; k<4; k++)         /* subtract scaled row i from row j */
00167                 B(j, k) -= B(i, k)*t;
00168         }
00169     }
00170 
00171     return det;
00172 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines