ImathQuat.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965
  1. ///////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2002-2012, 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. #ifndef INCLUDED_IMATHQUAT_H
  35. #define INCLUDED_IMATHQUAT_H
  36. //----------------------------------------------------------------------
  37. //
  38. // template class Quat<T>
  39. //
  40. // "Quaternions came from Hamilton ... and have been an unmixed
  41. // evil to those who have touched them in any way. Vector is a
  42. // useless survival ... and has never been of the slightest use
  43. // to any creature."
  44. //
  45. // - Lord Kelvin
  46. //
  47. // This class implements the quaternion numerical type -- you
  48. // will probably want to use this class to represent orientations
  49. // in R3 and to convert between various euler angle reps. You
  50. // should probably use Imath::Euler<> for that.
  51. //
  52. //----------------------------------------------------------------------
  53. #include "ImathExc.h"
  54. #include "ImathMatrix.h"
  55. #include "ImathNamespace.h"
  56. #include <iostream>
  57. #include <algorithm>
  58. IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
  59. #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
  60. // Disable MS VC++ warnings about conversion from double to float
  61. #pragma warning(disable:4244)
  62. #endif
  63. template <class T>
  64. class Quat
  65. {
  66. public:
  67. T r; // real part
  68. Vec3<T> v; // imaginary vector
  69. //-----------------------------------------------------
  70. // Constructors - default constructor is identity quat
  71. //-----------------------------------------------------
  72. Quat ();
  73. template <class S>
  74. Quat (const Quat<S> &q);
  75. Quat (T s, T i, T j, T k);
  76. Quat (T s, Vec3<T> d);
  77. static Quat<T> identity ();
  78. //-------------------------------------------------
  79. // Basic Algebra - Operators and Methods
  80. // The operator return values are *NOT* normalized
  81. //
  82. // operator^ and euclideanInnnerProduct() both
  83. // implement the 4D dot product
  84. //
  85. // operator/ uses the inverse() quaternion
  86. //
  87. // operator~ is conjugate -- if (S+V) is quat then
  88. // the conjugate (S+V)* == (S-V)
  89. //
  90. // some operators (*,/,*=,/=) treat the quat as
  91. // a 4D vector when one of the operands is scalar
  92. //-------------------------------------------------
  93. const Quat<T> & operator = (const Quat<T> &q);
  94. const Quat<T> & operator *= (const Quat<T> &q);
  95. const Quat<T> & operator *= (T t);
  96. const Quat<T> & operator /= (const Quat<T> &q);
  97. const Quat<T> & operator /= (T t);
  98. const Quat<T> & operator += (const Quat<T> &q);
  99. const Quat<T> & operator -= (const Quat<T> &q);
  100. T & operator [] (int index); // as 4D vector
  101. T operator [] (int index) const;
  102. template <class S> bool operator == (const Quat<S> &q) const;
  103. template <class S> bool operator != (const Quat<S> &q) const;
  104. Quat<T> & invert (); // this -> 1 / this
  105. Quat<T> inverse () const;
  106. Quat<T> & normalize (); // returns this
  107. Quat<T> normalized () const;
  108. T length () const; // in R4
  109. Vec3<T> rotateVector(const Vec3<T> &original) const;
  110. T euclideanInnerProduct(const Quat<T> &q) const;
  111. //-----------------------
  112. // Rotation conversion
  113. //-----------------------
  114. Quat<T> & setAxisAngle (const Vec3<T> &axis, T radians);
  115. Quat<T> & setRotation (const Vec3<T> &fromDirection,
  116. const Vec3<T> &toDirection);
  117. T angle () const;
  118. Vec3<T> axis () const;
  119. Matrix33<T> toMatrix33 () const;
  120. Matrix44<T> toMatrix44 () const;
  121. Quat<T> log () const;
  122. Quat<T> exp () const;
  123. private:
  124. void setRotationInternal (const Vec3<T> &f0,
  125. const Vec3<T> &t0,
  126. Quat<T> &q);
  127. };
  128. template<class T>
  129. Quat<T> slerp (const Quat<T> &q1, const Quat<T> &q2, T t);
  130. template<class T>
  131. Quat<T> slerpShortestArc
  132. (const Quat<T> &q1, const Quat<T> &q2, T t);
  133. template<class T>
  134. Quat<T> squad (const Quat<T> &q1, const Quat<T> &q2,
  135. const Quat<T> &qa, const Quat<T> &qb, T t);
  136. template<class T>
  137. void intermediate (const Quat<T> &q0, const Quat<T> &q1,
  138. const Quat<T> &q2, const Quat<T> &q3,
  139. Quat<T> &qa, Quat<T> &qb);
  140. template<class T>
  141. Matrix33<T> operator * (const Matrix33<T> &M, const Quat<T> &q);
  142. template<class T>
  143. Matrix33<T> operator * (const Quat<T> &q, const Matrix33<T> &M);
  144. template<class T>
  145. std::ostream & operator << (std::ostream &o, const Quat<T> &q);
  146. template<class T>
  147. Quat<T> operator * (const Quat<T> &q1, const Quat<T> &q2);
  148. template<class T>
  149. Quat<T> operator / (const Quat<T> &q1, const Quat<T> &q2);
  150. template<class T>
  151. Quat<T> operator / (const Quat<T> &q, T t);
  152. template<class T>
  153. Quat<T> operator * (const Quat<T> &q, T t);
  154. template<class T>
  155. Quat<T> operator * (T t, const Quat<T> &q);
  156. template<class T>
  157. Quat<T> operator + (const Quat<T> &q1, const Quat<T> &q2);
  158. template<class T>
  159. Quat<T> operator - (const Quat<T> &q1, const Quat<T> &q2);
  160. template<class T>
  161. Quat<T> operator ~ (const Quat<T> &q);
  162. template<class T>
  163. Quat<T> operator - (const Quat<T> &q);
  164. template<class T>
  165. Vec3<T> operator * (const Vec3<T> &v, const Quat<T> &q);
  166. //--------------------
  167. // Convenient typedefs
  168. //--------------------
  169. typedef Quat<float> Quatf;
  170. typedef Quat<double> Quatd;
  171. //---------------
  172. // Implementation
  173. //---------------
  174. template<class T>
  175. inline
  176. Quat<T>::Quat (): r (1), v (0, 0, 0)
  177. {
  178. // empty
  179. }
  180. template<class T>
  181. template <class S>
  182. inline
  183. Quat<T>::Quat (const Quat<S> &q): r (q.r), v (q.v)
  184. {
  185. // empty
  186. }
  187. template<class T>
  188. inline
  189. Quat<T>::Quat (T s, T i, T j, T k): r (s), v (i, j, k)
  190. {
  191. // empty
  192. }
  193. template<class T>
  194. inline
  195. Quat<T>::Quat (T s, Vec3<T> d): r (s), v (d)
  196. {
  197. // empty
  198. }
  199. template<class T>
  200. inline Quat<T>
  201. Quat<T>::identity ()
  202. {
  203. return Quat<T>();
  204. }
  205. template<class T>
  206. inline const Quat<T> &
  207. Quat<T>::operator = (const Quat<T> &q)
  208. {
  209. r = q.r;
  210. v = q.v;
  211. return *this;
  212. }
  213. template<class T>
  214. inline const Quat<T> &
  215. Quat<T>::operator *= (const Quat<T> &q)
  216. {
  217. T rtmp = r * q.r - (v ^ q.v);
  218. v = r * q.v + v * q.r + v % q.v;
  219. r = rtmp;
  220. return *this;
  221. }
  222. template<class T>
  223. inline const Quat<T> &
  224. Quat<T>::operator *= (T t)
  225. {
  226. r *= t;
  227. v *= t;
  228. return *this;
  229. }
  230. template<class T>
  231. inline const Quat<T> &
  232. Quat<T>::operator /= (const Quat<T> &q)
  233. {
  234. *this = *this * q.inverse();
  235. return *this;
  236. }
  237. template<class T>
  238. inline const Quat<T> &
  239. Quat<T>::operator /= (T t)
  240. {
  241. r /= t;
  242. v /= t;
  243. return *this;
  244. }
  245. template<class T>
  246. inline const Quat<T> &
  247. Quat<T>::operator += (const Quat<T> &q)
  248. {
  249. r += q.r;
  250. v += q.v;
  251. return *this;
  252. }
  253. template<class T>
  254. inline const Quat<T> &
  255. Quat<T>::operator -= (const Quat<T> &q)
  256. {
  257. r -= q.r;
  258. v -= q.v;
  259. return *this;
  260. }
  261. template<class T>
  262. inline T &
  263. Quat<T>::operator [] (int index)
  264. {
  265. return index ? v[index - 1] : r;
  266. }
  267. template<class T>
  268. inline T
  269. Quat<T>::operator [] (int index) const
  270. {
  271. return index ? v[index - 1] : r;
  272. }
  273. template <class T>
  274. template <class S>
  275. inline bool
  276. Quat<T>::operator == (const Quat<S> &q) const
  277. {
  278. return r == q.r && v == q.v;
  279. }
  280. template <class T>
  281. template <class S>
  282. inline bool
  283. Quat<T>::operator != (const Quat<S> &q) const
  284. {
  285. return r != q.r || v != q.v;
  286. }
  287. template<class T>
  288. inline T
  289. operator ^ (const Quat<T>& q1 ,const Quat<T>& q2)
  290. {
  291. return q1.r * q2.r + (q1.v ^ q2.v);
  292. }
  293. template <class T>
  294. inline T
  295. Quat<T>::length () const
  296. {
  297. return Math<T>::sqrt (r * r + (v ^ v));
  298. }
  299. template <class T>
  300. inline Quat<T> &
  301. Quat<T>::normalize ()
  302. {
  303. if (T l = length())
  304. {
  305. r /= l;
  306. v /= l;
  307. }
  308. else
  309. {
  310. r = 1;
  311. v = Vec3<T> (0);
  312. }
  313. return *this;
  314. }
  315. template <class T>
  316. inline Quat<T>
  317. Quat<T>::normalized () const
  318. {
  319. if (T l = length())
  320. return Quat (r / l, v / l);
  321. return Quat();
  322. }
  323. template<class T>
  324. inline Quat<T>
  325. Quat<T>::inverse () const
  326. {
  327. //
  328. // 1 Q*
  329. // - = ---- where Q* is conjugate (operator~)
  330. // Q Q* Q and (Q* Q) == Q ^ Q (4D dot)
  331. //
  332. T qdot = *this ^ *this;
  333. return Quat (r / qdot, -v / qdot);
  334. }
  335. template<class T>
  336. inline Quat<T> &
  337. Quat<T>::invert ()
  338. {
  339. T qdot = (*this) ^ (*this);
  340. r /= qdot;
  341. v = -v / qdot;
  342. return *this;
  343. }
  344. template<class T>
  345. inline Vec3<T>
  346. Quat<T>::rotateVector(const Vec3<T>& original) const
  347. {
  348. //
  349. // Given a vector p and a quaternion q (aka this),
  350. // calculate p' = qpq*
  351. //
  352. // Assumes unit quaternions (because non-unit
  353. // quaternions cannot be used to rotate vectors
  354. // anyway).
  355. //
  356. Quat<T> vec (0, original); // temporarily promote grade of original
  357. Quat<T> inv (*this);
  358. inv.v *= -1; // unit multiplicative inverse
  359. Quat<T> result = *this * vec * inv;
  360. return result.v;
  361. }
  362. template<class T>
  363. inline T
  364. Quat<T>::euclideanInnerProduct (const Quat<T> &q) const
  365. {
  366. return r * q.r + v.x * q.v.x + v.y * q.v.y + v.z * q.v.z;
  367. }
  368. template<class T>
  369. T
  370. angle4D (const Quat<T> &q1, const Quat<T> &q2)
  371. {
  372. //
  373. // Compute the angle between two quaternions,
  374. // interpreting the quaternions as 4D vectors.
  375. //
  376. Quat<T> d = q1 - q2;
  377. T lengthD = Math<T>::sqrt (d ^ d);
  378. Quat<T> s = q1 + q2;
  379. T lengthS = Math<T>::sqrt (s ^ s);
  380. return 2 * Math<T>::atan2 (lengthD, lengthS);
  381. }
  382. template<class T>
  383. Quat<T>
  384. slerp (const Quat<T> &q1, const Quat<T> &q2, T t)
  385. {
  386. //
  387. // Spherical linear interpolation.
  388. // Assumes q1 and q2 are normalized and that q1 != -q2.
  389. //
  390. // This method does *not* interpolate along the shortest
  391. // arc between q1 and q2. If you desire interpolation
  392. // along the shortest arc, and q1^q2 is negative, then
  393. // consider calling slerpShortestArc(), below, or flipping
  394. // the second quaternion explicitly.
  395. //
  396. // The implementation of squad() depends on a slerp()
  397. // that interpolates as is, without the automatic
  398. // flipping.
  399. //
  400. // Don Hatch explains the method we use here on his
  401. // web page, The Right Way to Calculate Stuff, at
  402. // http://www.plunk.org/~hatch/rightway.php
  403. //
  404. T a = angle4D (q1, q2);
  405. T s = 1 - t;
  406. Quat<T> q = sinx_over_x (s * a) / sinx_over_x (a) * s * q1 +
  407. sinx_over_x (t * a) / sinx_over_x (a) * t * q2;
  408. return q.normalized();
  409. }
  410. template<class T>
  411. Quat<T>
  412. slerpShortestArc (const Quat<T> &q1, const Quat<T> &q2, T t)
  413. {
  414. //
  415. // Spherical linear interpolation along the shortest
  416. // arc from q1 to either q2 or -q2, whichever is closer.
  417. // Assumes q1 and q2 are unit quaternions.
  418. //
  419. if ((q1 ^ q2) >= 0)
  420. return slerp (q1, q2, t);
  421. else
  422. return slerp (q1, -q2, t);
  423. }
  424. template<class T>
  425. Quat<T>
  426. spline (const Quat<T> &q0, const Quat<T> &q1,
  427. const Quat<T> &q2, const Quat<T> &q3,
  428. T t)
  429. {
  430. //
  431. // Spherical Cubic Spline Interpolation -
  432. // from Advanced Animation and Rendering
  433. // Techniques by Watt and Watt, Page 366:
  434. // A spherical curve is constructed using three
  435. // spherical linear interpolations of a quadrangle
  436. // of unit quaternions: q1, qa, qb, q2.
  437. // Given a set of quaternion keys: q0, q1, q2, q3,
  438. // this routine does the interpolation between
  439. // q1 and q2 by constructing two intermediate
  440. // quaternions: qa and qb. The qa and qb are
  441. // computed by the intermediate function to
  442. // guarantee the continuity of tangents across
  443. // adjacent cubic segments. The qa represents in-tangent
  444. // for q1 and the qb represents the out-tangent for q2.
  445. //
  446. // The q1 q2 is the cubic segment being interpolated.
  447. // The q0 is from the previous adjacent segment and q3 is
  448. // from the next adjacent segment. The q0 and q3 are used
  449. // in computing qa and qb.
  450. //
  451. Quat<T> qa = intermediate (q0, q1, q2);
  452. Quat<T> qb = intermediate (q1, q2, q3);
  453. Quat<T> result = squad (q1, qa, qb, q2, t);
  454. return result;
  455. }
  456. template<class T>
  457. Quat<T>
  458. squad (const Quat<T> &q1, const Quat<T> &qa,
  459. const Quat<T> &qb, const Quat<T> &q2,
  460. T t)
  461. {
  462. //
  463. // Spherical Quadrangle Interpolation -
  464. // from Advanced Animation and Rendering
  465. // Techniques by Watt and Watt, Page 366:
  466. // It constructs a spherical cubic interpolation as
  467. // a series of three spherical linear interpolations
  468. // of a quadrangle of unit quaternions.
  469. //
  470. Quat<T> r1 = slerp (q1, q2, t);
  471. Quat<T> r2 = slerp (qa, qb, t);
  472. Quat<T> result = slerp (r1, r2, 2 * t * (1 - t));
  473. return result;
  474. }
  475. template<class T>
  476. Quat<T>
  477. intermediate (const Quat<T> &q0, const Quat<T> &q1, const Quat<T> &q2)
  478. {
  479. //
  480. // From advanced Animation and Rendering
  481. // Techniques by Watt and Watt, Page 366:
  482. // computing the inner quadrangle
  483. // points (qa and qb) to guarantee tangent
  484. // continuity.
  485. //
  486. Quat<T> q1inv = q1.inverse();
  487. Quat<T> c1 = q1inv * q2;
  488. Quat<T> c2 = q1inv * q0;
  489. Quat<T> c3 = (T) (-0.25) * (c2.log() + c1.log());
  490. Quat<T> qa = q1 * c3.exp();
  491. qa.normalize();
  492. return qa;
  493. }
  494. template <class T>
  495. inline Quat<T>
  496. Quat<T>::log () const
  497. {
  498. //
  499. // For unit quaternion, from Advanced Animation and
  500. // Rendering Techniques by Watt and Watt, Page 366:
  501. //
  502. T theta = Math<T>::acos (std::min (r, (T) 1.0));
  503. if (theta == 0)
  504. return Quat<T> (0, v);
  505. T sintheta = Math<T>::sin (theta);
  506. T k;
  507. if (abs (sintheta) < 1 && abs (theta) >= limits<T>::max() * abs (sintheta))
  508. k = 1;
  509. else
  510. k = theta / sintheta;
  511. return Quat<T> ((T) 0, v.x * k, v.y * k, v.z * k);
  512. }
  513. template <class T>
  514. inline Quat<T>
  515. Quat<T>::exp () const
  516. {
  517. //
  518. // For pure quaternion (zero scalar part):
  519. // from Advanced Animation and Rendering
  520. // Techniques by Watt and Watt, Page 366:
  521. //
  522. T theta = v.length();
  523. T sintheta = Math<T>::sin (theta);
  524. T k;
  525. if (abs (theta) < 1 && abs (sintheta) >= limits<T>::max() * abs (theta))
  526. k = 1;
  527. else
  528. k = sintheta / theta;
  529. T costheta = Math<T>::cos (theta);
  530. return Quat<T> (costheta, v.x * k, v.y * k, v.z * k);
  531. }
  532. template <class T>
  533. inline T
  534. Quat<T>::angle () const
  535. {
  536. return 2 * Math<T>::atan2 (v.length(), r);
  537. }
  538. template <class T>
  539. inline Vec3<T>
  540. Quat<T>::axis () const
  541. {
  542. return v.normalized();
  543. }
  544. template <class T>
  545. inline Quat<T> &
  546. Quat<T>::setAxisAngle (const Vec3<T> &axis, T radians)
  547. {
  548. r = Math<T>::cos (radians / 2);
  549. v = axis.normalized() * Math<T>::sin (radians / 2);
  550. return *this;
  551. }
  552. template <class T>
  553. Quat<T> &
  554. Quat<T>::setRotation (const Vec3<T> &from, const Vec3<T> &to)
  555. {
  556. //
  557. // Create a quaternion that rotates vector from into vector to,
  558. // such that the rotation is around an axis that is the cross
  559. // product of from and to.
  560. //
  561. // This function calls function setRotationInternal(), which is
  562. // numerically accurate only for rotation angles that are not much
  563. // greater than pi/2. In order to achieve good accuracy for angles
  564. // greater than pi/2, we split large angles in half, and rotate in
  565. // two steps.
  566. //
  567. //
  568. // Normalize from and to, yielding f0 and t0.
  569. //
  570. Vec3<T> f0 = from.normalized();
  571. Vec3<T> t0 = to.normalized();
  572. if ((f0 ^ t0) >= 0)
  573. {
  574. //
  575. // The rotation angle is less than or equal to pi/2.
  576. //
  577. setRotationInternal (f0, t0, *this);
  578. }
  579. else
  580. {
  581. //
  582. // The angle is greater than pi/2. After computing h0,
  583. // which is halfway between f0 and t0, we rotate first
  584. // from f0 to h0, then from h0 to t0.
  585. //
  586. Vec3<T> h0 = (f0 + t0).normalized();
  587. if ((h0 ^ h0) != 0)
  588. {
  589. setRotationInternal (f0, h0, *this);
  590. Quat<T> q;
  591. setRotationInternal (h0, t0, q);
  592. *this *= q;
  593. }
  594. else
  595. {
  596. //
  597. // f0 and t0 point in exactly opposite directions.
  598. // Pick an arbitrary axis that is orthogonal to f0,
  599. // and rotate by pi.
  600. //
  601. r = T (0);
  602. Vec3<T> f02 = f0 * f0;
  603. if (f02.x <= f02.y && f02.x <= f02.z)
  604. v = (f0 % Vec3<T> (1, 0, 0)).normalized();
  605. else if (f02.y <= f02.z)
  606. v = (f0 % Vec3<T> (0, 1, 0)).normalized();
  607. else
  608. v = (f0 % Vec3<T> (0, 0, 1)).normalized();
  609. }
  610. }
  611. return *this;
  612. }
  613. template <class T>
  614. void
  615. Quat<T>::setRotationInternal (const Vec3<T> &f0, const Vec3<T> &t0, Quat<T> &q)
  616. {
  617. //
  618. // The following is equivalent to setAxisAngle(n,2*phi),
  619. // where the rotation axis, n, is orthogonal to the f0 and
  620. // t0 vectors, and 2*phi is the angle between f0 and t0.
  621. //
  622. // This function is called by setRotation(), above; it assumes
  623. // that f0 and t0 are normalized and that the angle between
  624. // them is not much greater than pi/2. This function becomes
  625. // numerically inaccurate if f0 and t0 point into nearly
  626. // opposite directions.
  627. //
  628. //
  629. // Find a normalized vector, h0, that is halfway between f0 and t0.
  630. // The angle between f0 and h0 is phi.
  631. //
  632. Vec3<T> h0 = (f0 + t0).normalized();
  633. //
  634. // Store the rotation axis and rotation angle.
  635. //
  636. q.r = f0 ^ h0; // f0 ^ h0 == cos (phi)
  637. q.v = f0 % h0; // (f0 % h0).length() == sin (phi)
  638. }
  639. template<class T>
  640. Matrix33<T>
  641. Quat<T>::toMatrix33() const
  642. {
  643. return Matrix33<T> (1 - 2 * (v.y * v.y + v.z * v.z),
  644. 2 * (v.x * v.y + v.z * r),
  645. 2 * (v.z * v.x - v.y * r),
  646. 2 * (v.x * v.y - v.z * r),
  647. 1 - 2 * (v.z * v.z + v.x * v.x),
  648. 2 * (v.y * v.z + v.x * r),
  649. 2 * (v.z * v.x + v.y * r),
  650. 2 * (v.y * v.z - v.x * r),
  651. 1 - 2 * (v.y * v.y + v.x * v.x));
  652. }
  653. template<class T>
  654. Matrix44<T>
  655. Quat<T>::toMatrix44() const
  656. {
  657. return Matrix44<T> (1 - 2 * (v.y * v.y + v.z * v.z),
  658. 2 * (v.x * v.y + v.z * r),
  659. 2 * (v.z * v.x - v.y * r),
  660. 0,
  661. 2 * (v.x * v.y - v.z * r),
  662. 1 - 2 * (v.z * v.z + v.x * v.x),
  663. 2 * (v.y * v.z + v.x * r),
  664. 0,
  665. 2 * (v.z * v.x + v.y * r),
  666. 2 * (v.y * v.z - v.x * r),
  667. 1 - 2 * (v.y * v.y + v.x * v.x),
  668. 0,
  669. 0,
  670. 0,
  671. 0,
  672. 1);
  673. }
  674. template<class T>
  675. inline Matrix33<T>
  676. operator * (const Matrix33<T> &M, const Quat<T> &q)
  677. {
  678. return M * q.toMatrix33();
  679. }
  680. template<class T>
  681. inline Matrix33<T>
  682. operator * (const Quat<T> &q, const Matrix33<T> &M)
  683. {
  684. return q.toMatrix33() * M;
  685. }
  686. template<class T>
  687. std::ostream &
  688. operator << (std::ostream &o, const Quat<T> &q)
  689. {
  690. return o << "(" << q.r
  691. << " " << q.v.x
  692. << " " << q.v.y
  693. << " " << q.v.z
  694. << ")";
  695. }
  696. template<class T>
  697. inline Quat<T>
  698. operator * (const Quat<T> &q1, const Quat<T> &q2)
  699. {
  700. return Quat<T> (q1.r * q2.r - (q1.v ^ q2.v),
  701. q1.r * q2.v + q1.v * q2.r + q1.v % q2.v);
  702. }
  703. template<class T>
  704. inline Quat<T>
  705. operator / (const Quat<T> &q1, const Quat<T> &q2)
  706. {
  707. return q1 * q2.inverse();
  708. }
  709. template<class T>
  710. inline Quat<T>
  711. operator / (const Quat<T> &q, T t)
  712. {
  713. return Quat<T> (q.r / t, q.v / t);
  714. }
  715. template<class T>
  716. inline Quat<T>
  717. operator * (const Quat<T> &q, T t)
  718. {
  719. return Quat<T> (q.r * t, q.v * t);
  720. }
  721. template<class T>
  722. inline Quat<T>
  723. operator * (T t, const Quat<T> &q)
  724. {
  725. return Quat<T> (q.r * t, q.v * t);
  726. }
  727. template<class T>
  728. inline Quat<T>
  729. operator + (const Quat<T> &q1, const Quat<T> &q2)
  730. {
  731. return Quat<T> (q1.r + q2.r, q1.v + q2.v);
  732. }
  733. template<class T>
  734. inline Quat<T>
  735. operator - (const Quat<T> &q1, const Quat<T> &q2)
  736. {
  737. return Quat<T> (q1.r - q2.r, q1.v - q2.v);
  738. }
  739. template<class T>
  740. inline Quat<T>
  741. operator ~ (const Quat<T> &q)
  742. {
  743. return Quat<T> (q.r, -q.v);
  744. }
  745. template<class T>
  746. inline Quat<T>
  747. operator - (const Quat<T> &q)
  748. {
  749. return Quat<T> (-q.r, -q.v);
  750. }
  751. template<class T>
  752. inline Vec3<T>
  753. operator * (const Vec3<T> &v, const Quat<T> &q)
  754. {
  755. Vec3<T> a = q.v % v;
  756. Vec3<T> b = q.v % a;
  757. return v + T (2) * (q.r * a + b);
  758. }
  759. #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
  760. #pragma warning(default:4244)
  761. #endif
  762. IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
  763. #endif // INCLUDED_IMATHQUAT_H