Home | History | Annotate | Download | only in Imath
      1 ///////////////////////////////////////////////////////////////////////////
      2 //
      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 //
     33 ///////////////////////////////////////////////////////////////////////////
     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>
    163 Quat<T>			slerpShortestArc
    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 
    220 typedef Quat<float>	Quatf;
    221 typedef Quat<double>	Quatd;
    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>
    263 Quat<T>::identity ()
    264 {
    265     return Quat<T>();
    266 }
    267 
    268 template<class T>
    269 inline const Quat<T> &
    270 Quat<T>::operator = (const Quat<T> &q)
    271 {
    272     r = q.r;
    273     v = q.v;
    274     return *this;
    275 }
    276 
    277 
    278 template<class T>
    279 inline const Quat<T> &
    280 Quat<T>::operator *= (const Quat<T> &q)
    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> &
    291 Quat<T>::operator *= (T t)
    292 {
    293     r *= t;
    294     v *= t;
    295     return *this;
    296 }
    297 
    298 
    299 template<class T>
    300 inline const Quat<T> &
    301 Quat<T>::operator /= (const Quat<T> &q)
    302 {
    303     *this = *this * q.inverse();
    304     return *this;
    305 }
    306 
    307 
    308 template<class T>
    309 inline const Quat<T> &
    310 Quat<T>::operator /= (T t)
    311 {
    312     r /= t;
    313     v /= t;
    314     return *this;
    315 }
    316 
    317 
    318 template<class T>
    319 inline const Quat<T> &
    320 Quat<T>::operator += (const Quat<T> &q)
    321 {
    322     r += q.r;
    323     v += q.v;
    324     return *this;
    325 }
    326 
    327 
    328 template<class T>
    329 inline const Quat<T> &
    330 Quat<T>::operator -= (const Quat<T> &q)
    331 {
    332     r -= q.r;
    333     v -= q.v;
    334     return *this;
    335 }
    336 
    337 
    338 template<class T>
    339 inline T &
    340 Quat<T>::operator [] (int index)
    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
    357 Quat<T>::operator == (const Quat<S> &q) const
    358 {
    359     return r == q.r && v == q.v;
    360 }
    361 
    362 
    363 template <class T>
    364 template <class S>
    365 inline bool
    366 Quat<T>::operator != (const Quat<S> &q) const
    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
    382 Quat<T>::length () const
    383 {
    384     return Math<T>::sqrt (r * r + (v ^ v));
    385 }
    386 
    387 
    388 template <class T>
    389 inline Quat<T> &
    390 Quat<T>::normalize ()
    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>
    409 Quat<T>::normalized () const
    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>
    420 Quat<T>::inverse () const
    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> &
    435 Quat<T>::invert ()
    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
    467 Quat<T>::euclideanInnerProduct (const Quat<T> &q) const
    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
    676 Quat<T>::angle () const
    677 {
    678     return 2 * Math<T>::atan2 (v.length(), r);
    679 }
    680 
    681 
    682 template <class T>
    683 inline Vec3<T>
    684 Quat<T>::axis () const
    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>
    809 Quat<T>::toMatrix33() const
    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>
    825 Matrix44<T>
    826 Quat<T>::toMatrix44() const
    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>
    934 operator ~ (const Quat<T> &q)
    935 {
    936     return Quat<T> (q.r, -q.v);
    937 }
    938 
    939 
    940 template<class T>
    941 inline Quat<T>
    942 operator - (const Quat<T> &q)
    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
    964