Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

Mat4.cc

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

Generated at Sat Aug 5 00:16:47 2000 for Class Library by doxygen 1.1.0 written by Dimitri van Heesch, © 1997-2000