libmoldeo (Moldeo 1.0 Core)  1.0
libmoldeo es el conjunto de objetos y funciones, que permiten ejecutar las operaciones básicas de la plataforma Moldeo, y que compone su núcleo.
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Amigas 'defines' Grupos Páginas
moMathQuaternion.h
Ir a la documentación de este archivo.
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)
moTypes MOint moText moParamIndex moParamReference int iRow int int i int i
Definition: all_f.js:18
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)
moPort const
Definition: all_14.js:19
const Real * operator[](int iRow) const
moQuaternion< Real > operator*(Real fScalar, const moQuaternion< Real > &rkQ)