Rumba C++ SDK
ImathQuat.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
4 // Digital Ltd. LLC
5 //
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
10 // met:
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 // * Neither the name of Industrial Light & Magic nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
34 
35 
36 
37 #ifndef INCLUDED_IMATHQUAT_H
38 #define INCLUDED_IMATHQUAT_H
39 
40 //----------------------------------------------------------------------
41 //
42 // template class Quat<T>
43 //
44 // "Quaternions came from Hamilton ... and have been an unmixed
45 // evil to those who have touched them in any way. Vector is a
46 // useless survival ... and has never been of the slightest use
47 // to any creature."
48 //
49 // - Lord Kelvin
50 //
51 // This class implements the quaternion numerical type -- you
52 // will probably want to use this class to represent orientations
53 // in R3 and to convert between various euler angle reps. You
54 // should probably use Imath::Euler<> for that.
55 //
56 //----------------------------------------------------------------------
57 
58 #include "ImathExc.h"
59 #include "ImathMatrix.h"
60 
61 #include <iostream>
62 
63 namespace Imath {
64 
65 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
66 // Disable MS VC++ warnings about conversion from double to float
67 #pragma warning(disable:4244)
68 #endif
69 
70 template <class T>
71 class Quat
72 {
73  public:
74 
75  T r; // real part
76  Vec3<T> v; // imaginary vector
77 
78 
79  //-----------------------------------------------------
80  // Constructors - default constructor is identity quat
81  //-----------------------------------------------------
82 
83  Quat ();
84 
85  template <class S>
86  Quat (const Quat<S> &q);
87 
88  Quat (T s, T i, T j, T k);
89 
90  Quat (T s, Vec3<T> d);
91 
92  static Quat<T> identity ();
93 
94 
95  //-------------------------------------------------
96  // Basic Algebra - Operators and Methods
97  // The operator return values are *NOT* normalized
98  //
99  // operator^ and euclideanInnnerProduct() both
100  // implement the 4D dot product
101  //
102  // operator/ uses the inverse() quaternion
103  //
104  // operator~ is conjugate -- if (S+V) is quat then
105  // the conjugate (S+V)* == (S-V)
106  //
107  // some operators (*,/,*=,/=) treat the quat as
108  // a 4D vector when one of the operands is scalar
109  //-------------------------------------------------
110 
111  const Quat<T> & operator = (const Quat<T> &q);
112  const Quat<T> & operator *= (const Quat<T> &q);
113  const Quat<T> & operator *= (T t);
114  const Quat<T> & operator /= (const Quat<T> &q);
115  const Quat<T> & operator /= (T t);
116  const Quat<T> & operator += (const Quat<T> &q);
117  const Quat<T> & operator -= (const Quat<T> &q);
118  T & operator [] (int index); // as 4D vector
119  T operator [] (int index) const;
120 
121  template <class S> bool operator == (const Quat<S> &q) const;
122  template <class S> bool operator != (const Quat<S> &q) const;
123 
124  Quat<T> & invert (); // this -> 1 / this
125  Quat<T> inverse () const;
126  Quat<T> & normalize (); // returns this
127  Quat<T> normalized () const;
128  T length () const; // in R4
129  Vec3<T> rotateVector(const Vec3<T> &original) const;
130  T euclideanInnerProduct(const Quat<T> &q) const;
131 
132  //-----------------------
133  // Rotation conversion
134  //-----------------------
135 
136  Quat<T> & setAxisAngle (const Vec3<T> &axis, T radians);
137 
138  Quat<T> & setRotation (const Vec3<T> &fromDirection,
139  const Vec3<T> &toDirection);
140 
141  T angle () const;
142  Vec3<T> axis () const;
143 
144  Matrix33<T> toMatrix33 () const;
145  Matrix44<T> toMatrix44 () const;
146 
147  Quat<T> log () const;
148  Quat<T> exp () const;
149 
150 
151  private:
152 
153  void setRotationInternal (const Vec3<T> &f0,
154  const Vec3<T> &t0,
155  Quat<T> &q);
156 };
157 
158 
159 template<class T>
160 Quat<T> slerp (const Quat<T> &q1, const Quat<T> &q2, T t);
161 
162 template<class T>
164  (const Quat<T> &q1, const Quat<T> &q2, T t);
165 
166 
167 template<class T>
168 Quat<T> squad (const Quat<T> &q1, const Quat<T> &q2,
169  const Quat<T> &qa, const Quat<T> &qb, T t);
170 
171 template<class T>
172 void intermediate (const Quat<T> &q0, const Quat<T> &q1,
173  const Quat<T> &q2, const Quat<T> &q3,
174  Quat<T> &qa, Quat<T> &qb);
175 
176 template<class T>
177 Matrix33<T> operator * (const Matrix33<T> &M, const Quat<T> &q);
178 
179 template<class T>
180 Matrix33<T> operator * (const Quat<T> &q, const Matrix33<T> &M);
181 
182 template<class T>
183 std::ostream & operator << (std::ostream &o, const Quat<T> &q);
184 
185 template<class T>
186 Quat<T> operator * (const Quat<T> &q1, const Quat<T> &q2);
187 
188 template<class T>
189 Quat<T> operator / (const Quat<T> &q1, const Quat<T> &q2);
190 
191 template<class T>
192 Quat<T> operator / (const Quat<T> &q, T t);
193 
194 template<class T>
195 Quat<T> operator * (const Quat<T> &q, T t);
196 
197 template<class T>
198 Quat<T> operator * (T t, const Quat<T> &q);
199 
200 template<class T>
201 Quat<T> operator + (const Quat<T> &q1, const Quat<T> &q2);
202 
203 template<class T>
204 Quat<T> operator - (const Quat<T> &q1, const Quat<T> &q2);
205 
206 template<class T>
207 Quat<T> operator ~ (const Quat<T> &q);
208 
209 template<class T>
210 Quat<T> operator - (const Quat<T> &q);
211 
212 template<class T>
213 Vec3<T> operator * (const Vec3<T> &v, const Quat<T> &q);
214 
215 
216 //--------------------
217 // Convenient typedefs
218 //--------------------
219 
222 
223 
224 //---------------
225 // Implementation
226 //---------------
227 
228 template<class T>
229 inline
230 Quat<T>::Quat (): r (1), v (0, 0, 0)
231 {
232  // empty
233 }
234 
235 
236 template<class T>
237 template <class S>
238 inline
239 Quat<T>::Quat (const Quat<S> &q): r (q.r), v (q.v)
240 {
241  // empty
242 }
243 
244 
245 template<class T>
246 inline
247 Quat<T>::Quat (T s, T i, T j, T k): r (s), v (i, j, k)
248 {
249  // empty
250 }
251 
252 
253 template<class T>
254 inline
255 Quat<T>::Quat (T s, Vec3<T> d): r (s), v (d)
256 {
257  // empty
258 }
259 
260 
261 template<class T>
262 inline Quat<T>
264 {
265  return Quat<T>();
266 }
267 
268 template<class T>
269 inline const Quat<T> &
271 {
272  r = q.r;
273  v = q.v;
274  return *this;
275 }
276 
277 
278 template<class T>
279 inline const Quat<T> &
281 {
282  T rtmp = r * q.r - (v ^ q.v);
283  v = r * q.v + v * q.r + v % q.v;
284  r = rtmp;
285  return *this;
286 }
287 
288 
289 template<class T>
290 inline const Quat<T> &
292 {
293  r *= t;
294  v *= t;
295  return *this;
296 }
297 
298 
299 template<class T>
300 inline const Quat<T> &
302 {
303  *this = *this * q.inverse();
304  return *this;
305 }
306 
307 
308 template<class T>
309 inline const Quat<T> &
311 {
312  r /= t;
313  v /= t;
314  return *this;
315 }
316 
317 
318 template<class T>
319 inline const Quat<T> &
321 {
322  r += q.r;
323  v += q.v;
324  return *this;
325 }
326 
327 
328 template<class T>
329 inline const Quat<T> &
331 {
332  r -= q.r;
333  v -= q.v;
334  return *this;
335 }
336 
337 
338 template<class T>
339 inline T &
341 {
342  return index ? v[index - 1] : r;
343 }
344 
345 
346 template<class T>
347 inline T
348 Quat<T>::operator [] (int index) const
349 {
350  return index ? v[index - 1] : r;
351 }
352 
353 
354 template <class T>
355 template <class S>
356 inline bool
358 {
359  return r == q.r && v == q.v;
360 }
361 
362 
363 template <class T>
364 template <class S>
365 inline bool
367 {
368  return r != q.r || v != q.v;
369 }
370 
371 
372 template<class T>
373 inline T
374 operator ^ (const Quat<T>& q1 ,const Quat<T>& q2)
375 {
376  return q1.r * q2.r + (q1.v ^ q2.v);
377 }
378 
379 
380 template <class T>
381 inline T
383 {
384  return Math<T>::sqrt (r * r + (v ^ v));
385 }
386 
387 
388 template <class T>
389 inline Quat<T> &
391 {
392  if (T l = length())
393  {
394  r /= l;
395  v /= l;
396  }
397  else
398  {
399  r = 1;
400  v = Vec3<T> (0);
401  }
402 
403  return *this;
404 }
405 
406 
407 template <class T>
408 inline Quat<T>
410 {
411  if (T l = length())
412  return Quat (r / l, v / l);
413 
414  return Quat();
415 }
416 
417 
418 template<class T>
419 inline Quat<T>
421 {
422  //
423  // 1 Q*
424  // - = ---- where Q* is conjugate (operator~)
425  // Q Q* Q and (Q* Q) == Q ^ Q (4D dot)
426  //
427 
428  T qdot = *this ^ *this;
429  return Quat (r / qdot, -v / qdot);
430 }
431 
432 
433 template<class T>
434 inline Quat<T> &
436 {
437  T qdot = (*this) ^ (*this);
438  r /= qdot;
439  v = -v / qdot;
440  return *this;
441 }
442 
443 
444 template<class T>
445 inline Vec3<T>
446 Quat<T>::rotateVector(const Vec3<T>& original) const
447 {
448  //
449  // Given a vector p and a quaternion q (aka this),
450  // calculate p' = qpq*
451  //
452  // Assumes unit quaternions (because non-unit
453  // quaternions cannot be used to rotate vectors
454  // anyway).
455  //
456 
457  Quat<T> vec (0, original); // temporarily promote grade of original
458  Quat<T> inv (*this);
459  inv.v *= -1; // unit multiplicative inverse
460  Quat<T> result = *this * vec * inv;
461  return result.v;
462 }
463 
464 
465 template<class T>
466 inline T
468 {
469  return r * q.r + v.x * q.v.x + v.y * q.v.y + v.z * q.v.z;
470 }
471 
472 
473 template<class T>
474 T
475 angle4D (const Quat<T> &q1, const Quat<T> &q2)
476 {
477  //
478  // Compute the angle between two quaternions,
479  // interpreting the quaternions as 4D vectors.
480  //
481 
482  Quat<T> d = q1 - q2;
483  T lengthD = Math<T>::sqrt (d ^ d);
484 
485  Quat<T> s = q1 + q2;
486  T lengthS = Math<T>::sqrt (s ^ s);
487 
488  return 2 * Math<T>::atan2 (lengthD, lengthS);
489 }
490 
491 
492 template<class T>
493 Quat<T>
494 slerp (const Quat<T> &q1, const Quat<T> &q2, T t)
495 {
496  //
497  // Spherical linear interpolation.
498  // Assumes q1 and q2 are normalized and that q1 != -q2.
499  //
500  // This method does *not* interpolate along the shortest
501  // arc between q1 and q2. If you desire interpolation
502  // along the shortest arc, and q1^q2 is negative, then
503  // consider calling slerpShortestArc(), below, or flipping
504  // the second quaternion explicitly.
505  //
506  // The implementation of squad() depends on a slerp()
507  // that interpolates as is, without the automatic
508  // flipping.
509  //
510  // Don Hatch explains the method we use here on his
511  // web page, The Right Way to Calculate Stuff, at
512  // http://www.plunk.org/~hatch/rightway.php
513  //
514 
515  T a = angle4D (q1, q2);
516  T s = 1 - t;
517 
518  Quat<T> q = sinx_over_x (s * a) / sinx_over_x (a) * s * q1 +
519  sinx_over_x (t * a) / sinx_over_x (a) * t * q2;
520 
521  return q.normalized();
522 }
523 
524 
525 template<class T>
526 Quat<T>
527 slerpShortestArc (const Quat<T> &q1, const Quat<T> &q2, T t)
528 {
529  //
530  // Spherical linear interpolation along the shortest
531  // arc from q1 to either q2 or -q2, whichever is closer.
532  // Assumes q1 and q2 are unit quaternions.
533  //
534 
535  if ((q1 ^ q2) >= 0)
536  return slerp (q1, q2, t);
537  else
538  return slerp (q1, -q2, t);
539 }
540 
541 
542 template<class T>
543 Quat<T>
544 spline (const Quat<T> &q0, const Quat<T> &q1,
545  const Quat<T> &q2, const Quat<T> &q3,
546  T t)
547 {
548  //
549  // Spherical Cubic Spline Interpolation -
550  // from Advanced Animation and Rendering
551  // Techniques by Watt and Watt, Page 366:
552  // A spherical curve is constructed using three
553  // spherical linear interpolations of a quadrangle
554  // of unit quaternions: q1, qa, qb, q2.
555  // Given a set of quaternion keys: q0, q1, q2, q3,
556  // this routine does the interpolation between
557  // q1 and q2 by constructing two intermediate
558  // quaternions: qa and qb. The qa and qb are
559  // computed by the intermediate function to
560  // guarantee the continuity of tangents across
561  // adjacent cubic segments. The qa represents in-tangent
562  // for q1 and the qb represents the out-tangent for q2.
563  //
564  // The q1 q2 is the cubic segment being interpolated.
565  // The q0 is from the previous adjacent segment and q3 is
566  // from the next adjacent segment. The q0 and q3 are used
567  // in computing qa and qb.
568  //
569 
570  Quat<T> qa = intermediate (q0, q1, q2);
571  Quat<T> qb = intermediate (q1, q2, q3);
572  Quat<T> result = squad (q1, qa, qb, q2, t);
573 
574  return result;
575 }
576 
577 
578 template<class T>
579 Quat<T>
580 squad (const Quat<T> &q1, const Quat<T> &qa,
581  const Quat<T> &qb, const Quat<T> &q2,
582  T t)
583 {
584  //
585  // Spherical Quadrangle Interpolation -
586  // from Advanced Animation and Rendering
587  // Techniques by Watt and Watt, Page 366:
588  // It constructs a spherical cubic interpolation as
589  // a series of three spherical linear interpolations
590  // of a quadrangle of unit quaternions.
591  //
592 
593  Quat<T> r1 = slerp (q1, q2, t);
594  Quat<T> r2 = slerp (qa, qb, t);
595  Quat<T> result = slerp (r1, r2, 2 * t * (1 - t));
596 
597  return result;
598 }
599 
600 
601 template<class T>
602 Quat<T>
603 intermediate (const Quat<T> &q0, const Quat<T> &q1, const Quat<T> &q2)
604 {
605  //
606  // From advanced Animation and Rendering
607  // Techniques by Watt and Watt, Page 366:
608  // computing the inner quadrangle
609  // points (qa and qb) to guarantee tangent
610  // continuity.
611  //
612 
613  Quat<T> q1inv = q1.inverse();
614  Quat<T> c1 = q1inv * q2;
615  Quat<T> c2 = q1inv * q0;
616  Quat<T> c3 = (T) (-0.25) * (c2.log() + c1.log());
617  Quat<T> qa = q1 * c3.exp();
618  qa.normalize();
619  return qa;
620 }
621 
622 
623 template <class T>
624 inline Quat<T>
625 Quat<T>::log () const
626 {
627  //
628  // For unit quaternion, from Advanced Animation and
629  // Rendering Techniques by Watt and Watt, Page 366:
630  //
631 
632  T theta = Math<T>::acos (std::min (r, (T) 1.0));
633 
634  if (theta == 0)
635  return Quat<T> (0, v);
636 
637  T sintheta = Math<T>::sin (theta);
638 
639  T k;
640  if (abs (sintheta) < 1 && abs (theta) >= limits<T>::max() * abs (sintheta))
641  k = 1;
642  else
643  k = theta / sintheta;
644 
645  return Quat<T> ((T) 0, v.x * k, v.y * k, v.z * k);
646 }
647 
648 
649 template <class T>
650 inline Quat<T>
651 Quat<T>::exp () const
652 {
653  //
654  // For pure quaternion (zero scalar part):
655  // from Advanced Animation and Rendering
656  // Techniques by Watt and Watt, Page 366:
657  //
658 
659  T theta = v.length();
660  T sintheta = Math<T>::sin (theta);
661 
662  T k;
663  if (abs (theta) < 1 && abs (sintheta) >= limits<T>::max() * abs (theta))
664  k = 1;
665  else
666  k = sintheta / theta;
667 
668  T costheta = Math<T>::cos (theta);
669 
670  return Quat<T> (costheta, v.x * k, v.y * k, v.z * k);
671 }
672 
673 
674 template <class T>
675 inline T
677 {
678  return 2 * Math<T>::atan2 (v.length(), r);
679 }
680 
681 
682 template <class T>
683 inline Vec3<T>
685 {
686  return v.normalized();
687 }
688 
689 
690 template <class T>
691 inline Quat<T> &
692 Quat<T>::setAxisAngle (const Vec3<T> &axis, T radians)
693 {
694  r = Math<T>::cos (radians / 2);
695  v = axis.normalized() * Math<T>::sin (radians / 2);
696  return *this;
697 }
698 
699 
700 template <class T>
701 Quat<T> &
702 Quat<T>::setRotation (const Vec3<T> &from, const Vec3<T> &to)
703 {
704  //
705  // Create a quaternion that rotates vector from into vector to,
706  // such that the rotation is around an axis that is the cross
707  // product of from and to.
708  //
709  // This function calls function setRotationInternal(), which is
710  // numerically accurate only for rotation angles that are not much
711  // greater than pi/2. In order to achieve good accuracy for angles
712  // greater than pi/2, we split large angles in half, and rotate in
713  // two steps.
714  //
715 
716  //
717  // Normalize from and to, yielding f0 and t0.
718  //
719 
720  Vec3<T> f0 = from.normalized();
721  Vec3<T> t0 = to.normalized();
722 
723  if ((f0 ^ t0) >= 0)
724  {
725  //
726  // The rotation angle is less than or equal to pi/2.
727  //
728 
729  setRotationInternal (f0, t0, *this);
730  }
731  else
732  {
733  //
734  // The angle is greater than pi/2. After computing h0,
735  // which is halfway between f0 and t0, we rotate first
736  // from f0 to h0, then from h0 to t0.
737  //
738 
739  Vec3<T> h0 = (f0 + t0).normalized();
740 
741  if ((h0 ^ h0) != 0)
742  {
743  setRotationInternal (f0, h0, *this);
744 
745  Quat<T> q;
746  setRotationInternal (h0, t0, q);
747 
748  *this *= q;
749  }
750  else
751  {
752  //
753  // f0 and t0 point in exactly opposite directions.
754  // Pick an arbitrary axis that is orthogonal to f0,
755  // and rotate by pi.
756  //
757 
758  r = T (0);
759 
760  Vec3<T> f02 = f0 * f0;
761 
762  if (f02.x <= f02.y && f02.x <= f02.z)
763  v = (f0 % Vec3<T> (1, 0, 0)).normalized();
764  else if (f02.y <= f02.z)
765  v = (f0 % Vec3<T> (0, 1, 0)).normalized();
766  else
767  v = (f0 % Vec3<T> (0, 0, 1)).normalized();
768  }
769  }
770 
771  return *this;
772 }
773 
774 
775 template <class T>
776 void
777 Quat<T>::setRotationInternal (const Vec3<T> &f0, const Vec3<T> &t0, Quat<T> &q)
778 {
779  //
780  // The following is equivalent to setAxisAngle(n,2*phi),
781  // where the rotation axis, n, is orthogonal to the f0 and
782  // t0 vectors, and 2*phi is the angle between f0 and t0.
783  //
784  // This function is called by setRotation(), above; it assumes
785  // that f0 and t0 are normalized and that the angle between
786  // them is not much greater than pi/2. This function becomes
787  // numerically inaccurate if f0 and t0 point into nearly
788  // opposite directions.
789  //
790 
791  //
792  // Find a normalized vector, h0, that is halfway between f0 and t0.
793  // The angle between f0 and h0 is phi.
794  //
795 
796  Vec3<T> h0 = (f0 + t0).normalized();
797 
798  //
799  // Store the rotation axis and rotation angle.
800  //
801 
802  q.r = f0 ^ h0; // f0 ^ h0 == cos (phi)
803  q.v = f0 % h0; // (f0 % h0).length() == sin (phi)
804 }
805 
806 
807 template<class T>
808 Matrix33<T>
810 {
811  return Matrix33<T> (1 - 2 * (v.y * v.y + v.z * v.z),
812  2 * (v.x * v.y + v.z * r),
813  2 * (v.z * v.x - v.y * r),
814 
815  2 * (v.x * v.y - v.z * r),
816  1 - 2 * (v.z * v.z + v.x * v.x),
817  2 * (v.y * v.z + v.x * r),
818 
819  2 * (v.z * v.x + v.y * r),
820  2 * (v.y * v.z - v.x * r),
821  1 - 2 * (v.y * v.y + v.x * v.x));
822 }
823 
824 template<class T>
827 {
828  return Matrix44<T> (1 - 2 * (v.y * v.y + v.z * v.z),
829  2 * (v.x * v.y + v.z * r),
830  2 * (v.z * v.x - v.y * r),
831  0,
832  2 * (v.x * v.y - v.z * r),
833  1 - 2 * (v.z * v.z + v.x * v.x),
834  2 * (v.y * v.z + v.x * r),
835  0,
836  2 * (v.z * v.x + v.y * r),
837  2 * (v.y * v.z - v.x * r),
838  1 - 2 * (v.y * v.y + v.x * v.x),
839  0,
840  0,
841  0,
842  0,
843  1);
844 }
845 
846 
847 template<class T>
848 inline Matrix33<T>
849 operator * (const Matrix33<T> &M, const Quat<T> &q)
850 {
851  return M * q.toMatrix33();
852 }
853 
854 
855 template<class T>
856 inline Matrix33<T>
857 operator * (const Quat<T> &q, const Matrix33<T> &M)
858 {
859  return q.toMatrix33() * M;
860 }
861 
862 
863 template<class T>
864 std::ostream &
865 operator << (std::ostream &o, const Quat<T> &q)
866 {
867  return o << "(" << q.r
868  << " " << q.v.x
869  << " " << q.v.y
870  << " " << q.v.z
871  << ")";
872 }
873 
874 
875 template<class T>
876 inline Quat<T>
877 operator * (const Quat<T> &q1, const Quat<T> &q2)
878 {
879  return Quat<T> (q1.r * q2.r - (q1.v ^ q2.v),
880  q1.r * q2.v + q1.v * q2.r + q1.v % q2.v);
881 }
882 
883 
884 template<class T>
885 inline Quat<T>
886 operator / (const Quat<T> &q1, const Quat<T> &q2)
887 {
888  return q1 * q2.inverse();
889 }
890 
891 
892 template<class T>
893 inline Quat<T>
894 operator / (const Quat<T> &q, T t)
895 {
896  return Quat<T> (q.r / t, q.v / t);
897 }
898 
899 
900 template<class T>
901 inline Quat<T>
902 operator * (const Quat<T> &q, T t)
903 {
904  return Quat<T> (q.r * t, q.v * t);
905 }
906 
907 
908 template<class T>
909 inline Quat<T>
910 operator * (T t, const Quat<T> &q)
911 {
912  return Quat<T> (q.r * t, q.v * t);
913 }
914 
915 
916 template<class T>
917 inline Quat<T>
918 operator + (const Quat<T> &q1, const Quat<T> &q2)
919 {
920  return Quat<T> (q1.r + q2.r, q1.v + q2.v);
921 }
922 
923 
924 template<class T>
925 inline Quat<T>
926 operator - (const Quat<T> &q1, const Quat<T> &q2)
927 {
928  return Quat<T> (q1.r - q2.r, q1.v - q2.v);
929 }
930 
931 
932 template<class T>
933 inline Quat<T>
935 {
936  return Quat<T> (q.r, -q.v);
937 }
938 
939 
940 template<class T>
941 inline Quat<T>
943 {
944  return Quat<T> (-q.r, -q.v);
945 }
946 
947 
948 template<class T>
949 inline Vec3<T>
950 operator * (const Vec3<T> &v, const Quat<T> &q)
951 {
952  Vec3<T> a = q.v % v;
953  Vec3<T> b = q.v % a;
954  return v + T (2) * (q.r * a + b);
955 }
956 
957 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
958 #pragma warning(default:4244)
959 #endif
960 
961 } // namespace Imath
962 
963 #endif
Quat< float > Quatf
Definition: ImathQuat.h:220
Vec3< T > v
Definition: ImathQuat.h:76
Quat< T > & setAxisAngle(const Vec3< T > &axis, T radians)
Definition: ImathQuat.h:692
Quat()
Definition: ImathQuat.h:230
Quat< T > log() const
Definition: ImathQuat.h:625
T length() const
Definition: ImathQuat.h:382
Quat< T > squad(const Quat< T > &q1, const Quat< T > &q2, const Quat< T > &qa, const Quat< T > &qb, T t)
Definition: ImathQuat.h:580
Definition: ImathFrame.h:42
static Quat< T > identity()
Definition: ImathQuat.h:263
Definition: ImathFrame.h:43
Quat< T > operator/(const Quat< T > &q1, const Quat< T > &q2)
Definition: ImathQuat.h:886
T sinx_over_x(T x)
Definition: ImathMath.h:161
Plane3< T > operator-(const Plane3< T > &plane)
Definition: ImathPlane.h:248
static T atan2(T x, T y)
Definition: ImathMath.h:96
Quat< T > normalized() const
Definition: ImathQuat.h:409
Quat< T > operator+(const Quat< T > &q1, const Quat< T > &q2)
Definition: ImathQuat.h:918
Quat< T > spline(const Quat< T > &q0, const Quat< T > &q1, const Quat< T > &q2, const Quat< T > &q3, T t)
Definition: ImathQuat.h:544
bool operator==(const Quat< S > &q) const
Definition: ImathQuat.h:357
Quat< T > & setRotation(const Vec3< T > &fromDirection, const Vec3< T > &toDirection)
Definition: ImathQuat.h:702
const Quat< T > & operator+=(const Quat< T > &q)
Definition: ImathQuat.h:320
Quat< T > operator~(const Quat< T > &q)
Definition: ImathQuat.h:934
T abs(T a)
Definition: ImathFun.h:53
T operator^(const Quat< T > &q1, const Quat< T > &q2)
Definition: ImathQuat.h:374
Definition: ImathMatrix.h:66
Quat< T > slerp(const Quat< T > &q1, const Quat< T > &q2, T t)
Definition: ImathQuat.h:494
const Quat< T > & operator/=(const Quat< T > &q)
Definition: ImathQuat.h:301
Definition: ImathLimits.h:117
static T acos(T x)
Definition: ImathMath.h:93
Vec3< T > rotateVector(const Vec3< T > &original) const
Definition: ImathQuat.h:446
T x
Definition: ImathVec.h:274
T y
Definition: ImathVec.h:274
void intermediate(const Quat< T > &q0, const Quat< T > &q1, const Quat< T > &q2, const Quat< T > &q3, Quat< T > &qa, Quat< T > &qb)
const Quat< T > & operator-=(const Quat< T > &q)
Definition: ImathQuat.h:330
Quat< T > exp() const
Definition: ImathQuat.h:651
static T cos(T x)
Definition: ImathMath.h:97
Matrix44< T > toMatrix44() const
Definition: ImathQuat.h:826
T & operator[](int index)
Definition: ImathQuat.h:340
Quat< T > & normalize()
Definition: ImathQuat.h:390
Definition: ImathQuat.h:71
Vec3< T > axis() const
Definition: ImathQuat.h:684
T z
Definition: ImathVec.h:274
const Quat< T > & operator*=(const Quat< T > &q)
Definition: ImathQuat.h:280
T r
Definition: ImathQuat.h:75
Quat< T > slerpShortestArc(const Quat< T > &q1, const Quat< T > &q2, T t)
Definition: ImathQuat.h:527
Vec3< T > normalized() const
Definition: ImathVec.h:1730
Quat< T > inverse() const
Definition: ImathQuat.h:420
Quat< double > Quatd
Definition: ImathQuat.h:221
const Quat< T > & operator=(const Quat< T > &q)
Definition: ImathQuat.h:270
T angle4D(const Quat< T > &q1, const Quat< T > &q2)
Definition: ImathQuat.h:475
T euclideanInnerProduct(const Quat< T > &q) const
Definition: ImathQuat.h:467
Definition: ImathBox.h:67
T angle() const
Definition: ImathQuat.h:676
Color4< T > operator*(S a, const Color4< T > &v)
Definition: ImathColor.h:727
static T sin(T x)
Definition: ImathMath.h:98
static T sqrt(T x)
Definition: ImathMath.h:114
Matrix33< T > toMatrix33() const
Definition: ImathQuat.h:809
Quat< T > & invert()
Definition: ImathQuat.h:435
bool operator!=(const Quat< S > &q) const
Definition: ImathQuat.h:366