Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

Matrix3.h

Go to the documentation of this file.
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.

[SF.net]