Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

base/Quat4

Go to the documentation of this file.
00001 /* **-*-c++-*-**************************************************************
00002   Copyright (C)1996 David Jung <opensim@pobox.com>
00003 
00004   This program/file is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details. (http://www.gnu.org)
00013   
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017   
00018   $Id: Quat4 1029 2004-02-11 20:45:54Z jungd $
00019   $Revision: 1.9 $
00020   $Date: 2004-02-11 15:45:54 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #ifndef _BASE_QUAT4_
00026 #define _BASE_QUAT4_
00027 
00028 #include <iostream>
00029 
00030 #include <base/base>
00031 #include <base/consts>
00032 #include <base/Object>
00033 #include <base/Vector3>
00034 #include <base/Vector4>
00035 #include <base/Point3>
00036 #include <base/Point4>
00037 #include <base/Matrix4>
00038 
00039 
00040 namespace base {
00041 
00042 class Quat4;
00043 class Serializer;
00044 inline Quat4 inverse(const Quat4& q); //forward
00045 
00046 
00047 /**
00048  * Quaternion.
00049  * Used for representing rotations.
00050  */
00051 class Quat4
00052 {
00053 
00054 public:
00055   Quat4() { setIdentity(); }
00056   Quat4(const Quat4& q) { this->operator=(q); }
00057   Quat4(const Vector3& v) : v(v), w(Real(1)) {}
00058   Quat4(const Vector4& v) : v(v.x,v.y,v.z), w(v.w) {}
00059   explicit Quat4(const Real& s) : v(Real(0),Real(0),Real(0)), w(s) {}
00060   Quat4(Real x, Real y, Real z, Real w) : v(x,y,z), w(w) {}
00061   Quat4(const Vector3& axis, Real angle) { setRotation(axis,angle); }
00062   ~Quat4() {}
00063 
00064   static const Int X = 1;
00065   static const Int Y = 2;
00066   static const Int Z = 3;
00067   static const Int W = 4;
00068 
00069   void setIdentity() throw()
00070   {
00071     v.x=v.y=v.z=Real(0); w=Real(1);
00072   }
00073 
00074   void setZero() throw()
00075   {
00076     setIdentity(); w=Real(0);
00077   }
00078 
00079 
00080   Real& e(Int i) throw()
00081   {
00082 #ifdef DEBUG
00083     if ((i < 1) || (i > 4))
00084       throw std::runtime_error(Exception("quaternion index out of bounds (debug only check)"));
00085 #endif 
00086     return (i<4)?v.e(i):w; 
00087   }
00088 
00089   const Real& e(Int i) const throw()
00090   {
00091 #ifdef DEBUG
00092     if ((i < 1) || (i > 4))
00093       throw std::runtime_error(Exception("quaternion index out of bounds (debug only check)"));
00094 #endif 
00095     return (i<4)?v.e(i):w; 
00096   }
00097 
00098   Real& at(Int i) throw(std::out_of_range)
00099   {
00100     if ((i < 1) || (i > 4))
00101       throw std::out_of_range(Exception("quaternion index out of bounds"));
00102 
00103     return (i<4)?v.e(i):w;
00104   }
00105 
00106   const Real& at(Int i) const throw(std::out_of_range)
00107   {
00108     if ((i < 1) || (i > 4))
00109       throw std::out_of_range(Exception("quaternion index out of bounds"));
00110 
00111     return (i<3)?v.e(i):w;
00112   }
00113 
00114   Real& operator[](Int i)  
00115   { return e(i); }
00116 
00117   const Real& operator[](Int i) const
00118   { return e(i); }
00119 
00120   Quat4& operator=(const Quat4& src) throw()
00121   {
00122     if (&src != this) {
00123       v=src.v; w=src.w;
00124     }
00125     return *this;
00126   }
00127 
00128   bool operator==(const Quat4& q) const throw()
00129   {
00130     if (&q == this) return true;
00131     
00132     return ((v==q.v)&&(w==q.w));
00133   }
00134 
00135   bool equals(const Quat4& q) const throw()
00136   {
00137     if (&q == this) return true;
00138 
00139     return (v.equals(q.v) && (base::equals(w,q.w)));
00140   }
00141 
00142   Real norm() const throw()
00143   { return v.x*v.x+v.y*v.y+v.z*v.z+w*w; }
00144 
00145   Quat4& normalize() throw()
00146     {
00147       Real n = norm();
00148       
00149       if ((!base::equals(n,1)) && (n>0)) {
00150         Real l = base::sqrt(n);
00151         v /= l;
00152         w /= l;
00153       }
00154       return *this;
00155     }
00156 
00157   Quat4& conjugate() { v.negate(); return *this; }
00158 
00159   Quat4& invert() throw()   
00160   {
00161     Real n;
00162     if (base::equals(n=norm(),1))
00163       conjugate(); 
00164     else {
00165       conjugate();
00166       if (n>0)
00167         *this /= n;
00168     }
00169     return *this;
00170   }
00171 
00172   Quat4& operator*=(const Quat4& qr);
00173   Quat4& operator*=(Real s) { v*=s; w*=s; return *this; }
00174   Quat4& operator/=(Real s) { v/=s; w/=s; return *this; }
00175   Quat4& operator+=(const Quat4& q) { v+=q.v; w+=q.w; return *this; }
00176   Quat4& operator-=(const Quat4& q) { v-=q.v; w-=q.w; return *this; }
00177 
00178   Quat4& negate() throw() { v.negate(); w=-w; return *this; }
00179 
00180   /// Generate quat corresponding to rotation component of matrix.
00181   void setRotation(const Matrix4& rotation);
00182 
00183   void setRotation(const Vector3& axis, Real angle);
00184   void getRotation(Vector3& axis, Real& angle) const; 
00185   void rotatePoint(Point4& p) const;
00186   void rotatePoint(Point3& p) const 
00187     { Point4 p4(p); p4.w=0; rotatePoint(p4); p=Point3(p4.x,p4.y,p4.z); }
00188   Point3 rotate(const Point3& p) const 
00189     { Point4 ret(p); rotatePoint(ret); return Point3(ret.x,ret.y,ret.z); }
00190   Point4 rotate(const Point4& p) const
00191     { Point4 ret(p); rotatePoint(ret); return ret; }
00192 
00193   static Quat4 interpolate(const Quat4& from, const Quat4& to, Real t); ///< interpolate between from-to an amount t:[0..1] using SLERP
00194   static Real  angleBetween(const Quat4& q1, const Quat4& q2); ///< angle seperating the orientations q1 & q2
00195 
00196   operator Matrix4() const;   ///< convert to corresponding rotation matrix
00197 
00198   Real* c_array() { return &v.x; }
00199 
00200   void serialize(Serializer& s); ///< read or write object state to Serializer
00201 
00202   Vector3 v;
00203   Real w;
00204 
00205   friend std::ostream& operator<<(std::ostream&, const Quat4&); 
00206 
00207 };
00208 
00209 
00210 // Operations
00211 
00212 
00213 inline Quat4 operator*(const Quat4& q1, const Quat4& q2) // Quaternion multiplication
00214 { Quat4 r(q1); return (r *= q2); }
00215 
00216 inline Quat4 operator+(const Quat4& q1, const Quat4& q2) // Addition
00217 { Quat4 r(q1); return (r += q2); }
00218 
00219 inline Quat4 operator-(const Quat4& q1, const Quat4& q2) // Subtraction
00220 { Quat4 r(q1); return (r += q2); }
00221 
00222 inline Quat4 operator-(const Quat4& q1) // Negation
00223 { Quat4 r(q1); return r.negate(); }
00224 
00225 inline Quat4 operator*(const Quat4& q1, const Real& s) // Scalar multiplication
00226 { Quat4 r(q1); return (r *= s); }
00227 
00228 inline Quat4 operator*(const Real& s, const Quat4& q1) // Scalar multiplication
00229 { Quat4 r(q1); return (r *= s); }
00230 
00231 inline Quat4 operator/(const Quat4& q1, const Real& s) // Scalar division
00232 { Quat4 r(q1); return (r /= s); }
00233 
00234 inline Quat4 inverse(const Quat4& q) // inverse q^-1
00235 { Quat4 r(q); return r.invert(); }
00236 
00237 inline Quat4 conjugate(const Quat4& q)  // conjugate q*
00238 { Quat4 r(q); return r.conjugate(); }
00239 
00240 
00241 std::ostream& operator<<(std::ostream& out, const Quat4& q); // Output
00242 
00243 
00244 } // base
00245 
00246 #endif
00247 

Generated on Thu Jul 29 15:56:11 2004 for OpenSim by doxygen 1.3.6