00001 /* 00002 File: Mat3.cc 00003 00004 Function: Implements Mat3.h 00005 00006 Author(s): Andrew Willmott 00007 00008 Copyright: (c) 1995-2000, Andrew Willmott 00009 00010 Notes: 00011 00012 */ 00013 00014 00015 #include "vl/Mat3.h" 00016 #include <ctype.h> 00017 #include "vl/Vec4.h" 00018 #include <iomanip.h> 00019 00020 00021 TMat3::TMat3(TMReal a, TMReal b, TMReal c, 00022 TMReal d, TMReal e, TMReal f, 00023 TMReal g, TMReal h, TMReal i) 00024 { 00025 row[0][0] = a; row[0][1] = b; row[0][2] = c; 00026 row[1][0] = d; row[1][1] = e; row[1][2] = f; 00027 row[2][0] = g; row[2][1] = h; row[2][2] = i; 00028 } 00029 00030 TMat3::TMat3(const TMat3 &m) 00031 { 00032 row[0] = m[0]; 00033 row[1] = m[1]; 00034 row[2] = m[2]; 00035 } 00036 00037 TMat3 &TMat3::operator = (const TMat3 &m) 00038 { 00039 row[0] = m[0]; 00040 row[1] = m[1]; 00041 row[2] = m[2]; 00042 00043 return(SELF); 00044 } 00045 00046 TMat3 &TMat3::operator += (const TMat3 &m) 00047 { 00048 row[0] += m[0]; 00049 row[1] += m[1]; 00050 row[2] += m[2]; 00051 00052 return(SELF); 00053 } 00054 00055 TMat3 &TMat3::operator -= (const TMat3 &m) 00056 { 00057 row[0] -= m[0]; 00058 row[1] -= m[1]; 00059 row[2] -= m[2]; 00060 00061 return(SELF); 00062 } 00063 00064 TMat3 &TMat3::operator *= (const TMat3 &m) 00065 { 00066 SELF = SELF * m; 00067 00068 return(SELF); 00069 } 00070 00071 TMat3 &TMat3::operator *= (TMReal s) 00072 { 00073 row[0] *= s; 00074 row[1] *= s; 00075 row[2] *= s; 00076 00077 return(SELF); 00078 } 00079 00080 TMat3 &TMat3::operator /= (TMReal s) 00081 { 00082 row[0] /= s; 00083 row[1] /= s; 00084 row[2] /= s; 00085 00086 return(SELF); 00087 } 00088 00089 00090 Bool TMat3::operator == (const TMat3 &m) const 00091 { 00092 return(row[0] == m[0] && row[1] == m[1] && row[2] == m[2]); 00093 } 00094 00095 Bool TMat3::operator != (const TMat3 &m) const 00096 { 00097 return(row[0] != m[0] || row[1] != m[1] || row[2] != m[2]); 00098 } 00099 00100 00101 TMat3 TMat3::operator + (const TMat3 &m) const 00102 { 00103 TMat3 result; 00104 00105 result[0] = row[0] + m[0]; 00106 result[1] = row[1] + m[1]; 00107 result[2] = row[2] + m[2]; 00108 00109 return(result); 00110 } 00111 00112 TMat3 TMat3::operator - (const TMat3 &m) const 00113 { 00114 TMat3 result; 00115 00116 result[0] = row[0] - m[0]; 00117 result[1] = row[1] - m[1]; 00118 result[2] = row[2] - m[2]; 00119 00120 return(result); 00121 } 00122 00123 TMat3 TMat3::operator - () const 00124 { 00125 TMat3 result; 00126 00127 result[0] = -row[0]; 00128 result[1] = -row[1]; 00129 result[2] = -row[2]; 00130 00131 return(result); 00132 } 00133 00134 TMat3 TMat3::operator * (const TMat3 &m) const 00135 { 00136 #define N(x,y) row[x][y] 00137 #define M(x,y) m[x][y] 00138 #define R(x,y) result[x][y] 00139 00140 TMat3 result; 00141 00142 R(0,0) = N(0,0) * M(0,0) + N(0,1) * M(1,0) + N(0,2) * M(2,0); 00143 R(0,1) = N(0,0) * M(0,1) + N(0,1) * M(1,1) + N(0,2) * M(2,1); 00144 R(0,2) = N(0,0) * M(0,2) + N(0,1) * M(1,2) + N(0,2) * M(2,2); 00145 00146 R(1,0) = N(1,0) * M(0,0) + N(1,1) * M(1,0) + N(1,2) * M(2,0); 00147 R(1,1) = N(1,0) * M(0,1) + N(1,1) * M(1,1) + N(1,2) * M(2,1); 00148 R(1,2) = N(1,0) * M(0,2) + N(1,1) * M(1,2) + N(1,2) * M(2,2); 00149 00150 R(2,0) = N(2,0) * M(0,0) + N(2,1) * M(1,0) + N(2,2) * M(2,0); 00151 R(2,1) = N(2,0) * M(0,1) + N(2,1) * M(1,1) + N(2,2) * M(2,1); 00152 R(2,2) = N(2,0) * M(0,2) + N(2,1) * M(1,2) + N(2,2) * M(2,2); 00153 00154 return(result); 00155 00156 #undef N 00157 #undef M 00158 #undef R 00159 } 00160 00161 TMat3 TMat3::operator * (TMReal s) const 00162 { 00163 TMat3 result; 00164 00165 result[0] = row[0] * s; 00166 result[1] = row[1] * s; 00167 result[2] = row[2] * s; 00168 00169 return(result); 00170 } 00171 00172 TMat3 TMat3::operator / (TMReal s) const 00173 { 00174 TMat3 result; 00175 00176 result[0] = row[0] / s; 00177 result[1] = row[1] / s; 00178 result[2] = row[2] / s; 00179 00180 return(result); 00181 } 00182 00183 TMat3 trans(const TMat3 &m) 00184 { 00185 #define M(x,y) m[x][y] 00186 #define R(x,y) result[x][y] 00187 00188 TMat3 result; 00189 00190 R(0,0) = M(0,0); R(0,1) = M(1,0); R(0,2) = M(2,0); 00191 R(1,0) = M(0,1); R(1,1) = M(1,1); R(1,2) = M(2,1); 00192 R(2,0) = M(0,2); R(2,1) = M(1,2); R(2,2) = M(2,2); 00193 00194 return(result); 00195 00196 #undef M 00197 #undef R 00198 } 00199 00200 TMat3 adj(const TMat3 &m) 00201 { 00202 TMat3 result; 00203 00204 result[0] = cross(m[1], m[2]); 00205 result[1] = cross(m[2], m[0]); 00206 result[2] = cross(m[0], m[1]); 00207 00208 return(result); 00209 } 00210 00211 00212 TMReal trace(const TMat3 &m) 00213 { 00214 return(m[0][0] + m[1][1] + m[2][2]); 00215 } 00216 00217 TMReal det(const TMat3 &m) 00218 { 00219 return(dot(m[0], cross(m[1], m[2]))); 00220 } 00221 00222 TMat3 inv(const TMat3 &m) 00223 { 00224 TMReal mDet; 00225 TMat3 adjoint; 00226 TMat3 result; 00227 00228 adjoint = adj(m); 00229 mDet = dot(adjoint[0], m[0]); 00230 00231 Assert(mDet != 0, "(Mat3::inv) matrix is non-singular"); 00232 00233 result = trans(adjoint); 00234 result /= mDet; 00235 00236 return(result); 00237 } 00238 00239 TMat3 oprod(const TMVec3 &a, const TMVec3 &b) 00240 // returns outerproduct of a and b: a * trans(b) 00241 { 00242 TMat3 result; 00243 00244 result[0] = a[0] * b; 00245 result[1] = a[1] * b; 00246 result[2] = a[2] * b; 00247 00248 return(result); 00249 } 00250 00251 Void TMat3::MakeZero() 00252 { 00253 Int i; 00254 00255 for (i = 0; i < 9; i++) 00256 ((TMReal*) row)[i] = vl_zero; 00257 } 00258 00259 Void TMat3::MakeDiag(TMReal k) 00260 { 00261 Int i, j; 00262 00263 for (i = 0; i < 3; i++) 00264 for (j = 0; j < 3; j++) 00265 if (i == j) 00266 row[i][j] = k; 00267 else 00268 row[i][j] = vl_zero; 00269 } 00270 00271 Void TMat3::MakeBlock(TMReal k) 00272 { 00273 Int i; 00274 00275 for (i = 0; i < 9; i++) 00276 ((TMReal *) row)[i] = k; 00277 } 00278 00279 ostream &operator << (ostream &s, const TMat3 &m) 00280 { 00281 Int w = s.width(); 00282 00283 return(s << '[' << m[0] << endl << setw(w) << m[1] << endl << setw(w) 00284 << m[2] << ']' << endl); 00285 } 00286 00287 istream &operator >> (istream &s, TMat3 &m) 00288 { 00289 TMat3 result; 00290 Char c; 00291 00292 // Expected format: [[1 2 3] [4 5 6] [7 8 9]] 00293 // Each vector is a column of the matrix. 00294 00295 while (s >> c && isspace(c)) // ignore leading white space 00296 ; 00297 00298 if (c == '[') 00299 { 00300 s >> result[0] >> result[1] >> result[2]; 00301 00302 if (!s) 00303 { 00304 cerr << "Expected number while reading matrix\n"; 00305 return(s); 00306 } 00307 00308 while (s >> c && isspace(c)) 00309 ; 00310 00311 if (c != ']') 00312 { 00313 s.clear(ios::failbit); 00314 cerr << "Expected ']' while reading matrix\n"; 00315 return(s); 00316 } 00317 } 00318 else 00319 { 00320 s.clear(ios::failbit); 00321 cerr << "Expected '[' while reading matrix\n"; 00322 return(s); 00323 } 00324 00325 m = result; 00326 return(s); 00327 } 00328 00329 00330 TMat3 &TMat3::MakeRot(const TQuaternion &q) 00331 { 00332 TMReal i2 = 2 * q[0], 00333 j2 = 2 * q[1], 00334 k2 = 2 * q[2], 00335 ij = i2 * q[1], 00336 ik = i2 * q[2], 00337 jk = j2 * q[2], 00338 ri = i2 * q[3], 00339 rj = j2 * q[3], 00340 rk = k2 * q[3]; 00341 00342 i2 *= q[0]; 00343 j2 *= q[1]; 00344 k2 *= q[2]; 00345 00346 #if VL_ROW_ORIENT 00347 row[0][0] = 1 - j2 - k2; row[0][1] = ij + rk ; row[0][2] = ik - rj; 00348 row[1][0] = ij - rk ; row[1][1] = 1 - i2 - k2; row[1][2] = jk + ri; 00349 row[2][0] = ik + rj ; row[2][1] = jk - ri ; row[2][2] = 1 - i2 - j2; 00350 #else 00351 row[0][0] = 1 - j2 - k2; row[0][1] = ij - rk ; row[0][2] = ik + rj; 00352 row[1][0] = ij + rk ; row[1][1] = 1 - i2 - k2; row[1][2] = jk - ri; 00353 row[2][0] = ik - rj ; row[2][1] = jk + ri ; row[2][2] = 1 - i2 - j2; 00354 #endif 00355 00356 return(SELF); 00357 } 00358 00359 TMat3 &TMat3::MakeRot(const TMVec3 &axis, Real theta) 00360 { 00361 TMReal s; 00362 TMVec4 q; 00363 00364 theta /= 2.0; 00365 s = sin(theta); 00366 00367 q[0] = s * axis[0]; 00368 q[1] = s * axis[1]; 00369 q[2] = s * axis[2]; 00370 q[3] = cos(theta); 00371 00372 MakeRot(q); 00373 00374 return(SELF); 00375 } 00376 00377 TMat3 &TMat3::MakeScale(const TMVec3 &s) 00378 { 00379 MakeZero(); 00380 00381 row[0][0] = s[0]; 00382 row[1][1] = s[1]; 00383 row[2][2] = s[2]; 00384 00385 return(SELF); 00386 } 00387 00388 TMat3 &TMat3::MakeHRot(Real theta) 00389 { 00390 TMReal c, s; 00391 00392 MakeDiag(); 00393 00394 s = sin(theta); 00395 c = cos(theta); 00396 00397 #ifdef VL_ROW_ORIENT 00398 row[0][0] = c; row[0][1] = s; 00399 row[1][0] = -s; row[1][1] = c; 00400 #else 00401 row[0][0] = c; row[0][1] = -s; 00402 row[1][0] = s; row[1][1] = c; 00403 #endif 00404 00405 return(SELF); 00406 } 00407 00408 TMat3 &TMat3::MakeHScale(const TMVec2 &s) 00409 { 00410 MakeDiag(); 00411 00412 row[0][0] = s[0]; 00413 row[1][1] = s[1]; 00414 00415 return(SELF); 00416 } 00417 00418 TMat3 &TMat3::MakeHTrans(const TMVec2 &t) 00419 { 00420 MakeDiag(); 00421 00422 #ifdef VL_ROW_ORIENT 00423 row[2][0] = t[0]; 00424 row[2][1] = t[1]; 00425 #else 00426 row[0][2] = t[0]; 00427 row[1][2] = t[1]; 00428 #endif 00429 00430 return(SELF); 00431 } 00432