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. |