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

Quat.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_QUAT_H__
00036 #define __SIMDATA_QUAT_H__
00037 
00038 
00039 #include <SimData/BaseType.h>
00040 #include <SimData/Vector3.h>
00041 #include <SimData/Matrix3.h>
00042 
00043 #include <string>
00044 #include <vector>
00045 #include <iostream>
00046 #include <algorithm>
00047 #include <cmath>
00048 
00049 
00050 NAMESPACE_SIMDATA
00051 
00052 
00063 class SIMDATA_EXPORT Quat: public BaseType
00064 {
00065         double _x, _y, _z, _w;
00066 public:
00067 
00069         static const Quat IDENTITY;
00071         static const Quat ZERO;
00072 
00075         virtual void serialize(Archive&);
00076 
00081         virtual void parseXML(const char* cdata);
00082 
00085         virtual std::string asString() const;
00086 
00089         virtual std::string typeString() const { return "type::Quat"; }
00090 
00095         inline Quat(): _x(0.0), _y(0.0), _z(0.0), _w(0.0) {}
00096 
00101         inline Quat(double x_, double y_, double z_, double w_):  
00102                 _x(x_), _y(y_), _z(z_), _w(w_) 
00103         {
00104         }
00105 
00111         inline Quat(double angle, const Vector3& axis) { makeRotate(angle, axis); }
00112 
00117         inline Quat(const Matrix3 &m) { set(m); }
00118 
00128         inline Quat(double angle1, const Vector3& axis1, 
00129                     double angle2, const Vector3& axis2,
00130                     double angle3, const Vector3& axis3)
00131         {
00132                 makeRotate(angle1, axis1, angle2, axis2, angle3, axis3);
00133         }
00134 
00137         inline const Vector3 asVector3() const {
00138                 return Vector3(_x, _y, _z);
00139         }
00140 
00143         inline void set(double x_, double y_, double z_, double w_) {
00144                 _x = x_; _y = y_; _z = z_; _w = w_;
00145         }
00146 
00147 #ifndef SWIG
00148 
00150         inline double& operator [] (int i) { 
00151                 switch (i) {
00152                         case 0: return _x;
00153                         case 1: return _y;
00154                         case 2: return _z;
00155                         case 3: return _w;
00156                         default:
00157                                 throw ""; // FIXME
00158                 }
00159         }
00160 
00163         inline double  operator [] (int i) const { 
00164                 switch (i) {
00165                         case 0: return _x;
00166                         case 1: return _y;
00167                         case 2: return _z;
00168                         case 3: return _w;
00169                         default:
00170                                 throw ""; // FIXME
00171                 }
00172         }
00173 
00175         inline double& x() { return _x; }
00177         inline double& y() { return _y; }
00179         inline double& z() { return _z; }
00181         inline double& w() { return _w; }
00182 
00184         inline double x() const { return _x; }
00186         inline double y() const { return _y; }
00188         inline double z() const { return _z; }
00190         inline double w() const { return _w; }
00191 #endif // SWIG
00192 
00194         bool operator==(Quat const &rhs) const {
00195                 return _x==rhs._x && _y==rhs._y && _z==rhs._z && _w==rhs._w;
00196         }
00197 
00199         bool operator!=(Quat const &rhs) const {
00200                 return !(*this == rhs);
00201         }
00202 
00207         bool zeroRotation() const { 
00208                 return _x==0.0 && _y==0.0 && _z==0.0 && _w==1.0; 
00209         } 
00210 
00211 
00213         inline const Quat operator * (double rhs) const {
00214                 return Quat(_x*rhs, _y*rhs, _z*rhs, _w*rhs);
00215         }
00216 
00218         inline Quat& operator *= (double rhs) {
00219                 _x *= rhs; _y *= rhs; _z *= rhs; _w *= rhs;     
00220                 return *this;
00221         }
00222 
00224         inline const Quat operator*(const Quat& rhs) const {
00225                 return Quat(rhs._w*_x + rhs._x*_w - rhs._y*_z + rhs._z*_y,
00226                             rhs._w*_y + rhs._x*_z + rhs._y*_w - rhs._z*_x,
00227                             rhs._w*_z - rhs._x*_y + rhs._y*_x + rhs._z*_w,
00228                             rhs._w*_w - rhs._x*_x - rhs._y*_y - rhs._z*_z);
00229         }
00230 
00232         inline Quat& operator*=(const Quat& rhs) {
00233                 double x_ = rhs._w*_x + rhs._x*_w - rhs._y*_z + rhs._z*_y;
00234                 double y_ = rhs._w*_y + rhs._x*_z + rhs._y*_w - rhs._z*_x;
00235                 double z_ = rhs._w*_z - rhs._x*_y + rhs._y*_x + rhs._z*_w;
00236                 _w = rhs._w*_w - rhs._x*_x - rhs._y*_y - rhs._z*_z;
00237                 _z = z_;
00238                 _y = y_;
00239                 _x = x_;
00240                 return *this;   
00241         }
00242 
00244         inline const Quat operator / (double rhs) const {
00245                 return *this * (1.0/rhs);
00246         }
00247 
00249         inline Quat& operator /= (double rhs) {
00250                 return *this *= (1.0 / rhs);
00251         }
00252 
00254         inline const Quat operator/(const Quat& denom) const {
00255                 return *this * denom.inverse();
00256         }
00257 
00259         inline Quat& operator/=(const Quat& denom) {
00260                 return *this *= denom.inverse();
00261         }
00262 
00264         inline const Quat operator + (const Quat& rhs) const {
00265                 return Quat(_x+rhs._x, _y+rhs._y, _z+rhs._z, _w+rhs._w);
00266         }
00267 
00269         inline Quat& operator += (const Quat& rhs) {
00270                 _x += rhs._x; _y += rhs._y; _z += rhs._z; _w += rhs._w;
00271                 return *this;
00272         }
00273 
00275         inline const Quat operator - (const Quat& rhs) const {
00276                 return Quat(_x-rhs._x, _y-rhs._y, _z-rhs._z, _w-rhs._w);
00277         }
00278 
00280         inline Quat& operator -= (const Quat& rhs) {
00281                 _x -= rhs._x; _y -= rhs._y; _z -= rhs._z; _w -= rhs._w;
00282                 return *this;
00283         }
00284 
00286         inline const Quat operator - () const {
00287                 return Quat(-_x, -_y, -_z, -_w);
00288         }
00289 
00291         double length() const {
00292                 return sqrt(_x*_x + _y*_y + _z*_z + _w*_w);
00293         }
00294 
00296         double length2() const {
00297                 return (_x*_x + _y*_y + _z*_z + _w*_w);
00298         }
00299 
00301         inline Quat conj() const { 
00302                 return Quat(-_x, -_y, -_z, _w);
00303         }
00304 
00306         inline Quat operator ~() const {
00307                 return Quat(-_x, -_y, -_z, _w);
00308         }
00309 
00311         inline const Quat inverse () const {
00312                 return conj() / length2();
00313         }
00314 
00322         void makeRotate(double angle, 
00323                         double x, double y, double z);
00324 
00330         void makeRotate(double angle, const Vector3& vec);
00331 
00341         void makeRotate(double angle1, const Vector3& axis1, 
00342                         double angle2, const Vector3& axis2,
00343                         double angle3, const Vector3& axis3);
00344 
00347         void makeRotate(const Vector3& vec1, const Vector3& vec2);
00348 
00355         void makeRotate(double roll, double pitch, double yaw);
00356 
00357         void getEulerAngles(double &roll, double &pitch, double &yaw) const;
00358     
00361         void getRotate(double& angle, double& x, double& y, double& z) const;
00362 
00365         void getRotate(double& angle, Vector3& vec) const;
00366 
00370         void slerp(double t, const Quat& from, const Quat& to);
00371         
00374         void set(const Matrix3& m);
00375 
00378         void get(Matrix3& m) const;
00379 
00382         Matrix3 getMatrix3() const {
00383                 Matrix3 matrix;
00384                 get(matrix);
00385                 return matrix;
00386         }
00387         
00390         Vector3 rotate(const Vector3 &v) const;
00391 
00394         Vector3 invrotate(const Vector3 &v) const;
00395 
00398         inline Quat rotate(const Quat &q) const { return (*this)*q*conj(); }
00399 
00402         inline Quat invrotate(const Quat &q) const { return conj()*q*(*this); }
00403 
00404 #ifndef SWIG
00405 
00407         friend inline std::ostream& operator << (std::ostream& output, const Quat& vec);
00410         friend inline Quat operator * (double lhs, const Quat& rhs) { return rhs*lhs; }
00413         friend inline Quat operator *(Quat const& lhs, Vector3 const& rhs) {
00414                 return Quat( lhs.w()*rhs.x() + lhs.y()*rhs.z() - lhs.z()*rhs.y(),
00415                              lhs.w()*rhs.y() + lhs.z()*rhs.x() - lhs.x()*rhs.z(),
00416                              lhs.w()*rhs.z() + lhs.x()*rhs.y() - lhs.y()*rhs.x(),
00417                             -lhs.x()*rhs.x() - lhs.y()*rhs.y() - lhs.z()*rhs.z());
00418         }
00419 
00422         friend inline Quat operator *(Vector3 const& lhs, Quat const& rhs) {
00423                 return Quat( rhs.w()*lhs.x() + rhs.z()*lhs.y() - rhs.y()*lhs.z(),
00424                              rhs.w()*lhs.y() + rhs.x()*lhs.z() - rhs.z()*lhs.x(),
00425                              rhs.w()*lhs.z() + rhs.y()*lhs.x() - rhs.x()*lhs.y(),
00426                             -rhs.x()*lhs.x() - rhs.y()*lhs.y() - rhs.z()*lhs.z());
00427         }
00428 #endif // SWIG
00429 
00430 #ifdef SWIG
00431         // setup accessors for w, x, y, and z (ugly hack)
00432 %extend {
00433         void set_w(double w) { self->w()=w; }
00434         void set_x(double x) { self->x()=x; }
00435         void set_y(double y) { self->y()=y; }
00436         void set_z(double z) { self->z()=z; }
00437         double get_w() { return self->w(); }
00438         double get_x() { return self->x(); }
00439         double get_y() { return self->y(); }
00440         double get_z() { return self->z(); }
00441 }
00442 %insert("shadow") %{
00443         if _newclass:
00444                 w = property(_cSimData.Quat_get_w, _cSimData.Quat_set_w)
00445                 x = property(_cSimData.Quat_get_x, _cSimData.Quat_set_x)
00446                 y = property(_cSimData.Quat_get_y, _cSimData.Quat_set_y)
00447                 z = property(_cSimData.Quat_get_z, _cSimData.Quat_set_z)
00448         __swig_setmethods__["w"] = _cSimData.Quat_set_w
00449         __swig_getmethods__["w"] = _cSimData.Quat_get_w
00450         __swig_setmethods__["x"] = _cSimData.Quat_set_x
00451         __swig_getmethods__["x"] = _cSimData.Quat_get_x
00452         __swig_setmethods__["y"] = _cSimData.Quat_set_y
00453         __swig_getmethods__["y"] = _cSimData.Quat_get_y
00454         __swig_setmethods__["z"] = _cSimData.Quat_set_z
00455         __swig_getmethods__["z"] = _cSimData.Quat_get_z
00456 %}
00457 #endif // SWIG
00458 
00459 };      // end of class prototype
00460 
00461 
00462 inline std::ostream& operator << (std::ostream& output, const Quat& quat)
00463 {
00464     output << "[" << quat._x
00465            << " " << quat._y
00466            << " " << quat._z
00467            << " " << quat._w << "]";
00468     return output;
00469 }
00470 
00471 
00472 NAMESPACE_SIMDATA_END
00473 
00474 #endif  // __SIMDATA_QUAT_H__
00475 

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]