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

quaternion.h

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the QGLViewer library
00004  Copyright (C) 2002-2004  Gilles Debunne (Gilles.Debunne@imag.fr)
00005  Version 1.3.5 Release 8. Packaged on Monday December 22, 2003.
00006 
00007  http://www-imagis.imag.fr/Membres/Gilles.Debunne/CODE/QGLViewer
00008 
00009  libQGLViewer is free software; you can redistribute it and/or modify
00010  it under the terms of the GNU General Public License as published by
00011  the Free Software Foundation; either version 2 of the License, or
00012  (at your option) any later version.
00013 
00014  libQGLViewer is distributed in the hope that it will be useful,
00015  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  GNU General Public License for more details.
00018 
00019  You should have received a copy of the GNU General Public License
00020  along with libQGLViewer; if not, write to the Free Software
00021  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 
00023 *****************************************************************************/
00024 
00025 #ifndef QGLVIEWER_QUATERNION_H
00026 #define QGLVIEWER_QUATERNION_H
00027 
00028 #include "vec.h"
00029 #include <math.h>
00030 #include <iostream>
00031 
00032 namespace qglviewer {
00060 class QGLVIEWER_EXPORT Quaternion
00061 {
00062 public:
00065 
00066   explicit Quaternion()
00067   { q[0]=q[1]=q[2]=0.0;  q[3]=1.0; }
00068 
00070   explicit Quaternion(const Vec& axis, const double angle)
00071   {
00072     setAxisAngle(axis, angle);
00073   }
00074 
00076   explicit Quaternion(const Vec& v, const double sin_ha, const double cos_ha)
00077   {
00078     q[0] = v[0]*sin_ha ;
00079     q[1] = v[1]*sin_ha ;
00080     q[2] = v[2]*sin_ha ;
00081     q[3] = cos_ha ;
00082   }
00083   
00085   explicit Quaternion(const double q0, const double q1, const double q2, const double q3)
00086   { q[0]=q0;    q[1]=q1;    q[2]=q2;    q[3]=q3; }
00087 
00089   explicit Quaternion(const Vec& from, const Vec& to);
00090 
00092   Quaternion& operator=(const Quaternion& Q)
00093   {
00094     for (int i=0; i<4; ++i)
00095       q[i] = Q.q[i];
00096     return (*this);
00097   }
00098 
00100   Quaternion(const Quaternion& Q)
00101   { for (int i=0; i<4; ++i) q[i] = Q.q[i]; }
00103 
00104   void setAxisAngle(const Vec& v, const double angle)
00105   {
00106     const double norm = v.norm();
00107     if (norm < 1E-9)
00108       {
00109     // Null rotation
00110     q[0] = 0.0;      q[1] = 0.0;      q[2] = 0.0;      q[3] = 1.0;
00111       }
00112     else
00113       {
00114     const double sin_half_angle = sin(angle / 2.0);
00115     q[0] = sin_half_angle*v[0]/norm;
00116     q[1] = sin_half_angle*v[1]/norm;
00117     q[2] = sin_half_angle*v[2]/norm;
00118     q[3] = cos(angle / 2.0);
00119       }
00120   }
00121 
00123   void setValue(const double q0, const double q1, const double q2, const double q3)
00124   { q[0]=q0;    q[1]=q1;    q[2]=q2;    q[3]=q3; }
00125 
00126   void setFromRotationMatrix(const float m[3][3]);
00127   void setFromRotatedBase(const Vec& X,
00128               const Vec& Y,
00129               const Vec& Z);
00131 
00132   
00135   Vec axis() const;  
00136   float angle() const;
00137   void getAxisAngle(Vec& axis, float& angle) const;
00138 
00140   double operator[](int i) const { return q[i]; }
00141 
00143   double& operator[](int i) { return q[i]; }
00145 
00146 
00149 
00150 
00151 
00152   friend const Quaternion operator*(const Quaternion& a, const Quaternion& b)
00153   {
00154     return Quaternion (a.q[3]*b.q[0] + b.q[3]*a.q[0] + a.q[1]*b.q[2] - a.q[2]*b.q[1],
00155                a.q[3]*b.q[1] + b.q[3]*a.q[1] + a.q[2]*b.q[0] - a.q[0]*b.q[2],
00156                a.q[3]*b.q[2] + b.q[3]*a.q[2] + a.q[0]*b.q[1] - a.q[1]*b.q[0],
00157                a.q[3]*b.q[3] - b.q[0]*a.q[0] - a.q[1]*b.q[1] - a.q[2]*b.q[2]);
00158   }
00159 
00163   Quaternion& operator*=(const Quaternion &q)
00164   {
00165     *this = (*this)*q;
00166     return *this;
00167   }
00168 
00170   friend const Vec operator*(const Quaternion& a, const Vec& b)
00171   {
00172     return a.rotate(b);
00173   }
00174   
00175   Vec inverseRotate(const Vec& v) const;
00176   Vec rotate(const Vec& v) const;
00178 
00179 
00182 
00183   Quaternion inverse() const { return Quaternion(-q[0], -q[1], -q[2], q[3]); }
00184 
00186   void invert() { q[0] = -q[0]; q[1] = -q[1]; q[2] = -q[2]; }
00187 
00191   void negate() { invert(); q[3] = -q[3]; }
00192 
00194   double normalize()
00195   {
00196     const double norm = sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
00197     for (int i=0; i<4; ++i)
00198       q[i] /= norm;
00199     return norm;
00200   }
00202 
00203   
00206   const GLdouble* matrix() const;
00207   void getMatrix(GLdouble m[4][4]) const;
00208   void getMatrix(GLdouble m[16]) const;
00209 
00210   void getRotationMatrix(float m[3][3]) const;
00212 
00213   
00216   static Quaternion slerp(const Quaternion& a, const Quaternion& b, float t, bool allowFlip=true);
00217   static Quaternion squad(const Quaternion& a, const Quaternion& tgA, const Quaternion& tgB, const Quaternion& b, float t);
00219   static double dot(const Quaternion& a, const Quaternion& b) { return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3]; }
00220 
00221   Quaternion log();
00222   Quaternion exp();
00223   static Quaternion lnDif(const Quaternion& a, const Quaternion& b);
00224   static Quaternion squadTangent(const Quaternion& a, const Quaternion& b, const Quaternion& c);
00226 
00229   static Quaternion randomOrientation();
00231   
00234   QDomElement domElement(const QString& name, QDomDocument& doc) const;  
00235   void initFromDOMElement(const QDomElement& de);
00237 
00238 private: 
00240   double q[4];
00241 };
00242 
00243 } // namespace
00244 
00245 std::ostream& operator<<(std::ostream& o, const qglviewer::Quaternion&);
00246 
00247 #endif // QGLVIEWER_QUATERNION_H

Generated on Fri Feb 27 12:01:39 2004 for Glitch by doxygen 1.3.2