MeshKit
1.0
|
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 }