quaternion.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
00004 
00005  This file is part of the QGLViewer library version 2.4.0.
00006 
00007  http://www.libqglviewer.com - contact@libqglviewer.com
00008 
00009  This file may be used under the terms of the GNU General Public License 
00010  versions 2.0 or 3.0 as published by the Free Software Foundation and
00011  appearing in the LICENSE file included in the packaging of this file.
00012  In addition, as a special exception, Gilles Debunne gives you certain 
00013  additional rights, described in the file GPL_EXCEPTION in this package.
00014 
00015  libQGLViewer uses dual licensing. Commercial/proprietary software must
00016  purchase a libQGLViewer Commercial License.
00017 
00018  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00019  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00020 
00021 *****************************************************************************/
00022 
00023 #ifndef QGLVIEWER_QUATERNION_H
00024 #define QGLVIEWER_QUATERNION_H
00025 
00026 #include "vec.h"
00027 #include <math.h>
00028 #include <iostream>
00029 
00030 namespace qglviewer {
00066         class QGLVIEWER_EXPORT Quaternion
00067         {
00068         public:
00072                 Quaternion()
00073                 { q[0]=q[1]=q[2]=0.0;  q[3]=1.0; }
00074 
00076                 Quaternion(const Vec& axis, double angle)
00077                 {
00078                         setAxisAngle(axis, angle);
00079                 }
00080 
00081                 Quaternion(const Vec& from, const Vec& to);
00082 
00088                 Quaternion(double q0, double q1, double q2, double q3)
00089                 { q[0]=q0;    q[1]=q1;    q[2]=q2;    q[3]=q3; }
00090 
00092                 Quaternion(const Quaternion& Q)
00093                 { for (int i=0; i<4; ++i) q[i] = Q.q[i]; }
00094 
00096                 Quaternion& operator=(const Quaternion& Q)
00097                 {
00098                         for (int i=0; i<4; ++i)
00099                                 q[i] = Q.q[i];
00100                         return (*this);
00101                 }
00102 
00106                 void setAxisAngle(const Vec& axis, double angle)
00107                 {
00108                         const double norm = axis.norm();
00109                         if (norm < 1E-8)
00110                         {
00111                                 // Null rotation
00112                                 q[0] = 0.0;      q[1] = 0.0;      q[2] = 0.0;      q[3] = 1.0;
00113                         }
00114                         else
00115                         {
00116                                 const double sin_half_angle = sin(angle / 2.0);
00117                                 q[0] = sin_half_angle*axis[0]/norm;
00118                                 q[1] = sin_half_angle*axis[1]/norm;
00119                                 q[2] = sin_half_angle*axis[2]/norm;
00120                                 q[3] = cos(angle / 2.0);
00121                         }
00122                 }
00123 
00125                 void setValue(double q0, double q1, double q2, double q3)
00126                 { q[0]=q0;    q[1]=q1;    q[2]=q2;    q[3]=q3; }
00127 
00128 #ifndef DOXYGEN
00129                 void setFromRotationMatrix(const float m[3][3]);
00130                 void setFromRotatedBase(const Vec& X, const Vec& Y, const Vec& Z);
00131 #endif
00132                 void setFromRotationMatrix(const double m[3][3]);
00133                 void setFromRotatedBasis(const Vec& X, const Vec& Y, const Vec& Z);
00135 
00136 
00139                 Vec axis() const;
00140                 double angle() const;
00141                 void getAxisAngle(Vec& axis, float& angle) const;
00142 
00144                 double operator[](int i) const { return q[i]; }
00145 
00147                 double& operator[](int i) { return q[i]; }
00149 
00150 
00164                 friend Quaternion operator*(const Quaternion& a, const Quaternion& b)
00165                 {
00166                         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],
00167                                 a.q[3]*b.q[1] + b.q[3]*a.q[1] + a.q[2]*b.q[0] - a.q[0]*b.q[2],
00168                                 a.q[3]*b.q[2] + b.q[3]*a.q[2] + a.q[0]*b.q[1] - a.q[1]*b.q[0],
00169                                 a.q[3]*b.q[3] - b.q[0]*a.q[0] - a.q[1]*b.q[1] - a.q[2]*b.q[2]);
00170                 }
00171 
00178                 Quaternion& operator*=(const Quaternion &q)
00179                 {
00180                         *this = (*this)*q;
00181                         return *this;
00182                 }
00183 
00187                 friend Vec operator*(const Quaternion& q, const Vec& v)
00188                 {
00189                         return q.rotate(v);
00190                 }
00191 
00192                 Vec rotate(const Vec& v) const;
00193                 Vec inverseRotate(const Vec& v) const;
00195 
00196 
00205                 Quaternion inverse() const { return Quaternion(-q[0], -q[1], -q[2], q[3]); }
00206 
00210                 void invert() { q[0] = -q[0]; q[1] = -q[1]; q[2] = -q[2]; }
00211 
00220                 void negate() { invert(); q[3] = -q[3]; }
00221 
00227                 double normalize()
00228                 {
00229                         const double norm = sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
00230                         for (int i=0; i<4; ++i)
00231                                 q[i] /= norm;
00232                         return norm;
00233                 }
00234 
00238                 Quaternion normalized() const
00239                 {
00240                         double Q[4];
00241                         const double norm = sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
00242                         for (int i=0; i<4; ++i)
00243                                 Q[i] = q[i] / norm;
00244                         return Quaternion(Q[0], Q[1], Q[2], Q[3]);
00245                 }
00247 
00248 
00251                 const GLdouble* matrix() const;
00252                 void getMatrix(GLdouble m[4][4]) const;
00253                 void getMatrix(GLdouble m[16]) const;
00254 
00255                 void getRotationMatrix(float m[3][3]) const;
00256 
00257                 const GLdouble* inverseMatrix() const;
00258                 void getInverseMatrix(GLdouble m[4][4]) const;
00259                 void getInverseMatrix(GLdouble m[16]) const;
00260 
00261                 void getInverseRotationMatrix(float m[3][3]) const;
00263 
00264 
00267                 static Quaternion slerp(const Quaternion& a, const Quaternion& b, float t, bool allowFlip=true);
00268                 static Quaternion squad(const Quaternion& a, const Quaternion& tgA, const Quaternion& tgB, const Quaternion& b, float t);
00270                 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]; }
00271 
00272                 Quaternion log();
00273                 Quaternion exp();
00274                 static Quaternion lnDif(const Quaternion& a, const Quaternion& b);
00275                 static Quaternion squadTangent(const Quaternion& before, const Quaternion& center, const Quaternion& after);
00277 
00280                 static Quaternion randomQuaternion();
00282 
00285                 explicit Quaternion(const QDomElement& element);
00286                 QDomElement domElement(const QString& name, QDomDocument& document) const;
00287                 void initFromDOMElement(const QDomElement& element);
00289 
00290 #ifdef DOXYGEN
00291 
00298                 std::ostream& operator<<(std::ostream& o, const qglviewer::Vec&);
00300 #endif
00301 
00302         private:
00304                 double q[4];
00305         };
00306 
00307 } // namespace
00308 
00309 std::ostream& operator<<(std::ostream& o, const qglviewer::Quaternion&);
00310 
00311 #endif // QGLVIEWER_QUATERNION_H


octovis
Author(s): Kai M. Wurm , Armin Hornung
autogenerated on Thu Feb 11 2016 23:51:20