00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef mat3_h
00022 #define mat3_h
00023
00024 #include "mm.h"
00025
00026
00027 namespace gutz {
00028
00029 template <class T>
00030 class vec2;
00031
00032 template <class T>
00033 class mat2;
00034
00035 template <class T>
00036 class vec3;
00037
00038
00039
00040
00041 template <class T>
00042 class mat3 {
00043
00044 public:
00045
00046 inline mat3 ();
00047 inline mat3 (const T);
00048 inline mat3 (const T*);
00049 inline mat3 (const T, const T, const T,
00050 const T, const T, const T,
00051 const T, const T, const T);
00052 inline mat3 (const vec3<T>&, const vec3<T>&, const vec3<T>&);
00053 inline mat3 (const mat2<T>&, const vec2<T>&);
00054 inline mat3 (const quat<T>&);
00055 inline mat3 (const mat3<T>& M);
00056 inline mat3 (const T theta, const vec3<T> &v);
00057
00058 inline ~mat3 () {}
00059
00060
00061 inline mat3& operator+= (const mat3&);
00062 inline mat3& operator-= (const mat3&);
00063 inline mat3& operator*= (const T);
00064 inline mat3& operator/= (const T);
00065 inline mat3& operator*= (const mat3&);
00066
00067 inline mat3 operator+ (const mat3&) const;
00068 inline mat3 operator- (const mat3&) const;
00069 inline mat3 operator- () const;
00070 inline mat3 operator* (const T) const;
00071 inline mat3 operator/ (const T) const;
00072 inline mat3 operator* (const mat3&) const;
00073 inline vec3<T> operator* (const vec3<T>&) const;
00074
00075 inline T* v ();
00076 inline const T* v () const;
00077 inline void set (const T, const T, const T,
00078 const T, const T, const T,
00079 const T, const T, const T);
00080
00081 inline void set (const T theta, const vec3<T>& v);
00082
00083 inline T& operator[] (const int);
00084 inline T operator[] (const int) const;
00085
00086 inline void zero ();
00087
00088 inline void eye ();
00089
00090 inline vec3<T>& x() const;
00091 inline vec3<T>& y() const;
00092 inline vec3<T>& z() const;
00093
00094 T norm() const;
00095
00096
00097
00098
00099 mat3 inv () const;
00100 inline mat3 tp () const;
00101
00102 inline mat2<T> rot () const;
00103 inline void rot (const mat2<T>&);
00104
00105 inline vec2<T> trans () const;
00106 inline void trans (const vec2<T>&);
00107
00108 inline vec2<T> tpoint (const vec2<T>&) const;
00109 inline vec2<T> tdir (const vec2<T>&) const;
00110
00111 public:
00112 T m[9];
00113 };
00114
00115
00116
00117
00118
00119 typedef mat3<uchar> mat3ub;
00120 typedef mat3<int> mat3i;
00121 typedef mat3<uint> mat3ui;
00122 typedef mat3<float> mat3f;
00123 typedef mat3<double> mat3d;
00124
00125
00126
00127
00128
00129 template <class T>
00130 inline
00131 mat3<T>
00132 operator* (const T, const mat3<T>&);
00133
00134
00135 template <class T>
00136 mat3<T>
00137 skewsym (const vec3<T>&);
00138
00139
00140 template <class T>
00141 mat3<T>
00142 rot (const T, const vec3<T>&);
00143
00144
00145 template <class T>
00146 mat3<T>
00147 rot (const T, const T, const vec3<T>&);
00148
00149
00150 template <class T>
00151 mat3<T>
00152 diag (const vec3<T>&);
00153
00154 template <class T>
00155 std::ostream&
00156 operator<< (std::ostream& os, const mat3<T>& M)
00157 {
00158 os << M.m[0] << " " << M.m[3] << " " << M.m[6] << "\n"
00159 << M.m[1] << " " << M.m[4] << " " << M.m[7] << "\n"
00160 << M.m[2] << " " << M.m[5] << " " << M.m[8];
00161 return os;
00162 }
00163
00164 template <class T>
00165 std::istream&
00166 operator<< (std::istream& os, mat3<T>& M)
00167 {
00168 is >> M.m[0] >> M.m[3] >> M.m[6];
00169 is >> M.m[1] >> M.m[4] >> M.m[7];
00170 is >> M.m[2] >> M.m[5] >> M.m[8];
00171 return is;
00172 }
00173
00174 template <class T>
00175 bool
00176 str2mat3 (const std::string& s, mat3<T>& v)
00177 {
00178 std::istringstream z(s);
00179 mat3<T> w;
00180 bool status = z.eof();
00181 for (int i=0; i<9; i++)
00182 {
00183 z >> w.m[i];
00184 status = status || z.fail() || z.eof();
00185 }
00186 z >> w.m[9];
00187 status = status || z.fail();
00188 if (!status) v = w.tp();
00189 return status;
00190 }
00191
00192 template <class T>
00193 bool
00194 str2mat3 (const std::string*, mat3<T>&);
00195
00196
00197
00198
00199
00200 template <class T>
00201 mat3<T>::mat3 ()
00202 {
00203 m[0] = 1; m[1] = 0; m[2] = 0;
00204 m[3] = 0; m[4] = 1; m[5] = 0;
00205 m[6] = 0; m[7] = 0; m[8] = 1;
00206 }
00207
00208 template <class T>
00209 mat3<T>::mat3 (const T c)
00210 {
00211 m[0] = c; m[1] = c; m[2] = c;
00212 m[3] = c; m[4] = c; m[5] = c;
00213 m[6] = c; m[7] = c; m[8] = c;
00214 }
00215
00216 template <class T>
00217 mat3<T>::mat3 (const T* m0)
00218 {
00219 m[0] = m0[0]; m[1] = m0[1]; m[2] = m0[2];
00220 m[3] = m0[3]; m[4] = m0[4]; m[5] = m0[5];
00221 m[6] = m0[6]; m[7] = m0[7]; m[8] = m0[8];
00222 }
00223
00224 template <class T>
00225 mat3<T>::mat3 (const T m0, const T m1, const T m2,
00226 const T m3, const T m4, const T m5,
00227 const T m6, const T m7, const T m8)
00228 {
00229 m[0] = m0; m[1] = m1; m[2] = m2;
00230 m[3] = m3; m[4] = m4; m[5] = m5;
00231 m[6] = m6; m[7] = m7; m[8] = m8;
00232 }
00233
00234 template <class T>
00235 mat3<T>::mat3 (const vec3<T>& c0, const vec3<T>& c1, const vec3<T>& c2)
00236 {
00237 m[0] = c0.x; m[1] = c0.y; m[2] = c0.z;
00238 m[3] = c1.x; m[4] = c1.y; m[5] = c1.z;
00239 m[6] = c2.x; m[7] = c2.y; m[8] = c2.z;
00240 }
00241
00242 template <class T>
00243 mat3<T>::mat3(const mat2<T>& M, const vec2<T>& v)
00244 {
00245 m[0] = M.m[0]; m[1] = M.m[1]; m[2] = 0;
00246 m[3] = M.m[3]; m[4] = M.m[4]; m[5] = 0;
00247 m[6] = v.x; m[7] = v.y; m[8] = 1;
00248 }
00249
00250 template <class T>
00251 mat3<T>::mat3 (const quat<T>& q)
00252 {
00253 m[0] = q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z;
00254 m[1] = 2*(q.x*q.y + q.w*q.z);
00255 m[2] = 2*(q.x*q.z - q.w*q.y);
00256 m[3] = 2*(q.x*q.y - q.w*q.z);
00257 m[4] = q.w*q.w + q.y*q.y - q.x*q.x - q.z*q.z;
00258 m[5] = 2*(q.y*q.z + q.w*q.x);
00259 m[6] = 2*(q.x*q.z + q.w*q.y);
00260 m[7] = 2*(q.y*q.z - q.w*q.x);
00261 m[8] = q.w*q.w + q.z*q.z - q.x*q.x - q.y*q.y;
00262 }
00263
00264 template <class T>
00265 mat3<T>::mat3 (const mat3<T>& M)
00266 {
00267 m[0] = M.m[0]; m[1] = M.m[1]; m[2] = M.m[2];
00268 m[3] = M.m[3]; m[4] = M.m[4]; m[5] = M.m[5];
00269 m[6] = M.m[6]; m[7] = M.m[7]; m[8] = M.m[8];
00270 }
00271
00272 template <class T>
00273 mat3<T>::mat3 (const T theta, const vec3<T> &v)
00274 {
00275 set(theta,v);
00276 }
00277
00278
00279 template <class T>
00280 mat3<T>&
00281 mat3<T>::operator+= (const mat3<T>& M)
00282 {
00283 m[0] += M.m[0]; m[1] += M.m[1]; m[2] += M.m[2];
00284 m[3] += M.m[3]; m[4] += M.m[4]; m[5] += M.m[5];
00285 m[6] += M.m[6]; m[7] += M.m[7]; m[8] += M.m[8];
00286 return *this;
00287 }
00288
00289 template <class T>
00290 mat3<T>&
00291 mat3<T>::operator-= (const mat3<T>& M)
00292 {
00293 m[0] -= M.m[0]; m[1] -= M.m[1]; m[2] -= M.m[2];
00294 m[3] -= M.m[3]; m[4] -= M.m[4]; m[5] -= M.m[5];
00295 m[6] -= M.m[6]; m[7] -= M.m[7]; m[8] -= M.m[8];
00296 return *this;
00297 }
00298
00299 template <class T>
00300 mat3<T>&
00301 mat3<T>::operator*= (T c)
00302 {
00303 m[0] *= c; m[1] *= c; m[2] *= c;
00304 m[3] *= c; m[4] *= c; m[5] *= c;
00305 m[6] *= c; m[7] *= c; m[8] *= c;
00306 return *this;
00307 }
00308
00309 template <class T>
00310 mat3<T>&
00311 mat3<T>::operator/= (T c)
00312 {
00313 T d = 1/c;
00314 m[0] *= d; m[1] *= d; m[2] *= d;
00315 m[3] *= d; m[4] *= d; m[5] *= d;
00316 m[6] *= d; m[7] *= d; m[8] *= d;
00317 return *this;
00318 }
00319
00320 template <class T>
00321 mat3<T>&
00322 mat3<T>::operator*= (const mat3<T>& M)
00323 {
00324 mat3<T> temp(*this);
00325 m[0] = temp.m[0] * M.m[0] + temp.m[3] * M.m[1] + temp.m[6] * M.m[2];
00326 m[1] = temp.m[1] * M.m[0] + temp.m[4] * M.m[1] + temp.m[7] * M.m[2];
00327 m[2] = temp.m[2] * M.m[0] + temp.m[5] * M.m[1] + temp.m[8] * M.m[2];
00328 m[3] = temp.m[0] * M.m[3] + temp.m[3] * M.m[4] + temp.m[6] * M.m[5];
00329 m[4] = temp.m[1] * M.m[3] + temp.m[4] * M.m[4] + temp.m[7] * M.m[5];
00330 m[5] = temp.m[2] * M.m[3] + temp.m[5] * M.m[4] + temp.m[8] * M.m[5];
00331 m[6] = temp.m[0] * M.m[6] + temp.m[3] * M.m[7] + temp.m[6] * M.m[8];
00332 m[7] = temp.m[1] * M.m[6] + temp.m[4] * M.m[7] + temp.m[7] * M.m[8];
00333 m[8] = temp.m[2] * M.m[6] + temp.m[5] * M.m[7] + temp.m[8] * M.m[8];
00334 return *this;
00335 }
00336
00337 template <class T>
00338 mat3<T>
00339 mat3<T>::operator+ (const mat3<T>& M) const
00340 {
00341 return mat3<T>(m[0] + M.m[0], m[1] + M.m[1], m[2] + M.m[2],
00342 m[3] + M.m[3], m[4] + M.m[4], m[5] + M.m[5],
00343 m[6] + M.m[6], m[7] + M.m[7], m[8] + M.m[8]);
00344 }
00345
00346 template <class T>
00347 mat3<T>
00348 mat3<T>::operator- (const mat3<T>& M) const
00349 {
00350 return mat3<T>(m[0] - M.m[0], m[1] - M.m[1], m[2] - M.m[2],
00351 m[3] - M.m[3], m[4] - M.m[4], m[5] - M.m[5],
00352 m[6] - M.m[6], m[7] - M.m[7], m[8] - M.m[8]);
00353 }
00354
00355 template <class T>
00356 mat3<T>
00357 mat3<T>::operator- () const
00358 {
00359 return mat3<T>(-m[0], -m[1], -m[2],
00360 -m[3], -m[4], -m[5],
00361 -m[6], -m[7], -m[8]);
00362 }
00363
00364 template <class T>
00365 mat3<T>
00366 mat3<T>::operator* (T c) const
00367 {
00368 return mat3<T>(m[0]*c, m[1]*c, m[2]*c,
00369 m[3]*c, m[4]*c, m[5]*c,
00370 m[6]*c, m[7]*c, m[8]*c);
00371 }
00372
00373 template <class T>
00374 mat3<T>
00375 mat3<T>::operator/ (T c) const
00376 {
00377 T d = 1/c;
00378 return mat3<T>(m[0]*d, m[1]*d, m[2]*d,
00379 m[3]*d, m[4]*d, m[5]*d,
00380 m[6]*d, m[7]*d, m[8]*d);
00381 }
00382
00383 template <class T>
00384 mat3<T>
00385 mat3<T>::operator* (const mat3<T>& M) const
00386 {
00387 return mat3<T>(m[0]*M.m[0] + m[3]*M.m[1] + m[6]*M.m[2],
00388 m[1]*M.m[0] + m[4]*M.m[1] + m[7]*M.m[2],
00389 m[2]*M.m[0] + m[5]*M.m[1] + m[8]*M.m[2],
00390
00391 m[0]*M.m[3] + m[3]*M.m[4] + m[6]*M.m[5],
00392 m[1]*M.m[3] + m[4]*M.m[4] + m[7]*M.m[5],
00393 m[2]*M.m[3] + m[5]*M.m[4] + m[8]*M.m[5],
00394
00395 m[0]*M.m[6] + m[3]*M.m[7] + m[6]*M.m[8],
00396 m[1]*M.m[6] + m[4]*M.m[7] + m[7]*M.m[8],
00397 m[2]*M.m[6] + m[5]*M.m[7] + m[8]*M.m[8]);
00398 }
00399
00400 template <class T>
00401 vec3<T>
00402 mat3<T>::operator* (const vec3<T>& v) const
00403 {
00404 return vec3<T>(m[0]*v.x + m[3]*v.y + m[6]*v.z,
00405 m[1]*v.x + m[4]*v.y + m[7]*v.z,
00406 m[2]*v.x + m[5]*v.y + m[8]*v.z);
00407 }
00408
00409 template <class T>
00410 vec2<T>
00411 mat3<T>::tpoint (const vec2<T>& v) const
00412 {
00413 return vec2<T>(m[0]*v.x + m[3]*v.y + m[6],
00414 m[1]*v.x + m[4]*v.y + m[7]);
00415 }
00416
00417 template <class T>
00418 vec2<T>
00419 mat3<T>::tdir (const vec2<T>& v) const
00420 {
00421 return vec2<T>(m[0]*v.x + m[3]*v.y,
00422 m[1]*v.x + m[4]*v.y);
00423 }
00424
00425 template <class T>
00426 T*
00427 mat3<T>::v ()
00428 {
00429 return m;
00430 }
00431
00432 template <class T>
00433 const T*
00434 mat3<T>::v () const
00435 {
00436 return m;
00437 }
00438
00439 template <class T>
00440 void
00441 mat3<T>::set(const T m0, const T m1, const T m2,
00442 const T m3, const T m4, const T m5,
00443 const T m6, const T m7, const T m8)
00444 {
00445 m[0] = m0; m[1] = m1; m[2] = m2;
00446 m[3] = m3; m[4] = m4; m[5] = m5;
00447 m[6] = m6; m[7] = m7; m[8] = m8;
00448 }
00449
00450 template <class T>
00451 void
00452 mat3<T>::set(const T theta, const vec3<T>& v)
00453 {
00454 T ct = cos(theta);
00455 T st = sin(theta);
00456
00457 T xx = v.x * v.x;
00458 T yy = v.y * v.y;
00459 T zz = v.z * v.z;
00460 T xy = v.x * v.y;
00461 T xz = v.x * v.z;
00462 T yz = v.y * v.z;
00463
00464 m[0] = xx + ct*(1-xx);
00465 m[3] = xy + ct*(-xy) + st*-v.z;
00466 m[6] = xz + ct*(-xz) + st*v.y;
00467
00468 m[1] = xy + ct*(-xy) + st*v.z;
00469 m[4] = yy + ct*(1-yy);
00470 m[7] = yz + ct*(-yz) + st*-v.x;
00471
00472 m[2] = xz + ct*(-xz) + st*-v.y;
00473 m[5] = yz + ct*(-yz) + st*v.x;
00474 m[8] = zz + ct*(1-zz);
00475 }
00476
00477 template <class T>
00478 T&
00479 mat3<T>::operator[] (const int i)
00480 {
00481 return v()[i];
00482 }
00483
00484 template <class T>
00485 T
00486 mat3<T>::operator[] (const int i) const
00487 {
00488 return v()[i];
00489 }
00490
00491 template <class T>
00492 void
00493 mat3<T>::zero ()
00494 {
00495 m[0] = 0; m[1] = 0; m[2] = 0;
00496 m[3] = 0; m[4] = 0; m[5] = 0;
00497 m[6] = 0; m[7] = 0; m[8] = 0;
00498 }
00499
00500 template <class T>
00501 void
00502 mat3<T>::eye ()
00503 {
00504 m[0] = 1; m[1] = 0; m[2] = 0;
00505 m[3] = 0; m[4] = 1; m[5] = 0;
00506 m[6] = 0; m[7] = 0; m[8] = 1;
00507 }
00508
00509 template <class T>
00510 vec3<T>&
00511 mat3<T>::x () const
00512 {
00513 return (vec3<T>&)m[0];
00514 }
00515
00516 template <class T>
00517 vec3<T>&
00518 mat3<T>::y () const
00519 {
00520 return (vec3<T>&)m[3];
00521 }
00522
00523 template <class T>
00524 vec3<T>&
00525 mat3<T>::z () const
00526 {
00527 return (vec3<T>&)m[6];
00528 }
00529
00530 template <class T>
00531 T
00532 mat3<T>::norm () const
00533 {
00534 return sqrt(m[0]*m[0] + m[1]*m[1] + m[2]*m[2] +
00535 m[3]*m[3] + m[4]*m[4] + m[5]*m[5] +
00536 m[6]*m[6] + m[7]*m[7] + m[8]*m[8]);
00537 }
00538
00539 template <class T>
00540 mat3<T>
00541 mat3<T>::inv () const
00542 {
00543 T det00 = m[4]*m[8] - m[5]*m[7];
00544 T det01 = m[1]*m[8] - m[2]*m[7];
00545 T det02 = m[1]*m[5] - m[2]*m[4];
00546
00547 T det10 = m[3]*m[8] - m[5]*m[6];
00548 T det11 = m[0]*m[8] - m[2]*m[6];
00549 T det12 = m[0]*m[5] - m[2]*m[3];
00550
00551 T det20 = m[3]*m[7] - m[4]*m[6];
00552 T det21 = m[0]*m[7] - m[1]*m[6];
00553 T det22 = m[0]*m[4] - m[1]*m[3];
00554
00555 T d = 1 / (det00*m[0] - det01*m[3] + det02*m[6]);
00556
00557 return mat3<T>(det00*d, -det10*d, det20*d,
00558 -det01*d, det11*d, -det21*d,
00559 det02*d, -det12*d, det22*d);
00560 }
00561
00562 template <class T>
00563 mat3<T>
00564 mat3<T>::tp () const
00565 {
00566 return mat3<T>(m[0], m[3], m[6],
00567 m[1], m[4], m[7],
00568 m[2], m[5], m[8]);
00569 }
00570
00571 template <class T>
00572 mat2<T>
00573 mat3<T>::rot () const
00574 {
00575 return mat2<T>(m[0], m[1], m[3], m[4]);
00576 }
00577
00578 template <class T>
00579 void
00580 mat3<T>::rot (const mat2<T>& M)
00581 {
00582 m[0] = M.m[0]; m[1] = M.m[1];
00583 m[2] = M.m[3]; m[3] = M.m[4];
00584 }
00585
00586 template <class T>
00587 vec2<T>
00588 mat3<T>::trans () const
00589 {
00590 return vec2<T>(m[7], m[8]);
00591 }
00592
00593 template <class T>
00594 void
00595 mat3<T>::trans (const vec2<T>& v)
00596 {
00597 m[7] = v.x; m[8] = v.y;
00598 }
00599
00600 template <class T>
00601 mat3<T>
00602 operator* (const T c, const mat3<T>& M)
00603 {
00604 return mat3<T> (M.m[0]*c, M.m[1]*c, M.m[2]*c,
00605 M.m[3]*c, M.m[4]*c, M.m[5]*c,
00606 M.m[6]*c, M.m[7]*c, M.m[8]*c);
00607 }
00608
00609 template <class T>
00610 mat3<T>
00611 skewsym (const vec3<T>& k)
00612 {
00613 return mat3<T> (0, -k.z, k.y,
00614 k.z, 0, -k.x,
00615 -k.y, k.x, 0);
00616 }
00617
00618 template <class T>
00619 mat3<T>
00620 rot (const T angle, const vec3<T>& k)
00621 {
00622 T ca = cos(angle);
00623 T sa = sin(angle);
00624 T va = 1 - ca;
00625
00626 return mat3<T>(k.x*k.x*va + ca, k.x*k.y*va + k.z*sa, k.x*k.z*va - k.y*sa,
00627 k.x*k.y*va - k.z*sa, k.y*k.y*va + ca, k.y*k.z*va + k.x*sa,
00628 k.x*k.z*va + k.y*sa, k.y*k.z*va - k.x*sa, k.z*k.z*va + ca);
00629 }
00630
00631 template <class T>
00632 mat3<T>
00633 rot (const T sa, const T ca, const vec3<T>& k)
00634 {
00635 T va = 1 - ca;
00636
00637 return mat3<T>(k.x*k.x*va + ca, k.x*k.y*va + k.z*sa, k.x*k.z*va - k.y*sa,
00638 k.x*k.y*va - k.z*sa, k.y*k.y*va + ca, k.y*k.z*va + k.x*sa,
00639 k.x*k.z*va + k.y*sa, k.y*k.z*va - k.x*sa, k.z*k.z*va + ca);
00640 }
00641
00642 template <class T>
00643 mat3<T>
00644 diag (const vec3<T>& v)
00645 {
00646 return mat3<T>(v.x, 0, 0,
00647 0, v.y, 0,
00648 0, 0, v.z);
00649 }
00650
00651 template <class T>
00652 bool
00653 str2mat3 (const std::string* s, mat3<T>& M)
00654 {
00655 if (!s) return true;
00656 return str2mat3(*s, M);
00657 }
00658
00659
00660
00661 typedef mat3<float> mat3f;
00662 typedef mat3<double> mat3d;
00663
00664 #if __win32
00665 inline
00666 mat3d
00667 mm_castf2d (mat3f M)
00668 {
00669 return mat3d(M.m[0], M.m[1], M.m[2],
00670 M.m[3], M.m[4], M.m[5],
00671 M.m[6], M.m[7], M.m[8]);
00672 }
00673
00674 inline
00675 mat3f
00676 mm_castd2f (mat3d M)
00677 {
00678 return mat3f((float)M.m[0], (float)M.m[1], (float)M.m[2],
00679 (float)M.m[3], (float)M.m[4], (float)M.m[5],
00680 (float)M.m[6], (float)M.m[7], (float)M.m[8]);
00681 }
00682 #else //__real_os
00683 template <class T1, class T2>
00684 mat3<T2>
00685 mm_cast (mat3<T1> v)
00686 {
00687 return mat3<T2>(M.m[0], M.m[1], M.m[2],
00688 M.m[3], M.m[4], M.m[5],
00689 M.m[6], M.m[7], M.m[8]);
00690 }
00691 #endif
00692
00693 }
00694
00695 #endif // mat3_h
00696