GteQuaternion.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #pragma once
9 
10 #include <Mathematics/GteVector4.h>
11 #include <Mathematics/GteMatrix.h>
13 
14 namespace gte
15 {
16 
17 template <typename Real>
18 class Quaternion : public Vector<4,Real>
19 {
20 public:
21  // The quaternions are of the form q = x*i + y*j + z*k + w. In tuple
22  // form, q = (x,y,z,w).
23 
24  // Construction. The default constructor does not initialize the members.
25  Quaternion();
26  Quaternion(Quaternion const& q);
27  Quaternion(Vector<4,Real> const& q);
28  Quaternion(Real x, Real y, Real z, Real w);
29 
30  // Assignment.
31  Quaternion& operator=(Quaternion const& q);
33 
34  // Special quaternions.
35  static Quaternion Zero(); // z = 0*i + 0*j + 0*k + 0
36  static Quaternion I(); // i = 1*i + 0*j + 0*k + 0
37  static Quaternion J(); // j = 0*i + 1*j + 0*k + 0
38  static Quaternion K(); // k = 0*i + 0*j + 1*k + 0
39  static Quaternion Identity(); // 1 = 0*i + 0*j + 0*k + 1
40 };
41 
42 // Multiplication of quaternions. This operation is not generally
43 // commutative; that is, q0*q1 and q1*q0 are not usually the same value.
44 // (x0*i + y0*j + z0*k + w0)*(x1*i + y1*j + z1*k + w1)
45 // =
46 // i*(+x0*w1 + y0*z1 - z0*y1 + w0*x1) +
47 // j*(-x0*z1 + y0*w1 + z0*x1 + w0*y1) +
48 // k*(+x0*y1 - y0*x1 + z0*w1 + w0*z1) +
49 // 1*(-x0*x1 - y0*y1 - z0*z1 + w0*w1)
50 template <typename Real>
52  Quaternion<Real> const& q1);
53 
54 // For a nonzero quaternion q = (x,y,z,w), inv(q) = (-x,-y,-z,w)/|q|^2, where
55 // |q| is the length of the quaternion. When q is zero, the function returns
56 // zero, which is considered to be an improbable case.
57 template <typename Real>
59 
60 // The conjugate of q = (x,y,z,w) is conj(q) = (-x,-y,-z,w).
61 template <typename Real>
63 
64 // Rotate a vector using quaternion multiplication. The input quaternion must
65 // be unit length.
66 template <typename Real>
68 
69 // The spherical linear interpolation (slerp) of unit-length quaternions
70 // q0 and q1 for t in [0,1] is
71 // slerp(t,q0,q1) = [sin(t*theta)*q0 + sin((1-t)*theta)*q1]/sin(theta)
72 // where theta is the angle between q0 and q1 [cos(theta) = Dot(q0,q1)].
73 // This function is a parameterization of the great spherical arc between
74 // q0 and q1 on the unit hypersphere. Moreover, the parameterization is
75 // one of normalized arclength--a particle traveling along the arc through
76 // time t does so with constant speed.
77 //
78 // When using slerp in animations involving sequences of quaternions, it is
79 // typical that the quaternions are preprocessed so that consecutive ones
80 // form an acute angle A in [0,pi/2]. Other preprocessing can help with
81 // performance. See the function comments below.
82 //
83 // See GteSlerpEstimate.{h,inl} for various approximations, including
84 // SLERP<Real>::EstimateRPH that gives good performance and accurate results
85 // for preprocessed quaternions.
86 
87 // The angle between q0 and q1 is in [0,pi). There are no angle restrictions
88 // restrictions and nothing is precomputed.
89 template <typename Real>
91  Quaternion<Real> const& q1);
92 
93 // The angle between q0 and q1 must be in [0,pi/2]. The suffix R is for
94 // 'Restricted'. The preprocessing code is
95 // Quaternion<Real> q[n]; // assuming initialized
96 // for (i0 = 0, i1 = 1; i1 < n; i0 = i1++)
97 // {
98 // cosA = Dot(q[i0], q[i1]);
99 // if (cosA < 0)
100 // {
101 // q[i1] = -q[i1]; // now Dot(q[i0], q[i]1) >= 0
102 // }
103 // }
104 template <typename Real>
105 Quaternion<Real> SlerpR(Real t, Quaternion<Real> const& q0,
106  Quaternion<Real> const& q1);
107 
108 // The angle between q0 and q1 must be in [0,pi/2]. The suffix R is for
109 // 'Restricted' and the suffix P is for 'Preprocessed'. The preprocessing
110 // code is
111 // Quaternion<Real> q[n]; // assuming initialized
112 // Real cosA[n-1], omcosA[n-1]; // to be precomputed
113 // for (i0 = 0, i1 = 1; i1 < n; i0 = i1++)
114 // {
115 // cs = Dot(q[i0], q[i1]);
116 // if (cosA[i0] < 0)
117 // {
118 // q[i1] = -q[i1];
119 // cs = -cs;
120 // }
121 // cosA[n-1] = cs; // for GeneralRP
122 // omcosA[i0] = 1 - cs; // for EstimateRP
123 // }
124 template <typename Real>
125 Quaternion<Real> SlerpRP(Real t, Quaternion<Real> const& q0,
126  Quaternion<Real> const& q1, Real cosA);
127 
128 
129 template <typename Real>
131 {
132  // Uninitialized.
133 }
134 
135 template <typename Real>
137 {
138  this->mTuple[0] = q[0];
139  this->mTuple[1] = q[1];
140  this->mTuple[2] = q[2];
141  this->mTuple[3] = q[3];
142 }
143 
144 template <typename Real>
146 {
147  this->mTuple[0] = q[0];
148  this->mTuple[1] = q[1];
149  this->mTuple[2] = q[2];
150  this->mTuple[3] = q[3];
151 }
152 
153 template <typename Real>
154 Quaternion<Real>::Quaternion(Real x, Real y, Real z, Real w)
155 {
156  this->mTuple[0] = x;
157  this->mTuple[1] = y;
158  this->mTuple[2] = z;
159  this->mTuple[3] = w;
160 }
161 
162 template <typename Real>
164 {
166  return *this;
167 }
168 
169 template <typename Real>
171 {
173  return *this;
174 }
175 
176 template <typename Real>
178 {
179  return Quaternion((Real)0, (Real)0, (Real)0, (Real)0);
180 }
181 
182 template <typename Real>
184 {
185  return Quaternion((Real)1, (Real)0, (Real)0, (Real)0);
186 }
187 
188 template <typename Real>
190 {
191  return Quaternion((Real)0, (Real)1, (Real)0, (Real)0);
192 }
193 
194 template <typename Real>
196 {
197  return Quaternion((Real)0, (Real)0, (Real)1, (Real)0);
198 }
199 
200 template <typename Real>
202 {
203  return Quaternion((Real)0, (Real)0, (Real)0, (Real)1);
204 }
205 
206 template <typename Real>
208  Quaternion<Real> const& q1)
209 {
210  // (x0*i + y0*j + z0*k + w0)*(x1*i + y1*j + z1*k + w1)
211  // =
212  // i*(+x0*w1 + y0*z1 - z0*y1 + w0*x1) +
213  // j*(-x0*z1 + y0*w1 + z0*x1 + w0*y1) +
214  // k*(+x0*y1 - y0*x1 + z0*w1 + w0*z1) +
215  // 1*(-x0*x1 - y0*y1 - z0*z1 + w0*w1)
216 
217  return Quaternion<Real>
218  (
219  +q0[0] * q1[3] + q0[1] * q1[2] - q0[2] * q1[1] + q0[3] * q1[0],
220  -q0[0] * q1[2] + q0[1] * q1[3] + q0[2] * q1[0] + q0[3] * q1[1],
221  +q0[0] * q1[1] - q0[1] * q1[0] + q0[2] * q1[3] + q0[3] * q1[2],
222  -q0[0] * q1[0] - q0[1] * q1[1] - q0[2] * q1[2] + q0[3] * q1[3]
223  );
224 }
225 
226 template <typename Real>
228 {
229  Real sqrLen = Dot(q, q);
230  if (sqrLen > (Real)0)
231  {
232  Real invSqrLen = ((Real)1) / sqrLen;
233  Quaternion<Real> inverse = Conjugate(q)*invSqrLen;
234  return inverse;
235  }
236  else
237  {
238  return Quaternion<Real>::Zero();
239  }
240 }
241 
242 template <typename Real>
244 {
245  return Quaternion<Real>(-q[0], -q[1], -q[2], +q[3]);
246 }
247 
248 template <typename Real>
250 {
252 
253  // Zero-out the w-component in remove numerical round-off error.
254  u[3] = (Real)0;
255  return u;
256 }
257 
258 template <typename Real>
260  Quaternion<Real> const& q1)
261 {
262  Real cosA = Dot(q0, q1);
263  Real sign;
264  if (cosA >= (Real)0)
265  {
266  sign = (Real)1;
267  }
268  else
269  {
270  cosA = -cosA;
271  sign = (Real)-1;
272  }
273 
274  Real f0, f1;
275  ChebyshevRatio<Real>::Get(t, cosA, f0, f1);
276  return q0 * f0 + q1 * (sign * f1);
277 }
278 
279 template <typename Real>
281  Quaternion<Real> const& q1)
282 {
283  Real f0, f1;
284  ChebyshevRatio<Real>::Get(t, Dot(q0, q1), f0, f1);
285  return q0 * f0 + q1 * f1;
286 }
287 
288 template <typename Real>
290  Quaternion<Real> const& q1, Real cosA)
291 {
292  Real f0, f1;
293  ChebyshevRatio<Real>::Get(t, cosA, f0, f1);
294  return q0 * f0 + q1 * f1;
295 }
296 
297 
298 }
static Quaternion Zero()
static Quaternion J()
static Quaternion K()
DualQuaternion< Real > Conjugate(DualQuaternion< Real > const &d)
Quaternion< Real > Slerp(Real t, Quaternion< Real > const &q0, Quaternion< Real > const &q1)
static void Get(Real t, Real cosA, Real &f0, Real &f1)
GLint GLenum GLint x
Definition: glcorearb.h:404
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:852
Quaternion< Real > SlerpR(Real t, Quaternion< Real > const &q0, Quaternion< Real > const &q1)
Vector< 4, Real > Rotate(Quaternion< Real > const &q, Vector< 4, Real > const &v)
std::array< Real, N > mTuple
Definition: GteVector.h:69
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
GLdouble GLdouble t
Definition: glext.h:239
static Quaternion I()
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:843
const GLdouble * v
Definition: glcorearb.h:832
static Quaternion Identity()
GLdouble GLdouble GLdouble GLdouble q
Definition: glext.h:255
Quaternion< Real > Inverse(Quaternion< Real > const &d)
Quaternion< Real > SlerpRP(Real t, Quaternion< Real > const &q0, Quaternion< Real > const &q1, Real cosA)
Vector4< float > operator*(Transform const &M, Vector4< float > const &V)
GLint y
Definition: glcorearb.h:98
Quaternion & operator=(Quaternion const &q)


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:01