libmoldeo (Moldeo 1.0 Core)  1.0
libmoldeo is the group of objects and functions that executes the basic operations of Moldeo 1.0 Platform.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
moMathQuaternion.h
Go to the documentation of this file.
1 /*******************************************************************************
2 
3  moMathQuaternion.h
4 
5  ****************************************************************************
6  * *
7  * This source is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This code is distributed in the hope that it will be useful, but *
13  * WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
15  * General Public License for more details. *
16  * *
17  * A copy of the GNU General Public License is available on the World *
18  * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
19  * obtain it by writing to the Free Software Foundation, *
20  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21  * *
22  ****************************************************************************
23 
24  Copyright(C) 2006 Fabricio Costa
25 
26  Authors:
27  Fabricio Costa
28  Andrés Colubri
29 
30  Portions taken from
31  Wild Magic Source Code
32  David Eberly
33  http://www.geometrictools.com
34  Copyright (c) 1998-2007
35 
36 *******************************************************************************/
37 
38 #include "moMathMatrix.h"
39 
40 #ifndef __MO_MATH_QUATERNION_H__
41 #define __MO_MATH_QUATERNION_H__
42 
43 template <class Real>
45 {
46 public:
47  // A quaternion is q = w + x*i + y*j + z*k where (w,x,y,z) is not
48  // necessarily a unit length vector in 4D.
49 
50  // construction
51  moQuaternion (); // uninitialized
52  moQuaternion (Real fW, Real fX, Real fY, Real fZ);
53  moQuaternion (const moQuaternion& rkQ);
54 
55  // quaternion for the input rotation matrix
56  moQuaternion (const moMatrix3<Real>& rkRot);
57 
58  // quaternion for the rotation of the axis-angle pair
59  moQuaternion (const moVector3<Real>& rkAxis, Real fAngle);
60 
61  // quaternion for the rotation matrix with specified columns
62  moQuaternion (const moVector3<Real> akRotColumn[3]);
63 
64  // member access: 0 = w, 1 = x, 2 = y, 3 = z
65  inline operator const Real* () const { return m_afTuple; }
66  inline operator Real* () { return m_afTuple; }
67  inline Real operator[] (int i) const { return m_afTuple[i]; }
68  inline Real& operator[] (int i) { return m_afTuple[i]; }
69  inline Real W () const { return m_afTuple[0]; }
70  inline Real& W () { return m_afTuple[0]; }
71  inline Real X () const { return m_afTuple[1]; }
72  inline Real& X () { return m_afTuple[1]; }
73  inline Real Y () const { return m_afTuple[2]; }
74  inline Real& Y () { return m_afTuple[2]; }
75  inline Real Z () const { return m_afTuple[3]; }
76  inline Real& Z () { return m_afTuple[3]; }
77 
78  // assignment
79  inline moQuaternion& operator= (const moQuaternion& rkQ)
80  {
81  m_afTuple[0] = rkQ.m_afTuple[0];
82  m_afTuple[1] = rkQ.m_afTuple[1];
83  m_afTuple[2] = rkQ.m_afTuple[2];
84  m_afTuple[3] = rkQ.m_afTuple[3];
85  return *this;
86  }
87 
88  // comparison
89  bool operator== (const moQuaternion& rkQ) const;
90  bool operator!= (const moQuaternion& rkQ) const;
91  bool operator< (const moQuaternion& rkQ) const;
92  bool operator<= (const moQuaternion& rkQ) const;
93  bool operator> (const moQuaternion& rkQ) const;
94  bool operator>= (const moQuaternion& rkQ) const;
95 
96  // arithmetic operations
97  inline moQuaternion operator+ (const moQuaternion& rkQ) const
98  {
99  moQuaternion kSum;
100  for (int i = 0; i < 4; i++) kSum.m_afTuple[i] = m_afTuple[i] + rkQ.m_afTuple[i];
101  return kSum;
102  }
103  inline moQuaternion operator- (const moQuaternion& rkQ) const
104  {
105  moQuaternion kDiff;
106  for (int i = 0; i < 4; i++) kDiff.m_afTuple[i] = m_afTuple[i] - rkQ.m_afTuple[i];
107  return kDiff;
108  }
109  inline moQuaternion operator* (const moQuaternion& rkQ) const
110  {
111  // NOTE: Multiplication is not generally commutative, so in most
112  // cases p*q != q*p.
113 
114  moQuaternion kProd;
115 
116  kProd.m_afTuple[0] =
117  m_afTuple[0]*rkQ.m_afTuple[0] -
118  m_afTuple[1]*rkQ.m_afTuple[1] -
119  m_afTuple[2]*rkQ.m_afTuple[2] -
120  m_afTuple[3]*rkQ.m_afTuple[3];
121 
122  kProd.m_afTuple[1] =
123  m_afTuple[0]*rkQ.m_afTuple[1] +
124  m_afTuple[1]*rkQ.m_afTuple[0] +
125  m_afTuple[2]*rkQ.m_afTuple[3] -
126  m_afTuple[3]*rkQ.m_afTuple[2];
127 
128  kProd.m_afTuple[2] =
129  m_afTuple[0]*rkQ.m_afTuple[2] +
130  m_afTuple[2]*rkQ.m_afTuple[0] +
131  m_afTuple[3]*rkQ.m_afTuple[1] -
132  m_afTuple[1]*rkQ.m_afTuple[3];
133 
134  kProd.m_afTuple[3] =
135  m_afTuple[0]*rkQ.m_afTuple[3] +
136  m_afTuple[3]*rkQ.m_afTuple[0] +
137  m_afTuple[1]*rkQ.m_afTuple[2] -
138  m_afTuple[2]*rkQ.m_afTuple[1];
139 
140  return kProd;
141  }
142  inline moQuaternion operator* (Real fScalar) const
143  {
144  moQuaternion kProd;
145  for (int i = 0; i < 4; i++) kProd.m_afTuple[i] = fScalar*m_afTuple[i];
146  return kProd;
147  }
148  inline moQuaternion operator/ (Real fScalar) const
149  {
150  moQuaternion kQuot;
151  int i;
152 
153  if (fScalar != (Real)0.0)
154  {
155  Real fInvScalar = ((Real)1.0)/fScalar;
156  for (i = 0; i < 4; i++) kQuot.m_afTuple[i] = fInvScalar*m_afTuple[i];
157  }
158  else
159  {
160  for (i = 0; i < 4; i++) kQuot.m_afTuple[i] = moMath<Real>::MAX_REAL;
161  }
162 
163  return kQuot;
164  }
165  inline moQuaternion operator- () const
166  {
167  moQuaternion kNeg;
168  for (int i = 0; i < 4; i++) kNeg.m_afTuple[i] = -m_afTuple[i];
169  return kNeg;
170  }
171 
172  // arithmetic updates
174  {
175  for (int i = 0; i < 4; i++) m_afTuple[i] += rkQ.m_afTuple[i];
176  return *this;
177  }
179  {
180  for (int i = 0; i < 4; i++) m_afTuple[i] -= rkQ.m_afTuple[i];
181  return *this;
182  }
183  inline moQuaternion& operator*= (Real fScalar)
184  {
185  for (int i = 0; i < 4; i++) m_afTuple[i] *= fScalar;
186  return *this;
187  }
188  inline moQuaternion& operator/= (Real fScalar)
189  {
190  int i;
191 
192  if (fScalar != (Real)0.0)
193  {
194  Real fInvScalar = ((Real)1.0)/fScalar;
195  for (i = 0; i < 4; i++) m_afTuple[i] *= fInvScalar;
196  }
197  else
198  {
199  for (i = 0; i < 4; i++) m_afTuple[i] = moMath<Real>::MAX_REAL;
200  }
201 
202  return *this;
203  }
204 
205  // conversion between quaternions, matrices, and axis-angle
206  moQuaternion& FromRotationMatrix (const moMatrix3<Real>& rkRot);
207  void ToRotationMatrix (moMatrix3<Real>& rkRot) const;
208  moQuaternion& FromRotationMatrix (const moVector3<Real> akRotColumn[3]);
209  void ToRotationMatrix (moVector3<Real> akRotColumn[3]) const;
210  moQuaternion& FromAxisAngle (const moVector3<Real>& rkAxis, Real fAngle);
211  void ToAxisAngle (moVector3<Real>& rkAxis, Real& rfAngle) const;
212 
213  // functions of a quaternion
214  inline Real Length () const // length of 4-tuple
215  {
216  return moMath<Real>::Sqrt(
217  m_afTuple[0]*m_afTuple[0] +
218  m_afTuple[1]*m_afTuple[1] +
219  m_afTuple[2]*m_afTuple[2] +
220  m_afTuple[3]*m_afTuple[3]);
221  }
222  inline Real SquaredLength () const // squared length of 4-tuple
223  {
224  return
225  m_afTuple[0]*m_afTuple[0] +
226  m_afTuple[1]*m_afTuple[1] +
227  m_afTuple[2]*m_afTuple[2] +
228  m_afTuple[3]*m_afTuple[3];
229  }
230  inline Real Dot (const moQuaternion& rkQ) const // dot product of 4-tuples
231  {
232  Real fDot = (Real)0.0;
233  for (int i = 0; i < 4; i++) fDot += m_afTuple[i]*rkQ.m_afTuple[i];
234  return fDot;
235  }
236  inline Real Normalize () // make the 4-tuple unit length
237  {
238  Real fLength = Length();
239 
240  if (fLength > moMath<Real>::ZERO_TOLERANCE)
241  {
242  Real fInvLength = ((Real)1.0)/fLength;
243  m_afTuple[0] *= fInvLength;
244  m_afTuple[1] *= fInvLength;
245  m_afTuple[2] *= fInvLength;
246  m_afTuple[3] *= fInvLength;
247  }
248  else
249  {
250  fLength = (Real)0.0;
251  m_afTuple[0] = (Real)0.0;
252  m_afTuple[1] = (Real)0.0;
253  m_afTuple[2] = (Real)0.0;
254  m_afTuple[3] = (Real)0.0;
255  }
256 
257  return fLength;
258  }
259 
260  moQuaternion Inverse () const; // apply to non-zero quaternion
261  moQuaternion Conjugate () const;
262  moQuaternion Exp () const; // apply to quaternion with w = 0
263  moQuaternion Log () const; // apply to unit-length quaternion
264 
265  // rotation of a vector by a quaternion
266  moVector3<Real> Rotate (const moVector3<Real>& rkVector) const;
267 
268  // spherical linear interpolation
269  moQuaternion& Slerp (Real fT, const moQuaternion& rkP, const moQuaternion& rkQ);
270 
271  moQuaternion& SlerpExtraSpins (Real fT, const moQuaternion& rkP,
272  const moQuaternion& rkQ, int iExtraSpins);
273 
274  // intermediate terms for spherical quadratic interpolation
275  moQuaternion& Intermediate (const moQuaternion& rkQ0,
276  const moQuaternion& rkQ1, const moQuaternion& rkQ2);
277 
278  // spherical quadratic interpolation
279  moQuaternion& Squad (Real fT, const moQuaternion& rkQ0,
280  const moQuaternion& rkA0, const moQuaternion& rkA1,
281  const moQuaternion& rkQ1);
282 
283  // Compute a quaternion that rotates unit-length vector V1 to unit-length
284  // vector V2. The rotation is about the axis perpendicular to both V1 and
285  // V2, with angle of that between V1 and V2. If V1 and V2 are parallel,
286  // any axis of rotation will do, such as the permutation (z2,x2,y2), where
287  // V2 = (x2,y2,z2).
288  moQuaternion& Align (const moVector3<Real>& rkV1, const moVector3<Real>& rkV2);
289 
290  // Decompose a quaternion into q = q_twist * q_swing, where q is 'this'
291  // quaternion. If V1 is the input axis and V2 is the rotation of V1 by
292  // q, q_swing represents the rotation about the axis perpendicular to
293  // V1 and V2 (see moQuaternion::Align), and q_twist is a rotation about V1.
294  void DecomposeTwistTimesSwing (const moVector3<Real>& rkV1,
295  moQuaternion& rkTwist, moQuaternion& rkSwing);
296 
297  // Decompose a quaternion into q = q_swing * q_twist, where q is 'this'
298  // quaternion. If V1 is the input axis and V2 is the rotation of V1 by
299  // q, q_swing represents the rotation about the axis perpendicular to
300  // V1 and V2 (see moQuaternion::Align), and q_twist is a rotation about V1.
301  void DecomposeSwingTimesTwist (const moVector3<Real>& rkV1,
302  moQuaternion& rkSwing, moQuaternion& rkTwist);
303 
304  // special values
305  static const moQuaternion IDENTITY;
306  static const moQuaternion ZERO;
307 
308 private:
309  // support for comparisons
310  int CompareArrays (const moQuaternion& rkQ) const;
311 
312  // support for FromRotationMatrix
313  static int ms_iNext[3];
314 
315  Real m_afTuple[4];
316 };
317 
318 template <class Real>
319 inline moQuaternion<Real> operator* (Real fScalar, const moQuaternion<Real>& rkQ)
320 {
321  moQuaternion<Real> kProd;
322  for (int i = 0; i < 4; i++)
323  {
324  kProd[i] = fScalar*rkQ[i];
325  }
326  return kProd;
327 }
328 
329 #ifndef MO_MACOSX
330 #ifndef MO_RASPBIAN
331 #ifndef MO_WIN32
334 #endif
335 #endif
336 #endif
337 
338 typedef moQuaternion<MOfloat> moQuaternionf;
339 typedef moQuaternion<MOdouble> moQuaterniond;
340 
341 #endif
342 
moMatrix3< Real > & FromAxisAngle(const moVector3< Real > &rkAxis, Real fAngle)
Definition: moMathMatrix.h:849
bool operator<=(const moMatrix3 &rkM) const
Definition: moMathMatrix.h:960
Real Y() const
static const moQuaternion IDENTITY
moMatrix3 operator-(const moMatrix3 &rkM) const
moMatrix3 operator/(Real fScalar) const
Real W() const
bool operator>(const moMatrix3 &rkM) const
Definition: moMathMatrix.h:966
void ToAxisAngle(moVector3< Real > &rkAxis, Real &rfAngle) const
moMatrix3< Real > Inverse() const
moQuaternion< MOfloat > moQuaternionf
Clase base abstracta de donde deben derivar los objetos [virtual pura].
Definition: moAbstract.h:191
#define LIBMOLDEO_API
Definition: moTypes.h:180
moMatrix3 & operator-=(const moMatrix3 &rkM)
bool operator==(const moMatrix3 &rkM) const
Definition: moMathMatrix.h:942
Real X() const
static Real Sqrt(Real fValue)
Definition: moMath.h:279
bool operator<(const moMatrix3 &rkM) const
Definition: moMathMatrix.h:954
moMatrix3< Real > & Slerp(Real fT, const moMatrix3 &rkR0, const moMatrix3 &rkR1)
Real SquaredLength() const
Real Length() const
moMatrix3 & operator/=(Real fScalar)
Real Z() const
static const moQuaternion ZERO
bool operator!=(const moMatrix3 &rkM) const
Definition: moMathMatrix.h:948
moMatrix3 & operator*=(Real fScalar)
bool operator>=(const moMatrix3 &rkM) const
Definition: moMathMatrix.h:972
moMatrix3 & operator=(const moMatrix3 &rkM)
Definition: moMath.h:64
Real Dot(const moQuaternion &rkQ) const
moMatrix3 operator+(const moMatrix3 &rkM) const
moQuaternion< MOdouble > moQuaterniond
moMatrix3 & operator+=(const moMatrix3 &rkM)
const Real * operator[](int iRow) const
moQuaternion< Real > operator*(Real fScalar, const moQuaternion< Real > &rkQ)