00001 /* SimData: Data Infrastructure for Simulations 00002 * Copyright (C) 2002, 2003 Mark Rose <tm2@stm.lbl.gov> 00003 * 00004 * This file is part of SimData. 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00019 */ 00020 00021 00035 #ifndef __SIMDATA_MATRIX3_H__ 00036 #define __SIMDATA_MATRIX3_H__ 00037 00038 00039 #include <SimData/BaseType.h> 00040 #include <SimData/Vector3.h> 00041 00042 #include <string> 00043 #include <vector> 00044 #include <iostream> 00045 #include <algorithm> 00046 #include <cassert> 00047 #include <cmath> 00048 00049 00050 NAMESPACE_SIMDATA 00051 00052 00053 class Quat; 00054 00055 00061 class SIMDATA_EXPORT Matrix3: public BaseType 00062 { 00063 public: 00066 virtual std::string asString() const; 00067 00070 virtual std::string typeString() const { return "Matrix3"; } 00071 00074 virtual void serialize(Archive&); 00075 00081 virtual void parseXML(const char* cdata); 00082 00085 static const Matrix3 ZERO; 00086 00089 static const Matrix3 IDENTITY; 00090 00098 Matrix3() { } // for speed, do not initialize 00099 00102 Matrix3(const Matrix3& other): BaseType(other) { set(other); } 00103 00106 explicit Matrix3(double const * const def) { set(def); } 00107 Matrix3(double a00, double a01, double a02, 00108 double a10, double a11, double a12, 00109 double a20, double a21, double a22) { 00110 set(a00, a01, a02, 00111 a10, a11, a12, 00112 a20, a21, a22); 00113 } 00114 00117 Matrix3(const Vector3& col0, const Vector3& col1, const Vector3& col2); 00118 00121 ~Matrix3() {} 00122 00131 int compare(const Matrix3& m) const { return memcmp(_mat, m._mat, sizeof(_mat)); } 00132 00135 bool operator == (const Matrix3& m) const { return compare(m)==0; } 00136 00139 bool operator != (const Matrix3& m) const { return compare(m)!=0; } 00140 00141 #ifndef SWIG 00142 00144 inline double& operator()(int row_, int col_) { return _mat[row_][col_]; } 00145 00148 inline double operator()(int row_, int col_) const { return _mat[row_][col_]; } 00149 #endif // SWIG 00150 00153 inline double getElement(int row_, int col_) { return _mat[row_][col_]; } 00154 00157 inline void setElement(int row_, int col_, double value) { _mat[row_][col_]=value; } 00158 00161 inline bool valid() const { return !isNaN(); } 00162 00165 bool isNaN() const; 00166 00167 #ifndef SWIG 00168 00170 inline Matrix3& operator = (const Matrix3& other) { 00171 if (&other == this) return *this; 00172 std::copy((double*)other._mat, (double*)other._mat+9, (double*)(_mat)); 00173 return *this; 00174 } 00175 #endif // SWIG 00176 00179 inline void set(const Matrix3& other) { 00180 std::copy((double*)other._mat, (double*)other._mat+9, (double*)(_mat)); 00181 } 00182 00185 inline void set(double const * const ptr_) { 00186 std::copy(ptr_, ptr_+9, (double*)(_mat)); 00187 } 00188 00191 void set(double a00, double a01, double a02, 00192 double a10, double a11, double a12, 00193 double a20, double a21, double a22) { 00194 _mat[0][0] = a00; 00195 _mat[0][1] = a01; 00196 _mat[0][2] = a02; 00197 _mat[1][0] = a10; 00198 _mat[1][1] = a11; 00199 _mat[1][2] = a12; 00200 _mat[2][0] = a20; 00201 _mat[2][1] = a21; 00202 _mat[2][2] = a22; 00203 } 00204 00207 std::vector<double> getElements() const; 00208 00211 void setElements(std::vector<double> const &v) const; 00212 00215 Vector3 getRow(int i) { 00216 assert(i>=0 && i<3); 00217 return Vector3(_mat[i][0], _mat[i][1], _mat[i][2]); 00218 } 00219 00222 Vector3 getCol(int i) { 00223 assert(i>=0 && i<3); 00224 return Vector3(_mat[0][i], _mat[1][i], _mat[2][i]); 00225 } 00226 00229 void setRow(int i, const Vector3& v) { 00230 assert(i>=0 && i<3); 00231 _mat[i][0] = v.x(); 00232 _mat[i][1] = v.y(); 00233 _mat[i][2] = v.z(); 00234 } 00235 00238 void setCol(int i, const Vector3& v) { 00239 assert(i>=0 && i<3); 00240 _mat[0][i] = v.x(); 00241 _mat[1][i] = v.y(); 00242 _mat[2][i] = v.z(); 00243 } 00244 00247 double * row(int i) { assert(i>=0 && i<3); return (double*)(_mat[i]); } 00248 00251 double * ptr() { return (double *)_mat; } 00252 00255 double const * ptr() const { return (double const *)_mat; } 00256 00259 inline void makeIdentity() { set(IDENTITY); } 00260 00263 inline void makeZero() { set(ZERO); } 00264 00275 inline void makeScale(const Vector3& v) { 00276 makeScale(v.x(), v.y(), v.z()); 00277 } 00278 00283 void makeScale(double, double, double); 00284 00290 void makeRotate(const Vector3& from, const Vector3& to); 00291 00297 void makeRotate(double angle, const Vector3& axis); 00298 00303 void makeRotate(double angle, double x, double y, double z); 00304 00307 void makeRotate(const Quat&); 00308 00315 void makeRotate(double roll, double pitch, double yaw); 00316 00326 void makeRotate(double angle1, const Vector3& axis1, 00327 double angle2, const Vector3& axis2, 00328 double angle3, const Vector3& axis3); 00329 00338 bool invert(const Matrix3 &m, double tolerance=1e-12); 00339 00347 inline bool invert(double tolerance=1e-12) { return invert(*this, tolerance); } 00348 00353 void transpose(const Matrix3& other); 00354 00357 inline void transpose() { 00358 swap(_mat[0][1], _mat[1][0]); 00359 swap(_mat[0][2], _mat[2][0]); 00360 swap(_mat[1][2], _mat[2][1]); 00361 } 00362 00367 inline Matrix3 getInverse(double tolerance=1e-12) const { return inverse(*this, tolerance); } 00368 00371 inline Matrix3 getTranspose() const { 00372 return Matrix3(_mat[0][0], _mat[1][0], _mat[2][0], 00373 _mat[0][1], _mat[1][1], _mat[2][1], 00374 _mat[0][2], _mat[1][2], _mat[2][2]); 00375 } 00376 00379 double determinant() const; 00380 00383 inline static Matrix3 const &identity(void) { return IDENTITY; } 00384 00387 inline static Matrix3 scale(const Vector3& sv); 00388 00391 inline static Matrix3 scale(double sx, double sy, double sz); 00392 00395 inline static Matrix3 rotate(const Vector3& from, const Vector3& to); 00396 00399 inline static Matrix3 rotate(double angle, double x, double y, double z); 00402 inline static Matrix3 rotate(double angle, const Vector3& axis); 00403 00406 inline static Matrix3 rotate(double angle1, const Vector3& axis1, 00407 double angle2, const Vector3& axis2, 00408 double angle3, const Vector3& axis3); 00409 00412 inline static Matrix3 rotate(double roll, double pitch, double yaw); 00413 00416 inline static Matrix3 rotate(const Quat& quat); 00417 00420 inline static Matrix3 inverse(const Matrix3& matrix, double tolerance=1e-12); 00423 inline static Matrix3 tensor(const Vector3&a, const Vector3 &b); 00424 00427 void getRotate(double angle, Vector3& axis) const; 00428 00431 void getEulerAngles(double &roll, double &pitch, double &yaw); 00432 00435 inline Vector3 preMult(const Vector3& v) const; 00436 00439 inline Vector3 postMult(const Vector3& v) const; 00440 00443 inline Vector3 operator* (const Vector3& v) const { return postMult(v); } 00444 #ifndef SWIG 00445 00447 inline friend Vector3 operator* (const Vector3& v, const Matrix3& m) { return m.preMult(v); } 00448 #endif // SWIG 00449 00452 inline Vector3 getScale() const { return Vector3(_mat[0][0],_mat[1][1],_mat[2][2]); } 00453 00456 inline double getTrace() const { return _mat[0][0] + _mat[1][1] + _mat[2][2]; } 00457 00460 void mult(const Matrix3&, const Matrix3&); 00461 00464 void preMult(const Matrix3&); 00465 00468 void postMult(const Matrix3&); 00469 00472 inline void operator *= (const Matrix3& other) { 00473 if (this == &other) { 00474 Matrix3 temp(other); 00475 postMult(temp); 00476 } else { 00477 postMult(other); 00478 } 00479 } 00480 00483 inline Matrix3 operator * (const Matrix3& m) const { 00484 Matrix3 r; 00485 r.mult(*this, m); 00486 return r; 00487 } 00488 00491 inline const Matrix3& operator += (const Matrix3& rhs) { 00492 double *m0 = reinterpret_cast<double*>(_mat); 00493 double const *m1 = reinterpret_cast<double const*>(rhs._mat); 00494 for (int i=0; i<9; ++i) { 00495 m0[i] += m1[i]; 00496 } 00497 return *this; 00498 } 00499 00502 inline const Matrix3& operator -= (const Matrix3& rhs) { 00503 double *m0 = reinterpret_cast<double*>(_mat); 00504 double const *m1 = reinterpret_cast<double const*>(rhs._mat); 00505 for (int i=0; i<9; ++i) { 00506 m0[i] -= m1[i]; 00507 } 00508 return *this; 00509 } 00510 00513 inline const Matrix3& operator *= (const double rhs) { 00514 double *m0 = reinterpret_cast<double*>(_mat); 00515 for (int i=0; i<9; ++i) { 00516 m0[i] *= rhs; 00517 } 00518 return *this; 00519 } 00520 00523 inline const Matrix3& operator /= (const double rhs) { 00524 return *this *= (1.0/rhs); 00525 } 00526 00529 inline Matrix3 operator + (const Matrix3& rhs) const { 00530 Matrix3 result; 00531 double *m0 = reinterpret_cast<double*>(result._mat); 00532 double const *m1 = reinterpret_cast<double const*>(_mat); 00533 double const *m2 = reinterpret_cast<double const*>(rhs._mat); 00534 for (int i=0; i<9; ++i) { 00535 m0[i] = m1[i] + m2[i]; 00536 } 00537 return result; 00538 } 00539 00542 inline Matrix3 operator - (const Matrix3& rhs) const { 00543 Matrix3 result; 00544 double *m0 = reinterpret_cast<double*>(result._mat); 00545 double const *m1 = reinterpret_cast<double const*>(_mat); 00546 double const *m2 = reinterpret_cast<double const*>(rhs._mat); 00547 for (int i=0; i<9; ++i) { 00548 m0[i] = m1[i] - m2[i]; 00549 } 00550 return result; 00551 } 00552 00555 inline Matrix3 operator * (double rhs) const { 00556 Matrix3 result; 00557 double *m0 = reinterpret_cast<double*>(result._mat); 00558 double const *m1 = reinterpret_cast<double const*>(_mat); 00559 for (int i=0; i<9; ++i) { 00560 m0[i] = m1[i] * rhs; 00561 } 00562 return result; 00563 } 00564 00567 inline Matrix3 operator / (double rhs) const { 00568 return *this * (1.0/rhs); 00569 } 00570 00573 inline Matrix3 operator - () const { 00574 return *this * (-1.0); 00575 } 00576 00577 #ifndef SWIG 00578 00580 inline friend Matrix3 operator * (double lhs, const Matrix3& rhs) { 00581 return rhs * lhs; 00582 } 00583 00586 friend SIMDATA_EXPORT std::ostream& operator<< (std::ostream& os, const Matrix3& m); 00587 #endif // SWIG 00588 00589 protected: 00591 double _mat[3][3]; 00592 00593 }; 00594 00595 00596 inline Matrix3 Matrix3::scale(double sx, double sy, double sz) { 00597 return Matrix3(sx, 0.0, 0.0, 0.0, sy, 0.0, 0.0, 0.0, sz); 00598 } 00599 00600 inline Matrix3 Matrix3::scale(const Vector3& v) { 00601 return Matrix3(v.x(), 0.0, 0.0, 0.0, v.y(), 0.0, 0.0, 0.0, v.z()); 00602 } 00603 00604 inline Matrix3 Matrix3::rotate(const Quat& q) { 00605 Matrix3 m; 00606 m.makeRotate(q); 00607 return m; 00608 } 00609 00610 inline Matrix3 Matrix3::rotate(double roll, double pitch, double yaw) { 00611 Matrix3 m; 00612 m.makeRotate(roll, pitch, yaw); 00613 return m; 00614 } 00615 00616 inline Matrix3 Matrix3::rotate(double angle, double x, double y, double z) { 00617 Matrix3 m; 00618 m.makeRotate(angle, x, y, z); 00619 return m; 00620 } 00621 00622 inline Matrix3 Matrix3::rotate(double angle, const Vector3& axis) { 00623 Matrix3 m; 00624 m.makeRotate(angle, axis); 00625 return m; 00626 } 00627 00628 inline Matrix3 Matrix3::rotate(double angle1, const Vector3& axis1, 00629 double angle2, const Vector3& axis2, 00630 double angle3, const Vector3& axis3) 00631 { 00632 Matrix3 m; 00633 m.makeRotate(angle1, axis1, angle2, axis2, angle3, axis3); 00634 return m; 00635 } 00636 00637 inline Matrix3 Matrix3::rotate(const Vector3& from, const Vector3& to) { 00638 Matrix3 m; 00639 m.makeRotate(from, to); 00640 return m; 00641 } 00642 00643 inline Matrix3 Matrix3::inverse(const Matrix3& matrix, double tolerance) { 00644 Matrix3 m; 00645 m.invert(matrix, tolerance); 00646 return m; 00647 } 00648 00649 inline Matrix3 Matrix3::tensor(const Vector3&a, const Vector3 &b) { 00650 return Matrix3(a.x()*b.x(), 00651 a.x()*b.y(), 00652 a.x()*b.z(), 00653 a.y()*b.x(), 00654 a.y()*b.y(), 00655 a.y()*b.z(), 00656 a.z()*b.x(), 00657 a.z()*b.y(), 00658 a.z()*b.z()); 00659 } 00660 00661 inline Vector3 Matrix3::postMult(const Vector3& v) const { 00662 return Vector3((_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z()), 00663 (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z()), 00664 (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z())); 00665 } 00666 00667 inline Vector3 Matrix3::preMult(const Vector3& v) const { 00668 return Vector3((_mat[0][0]*v.x() + _mat[1][0]*v.y() + _mat[2][0]*v.z()), 00669 (_mat[0][1]*v.x() + _mat[1][1]*v.y() + _mat[2][1]*v.z()), 00670 (_mat[0][2]*v.x() + _mat[1][2]*v.y() + _mat[2][2]*v.z())); 00671 } 00672 00673 00674 NAMESPACE_SIMDATA_END 00675 00676 00677 #endif // __SIMDATA_MATRIX3_H__ 00678
|
SimData version pre-0.4.0. For more information on SimData, visit the SimData Homepage. Generated on Tue Oct 14 12:06:39 2003, using Doxygen 1.2.18. |