Visualization Library 2.1.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
Quaternion.hpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #ifndef Quaternion_INCLUDE_ONCE
33 #define Quaternion_INCLUDE_ONCE
34 
35 #include <vlCore/glsl_math.hpp>
36 
37 namespace vl
38 {
39  //-----------------------------------------------------------------------------
40  // Quaternion
41  //-----------------------------------------------------------------------------
43  template<typename T_Scalar>
44  class Quaternion
45  {
46  public:
47  typedef T_Scalar scalar_type;
48  //-----------------------------------------------------------------------------
51  {
52  setNoRotation();
53  }
54  //-----------------------------------------------------------------------------
57  {
58  operator=(quat);
59  }
60  //-----------------------------------------------------------------------------
61  template<typename T>
62  explicit Quaternion(const Quaternion<T>& q)
63  {
64  mXYZW.x() = (T_Scalar)q.x();
65  mXYZW.y() = (T_Scalar)q.y();
66  mXYZW.z() = (T_Scalar)q.z();
67  mXYZW.w() = (T_Scalar)q.w();
68  }
69  //-----------------------------------------------------------------------------
71  explicit Quaternion(T_Scalar x, T_Scalar y, T_Scalar z, T_Scalar w)
72  {
73  mXYZW.x() = x;
74  mXYZW.y() = y;
75  mXYZW.z() = z;
76  mXYZW.w() = w;
77  }
78  //-----------------------------------------------------------------------------
80  explicit Quaternion(T_Scalar degrees, const Vector3<T_Scalar>& axis)
81  {
82  setFromAxisAngle(axis, degrees);
83  }
84  //-----------------------------------------------------------------------------
86  explicit Quaternion(const Vector4<T_Scalar>& v)
87  {
88  mXYZW.x() = (T_Scalar)v.x();
89  mXYZW.y() = (T_Scalar)v.y();
90  mXYZW.z() = (T_Scalar)v.z();
91  mXYZW.w() = (T_Scalar)v.w();
92  }
93  //-----------------------------------------------------------------------------
96  {
97  mXYZW.x() = q.x();
98  mXYZW.y() = q.y();
99  mXYZW.z() = q.z();
100  mXYZW.w() = q.w();
101  return *this;
102  }
103  //-----------------------------------------------------------------------------
106  {
107  mXYZW.x() = (T_Scalar)v.x();
108  mXYZW.y() = (T_Scalar)v.y();
109  mXYZW.z() = (T_Scalar)v.z();
110  mXYZW.w() = (T_Scalar)v.w();
111  return *this;
112  }
113  //-----------------------------------------------------------------------------
114  bool operator==(const Quaternion& q) const
115  {
116  return x() == q.x() && y() == q.y() && z() == q.z() && w() == q.w();
117  }
118  //-----------------------------------------------------------------------------
119  bool operator!=(const Quaternion& q) const
120  {
121  return !operator==(q);
122  }
123  //-----------------------------------------------------------------------------
125  bool operator<(const Quaternion& other) const
126  {
127  if (x() != other.x())
128  return x() < other.x();
129  if (y() != other.y())
130  return y() < other.y();
131  if (z() != other.z())
132  return z() < other.z();
133  else
134  return w() < other.w();
135  }
136  //-----------------------------------------------------------------------------
138  const Vector4<T_Scalar>& xyzw() const { return mXYZW; }
139  //-----------------------------------------------------------------------------
141  Vector4<T_Scalar>& xyzw() { return mXYZW; }
142  //-----------------------------------------------------------------------------
143  T_Scalar& x() { return mXYZW.x(); }
144  //-----------------------------------------------------------------------------
145  T_Scalar& y() { return mXYZW.y(); }
146  //-----------------------------------------------------------------------------
147  T_Scalar& z() { return mXYZW.z(); }
148  //-----------------------------------------------------------------------------
149  T_Scalar& w() { return mXYZW.w(); }
150  //-----------------------------------------------------------------------------
151  const T_Scalar& x() const { return mXYZW.x(); }
152  //-----------------------------------------------------------------------------
153  const T_Scalar& y() const { return mXYZW.y(); }
154  //-----------------------------------------------------------------------------
155  const T_Scalar& z() const { return mXYZW.z(); }
156  //-----------------------------------------------------------------------------
157  const T_Scalar& w() const { return mXYZW.w(); }
158  //-----------------------------------------------------------------------------
159  Quaternion operator*(T_Scalar val) const
160  {
161  Quaternion t = *this;
162  t.x() *= val;
163  t.y() *= val;
164  t.z() *= val;
165  t.w() *= val;
166  return t;
167  }
168  //-----------------------------------------------------------------------------
169  Quaternion& operator*=(T_Scalar val)
170  {
171  x() *= val;
172  y() *= val;
173  z() *= val;
174  w() *= val;
175  return *this;
176  }
177  //-----------------------------------------------------------------------------
178  Quaternion operator/(T_Scalar val) const
179  {
180  Quaternion t = *this;
181  val = (T_Scalar)1.0 / val;
182  t.x() *= val;
183  t.y() *= val;
184  t.z() *= val;
185  t.w() *= val;
186  return t;
187  }
188  //-----------------------------------------------------------------------------
189  Quaternion& operator/=(T_Scalar val)
190  {
191  val = (T_Scalar)1.0 / val;
192  x() *= val;
193  y() *= val;
194  z() *= val;
195  w() *= val;
196  return *this;
197  }
198  //-----------------------------------------------------------------------------
200  {
201  Quaternion t = *this;
202  t.x() += q.x();
203  t.y() += q.y();
204  t.z() += q.z();
205  t.w() += q.w();
206  return t;
207  }
208  //-----------------------------------------------------------------------------
210  {
211  x() += q.x();
212  y() += q.y();
213  z() += q.z();
214  w() += q.w();
215  return *this;
216  }
217  //-----------------------------------------------------------------------------
219  {
220  Quaternion t = *this;
221  t.x() -= q.x();
222  t.y() -= q.y();
223  t.z() -= q.z();
224  t.w() -= q.w();
225  return t;
226  }
227  //-----------------------------------------------------------------------------
229  {
230  x() -= q.x();
231  y() -= q.y();
232  z() -= q.z();
233  w() -= q.w();
234  return *this;
235  }
236  //-----------------------------------------------------------------------------
239  {
240  return Quaternion(-x(), -y(), -z(), -w());
241  }
242  //-----------------------------------------------------------------------------
245  {
246  mXYZW.x() = 0;
247  mXYZW.y() = 0;
248  mXYZW.z() = 0;
249  mXYZW.w() = 0;
250  return *this;
251  }
252  //-----------------------------------------------------------------------------
255  {
256  return Quaternion().setZero();
257  }
258  //-----------------------------------------------------------------------------
261  {
262  return q.setZero();
263  }
264  //-----------------------------------------------------------------------------
267  {
268  mXYZW.x() = 0;
269  mXYZW.y() = 0;
270  mXYZW.z() = 0;
271  mXYZW.w() = 1;
272  return *this;
273  }
274  //-----------------------------------------------------------------------------
277  {
278  return Quaternion();
279  }
280  //-----------------------------------------------------------------------------
283  {
284  return q.setNoRotation();
285  }
286  //-----------------------------------------------------------------------------
289  //-----------------------------------------------------------------------------
292  {
293  return Quaternion().setFromVectors(from, to);
294  }
295  //-----------------------------------------------------------------------------
298  {
299  return q.setFromVectors(from, to);
300  }
301  //-----------------------------------------------------------------------------
305  //-----------------------------------------------------------------------------
308  {
309  return Quaternion().setFromMatrix(m);
310  }
311  //-----------------------------------------------------------------------------
314  {
315  return q.setFromMatrix(m);
316  }
317  //-----------------------------------------------------------------------------
321  //-----------------------------------------------------------------------------
324  {
325  return Quaternion().setFromMatrix(m);
326  }
327  //-----------------------------------------------------------------------------
330  {
331  return q.setFromMatrix(m);
332  }
333  //-----------------------------------------------------------------------------
334  Quaternion& setFromEulerXYZ(T_Scalar degX, T_Scalar degY, T_Scalar degZ);
335  //-----------------------------------------------------------------------------
336  static Quaternion getFromEulerXYZ(T_Scalar degX, T_Scalar degY, T_Scalar degZ)
337  {
338  return Quaternion().setFromEulerXYZ(degX, degY, degZ);
339  }
340  //-----------------------------------------------------------------------------
341  static Quaternion& getFromEulerXYZ(Quaternion& q, T_Scalar degX, T_Scalar degY, T_Scalar degZ)
342  {
343  return q.setFromEulerXYZ(degX, degY, degZ);
344  }
345  //-----------------------------------------------------------------------------
346  Quaternion& setFromEulerZYX(T_Scalar degZ, T_Scalar degY, T_Scalar degX);
347  //-----------------------------------------------------------------------------
348  static Quaternion getFromEulerZYX(T_Scalar degZ, T_Scalar degY, T_Scalar degX)
349  {
350  return Quaternion().setFromEulerZYX(degZ, degY, degX);
351  }
352  //-----------------------------------------------------------------------------
353  static Quaternion& getFromEulerZYX(Quaternion& q, T_Scalar degZ, T_Scalar degY, T_Scalar degX)
354  {
355  return q.setFromEulerZYX(degZ, degY, degX);
356  }
357  //-----------------------------------------------------------------------------
358  Quaternion& setFromAxisAngle(const Vector3<T_Scalar>& axis, T_Scalar degrees);
359  //-----------------------------------------------------------------------------
360  static Quaternion getFromAxisAngle(const Vector3<T_Scalar>& axis, T_Scalar degrees)
361  {
362  return Quaternion().setFromAxisAngle(axis, degrees);
363  }
364  //-----------------------------------------------------------------------------
365  static Quaternion& getFromAxisAngle(Quaternion& q, const Vector3<T_Scalar>& axis, T_Scalar degrees)
366  {
367  return q.setFromAxisAngle(axis, degrees);
368  }
369  //-----------------------------------------------------------------------------
371  void toAxisAngle( Vector3<T_Scalar>& axis, T_Scalar& degrees ) const;
372  //-----------------------------------------------------------------------------
375  //-----------------------------------------------------------------------------
378  //-----------------------------------------------------------------------------
381  //-----------------------------------------------------------------------------
384  //-----------------------------------------------------------------------------
386  T_Scalar dot(const Quaternion& q) const
387  {
388  return x()*q.x() + y()*q.y() + z()*q.z() + w()*q.w();
389  }
390  //-----------------------------------------------------------------------------
392  T_Scalar length() const { return mXYZW.length(); }
393  //-----------------------------------------------------------------------------
396  Quaternion& normalize(T_Scalar* len=NULL) { mXYZW.normalize(len); return *this; }
397  //-----------------------------------------------------------------------------
400  Quaternion getNormalized(T_Scalar* len=NULL) const { Quaternion t = *this; t.normalize(len); return t; }
401  //-----------------------------------------------------------------------------
404  Quaternion& getNormalized(Quaternion& q, T_Scalar* len=NULL) const { q = *this; q.normalize(len); return q; }
405  //-----------------------------------------------------------------------------
407  T_Scalar lengthSquared() const
408  {
409  return x()*x() + y()*y() + z()*z() + w()*w();
410  }
411  //-----------------------------------------------------------------------------
414  {
415  return Quaternion(-x(), -y(), -z(), w());
416  }
417  //-----------------------------------------------------------------------------
420  {
421  q = Quaternion(-x(), -y(), -z(), w());
422  return q;
423  }
424  //-----------------------------------------------------------------------------
427  {
428  return getConjugate() / lengthSquared();
429  }
430  //-----------------------------------------------------------------------------
433  {
434  q = getConjugate() / lengthSquared();
435  return q;
436  }
437  //-----------------------------------------------------------------------------
441  static Quaternion getSlerp(T_Scalar t, const Quaternion& a, const Quaternion& b);
442  //-----------------------------------------------------------------------------
446  static Quaternion& getSlerp(Quaternion& out, T_Scalar t, const Quaternion& a, const Quaternion& b);
447  //-----------------------------------------------------------------------------
449  static Quaternion getSquad(T_Scalar t, const Quaternion& a, const Quaternion& p, const Quaternion& q, const Quaternion& b)
450  {
451  return getSlerp((T_Scalar)2.0*t*((T_Scalar)1.0-t), getSlerp(t,a,b), getSlerp(t,p,q));
452  }
453  //-----------------------------------------------------------------------------
455  static Quaternion& getSquad(Quaternion& out, T_Scalar t, const Quaternion& a, const Quaternion& p, const Quaternion& q, const Quaternion& b)
456  {
457  return getSlerp(out, (T_Scalar)2.0*t*((T_Scalar)1.0-t), getSlerp(t,a,b), getSlerp(t,p,q));
458  }
459  //-----------------------------------------------------------------------------
463  static Quaternion getNlerp( T_Scalar t, const Quaternion& a, const Quaternion& b )
464  {
465  Quaternion q = a + (b - a) * t;
466  q.normalize();
467  return q;
468  }
469  //-----------------------------------------------------------------------------
473  static Quaternion& getNlerp( Quaternion& out, T_Scalar t, const Quaternion& a, const Quaternion& b )
474  {
475  out = a + (b - a) * t;
476  out.normalize();
477  return out;
478  }
479  //-----------------------------------------------------------------------------
480 
481  protected:
483  };
484  //-----------------------------------------------------------------------------
485  template<typename T_Scalar>
487  {
488  return q * r;
489  }
490  //-----------------------------------------------------------------------------
491  template<typename T_Scalar>
493  {
495  q.x() = q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y();
496  q.y() = q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z();
497  q.z() = q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x();
498  q.w() = q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z();
499  return q;
500  }
501  //-----------------------------------------------------------------------------
502  // post multiplication
503  template<typename T_Scalar>
505  {
506  // Matrix conversion formula based implementation
507  T_Scalar x2 = q.x() * q.x();
508  T_Scalar y2 = q.y() * q.y();
509  T_Scalar z2 = q.z() * q.z();
510  T_Scalar xy = q.x() * q.y();
511  T_Scalar xz = q.x() * q.z();
512  T_Scalar yz = q.y() * q.z();
513  T_Scalar wx = q.w() * q.x();
514  T_Scalar wy = q.w() * q.y();
515  T_Scalar wz = q.w() * q.z();
516 
518  r.x() = ( v.x()*(1.0f - 2.0f * (y2 + z2)) + v.y()*(2.0f * (xy - wz)) + v.z()*(2.0f * (xz + wy)) );
519  r.y() = ( v.x()*(2.0f * (xy + wz)) + v.y()*(1.0f - 2.0f * (x2 + z2)) + v.z()*(2.0f * (yz - wx)) );
520  r.z() = ( v.x()*(2.0f * (xz - wy)) + v.y()*(2.0f * (yz + wx)) + v.z()*(1.0f - 2.0f * (x2 + y2)) );
521  return r;
522  }
523  //-----------------------------------------------------------------------------
524  // post multiplication
525  template<typename T_Scalar>
527  {
528  return Vector4<T_Scalar>( q * v.xyz(), v.w() );
529  }
530  //-----------------------------------------------------------------------------
531  template<typename T_Scalar>
532  Quaternion<T_Scalar>& Quaternion<T_Scalar>::setFromEulerXYZ(T_Scalar degX, T_Scalar degY, T_Scalar degZ )
533  {
534  *this = Quaternion<T_Scalar>(degX, Vector3<T_Scalar>(1,0,0)) * Quaternion<T_Scalar>(degY, Vector3<T_Scalar>(0,1,0)) * Quaternion<T_Scalar>(degZ, Vector3<T_Scalar>(0,0,1));
535  return *this;
536  }
537  //-----------------------------------------------------------------------------
538  template<typename T_Scalar>
539  Quaternion<T_Scalar>& Quaternion<T_Scalar>::setFromEulerZYX(T_Scalar degZ, T_Scalar degY, T_Scalar degX )
540  {
541  *this = Quaternion<T_Scalar>(degZ, Vector3<T_Scalar>(0,0,1)) * Quaternion<T_Scalar>(degY, Vector3<T_Scalar>(0,1,0)) * Quaternion<T_Scalar>(degX, Vector3<T_Scalar>(1,0,0));
542  return *this;
543  }
544  //-----------------------------------------------------------------------------
545  template<typename T_Scalar>
547  {
548  return setFromMatrix( m.get3x3() );
549  }
550  //-----------------------------------------------------------------------------
551  template<typename T_Scalar>
553  {
554  T_Scalar tr, s, q[4];
555 
556  int next[3] = {1, 2, 0};
557 
558  tr = m.e(0,0) + m.e(1,1) + m.e(2,2);
559 
560  // check the diagonal
561  if (tr + (T_Scalar)1.0 > 0.0)
562  {
563  s = vl::sqrt(tr + (T_Scalar)1.0);
564  w() = s / (T_Scalar)2.0;
565  s = (T_Scalar)0.5 / s;
566  x() = (m.e(2,1) - m.e(1,2)) * s;
567  y() = (m.e(0,2) - m.e(2,0)) * s;
568  z() = (m.e(1,0) - m.e(0,1)) * s;
569  }
570  else
571  {
572  // diagonal is negative
573  int i, j, k;
574  i = 0;
575  if (m.e(1,1) > m.e(0,0)) i = 1;
576  if (m.e(2,2) > m.e(i,i)) i = 2;
577  j = next[i];
578  k = next[j];
579 
580  s = vl::sqrt((m.e(i,i) - (m.e(j,j) + m.e(k,k))) + (T_Scalar)1.0);
581 
582  q[i] = s * (T_Scalar)0.5;
583 
584  if (s != 0.0)
585  s = (T_Scalar)0.5 / s;
586 
587  q[3] = (m.e(k,j) - m.e(j,k)) * s;
588  q[j] = (m.e(j,i) + m.e(i,j)) * s;
589  q[k] = (m.e(k,i) + m.e(i,k)) * s;
590 
591  x() = q[0];
592  y() = q[1];
593  z() = q[2];
594  w() = q[3];
595  }
596 
597  return *this;
598  }
599  //-----------------------------------------------------------------------------
600  template<typename T_Scalar>
602  {
603  degrees *= (T_Scalar)dDEG_TO_RAD;
604  T_Scalar sa2 = sin(degrees * (T_Scalar)0.5);
605  Vector3<T_Scalar> na = axis;
606  na.normalize();
607  mXYZW.x() = na.x() * sa2;
608  mXYZW.y() = na.y() * sa2;
609  mXYZW.z() = na.z() * sa2;
610  mXYZW.w() = cos(degrees * (T_Scalar)0.5);
611  return *this;
612  }
613  //-----------------------------------------------------------------------------
614  template<typename T_Scalar>
616  {
617  T_Scalar iscale = sqrt( x()*x() + y()*y() + z()*z() );
618  if (iscale == 0)
619  {
620  axis.x() = 0;
621  axis.y() = 0;
622  axis.z() = 0;
623  degrees = 0;
624  }
625  else
626  {
627  iscale = T_Scalar(1.0) / iscale;
628  axis.x() = x() * iscale;
629  axis.y() = y() * iscale;
630  axis.z() = z() * iscale;
631  VL_CHECK(w()>=-1.0 && w()<=+1.0)
632  T_Scalar tw = clamp(w(),(T_Scalar)-1.0,(T_Scalar)+1.0);
633  degrees = acos( tw ) * (T_Scalar)2.0 * (T_Scalar)dRAD_TO_DEG;
634  }
635  }
636  //-----------------------------------------------------------------------------
637  template<typename T_Scalar>
639  {
640  T_Scalar x2 = x() * x();
641  T_Scalar y2 = y() * y();
642  T_Scalar z2 = z() * z();
643  T_Scalar xy = x() * y();
644  T_Scalar xz = x() * z();
645  T_Scalar yz = y() * z();
646  T_Scalar wx = w() * x();
647  T_Scalar wy = w() * y();
648  T_Scalar wz = w() * z();
649 
650  return out = Matrix4<T_Scalar>(
651  (1.0f - 2.0f * (y2 + z2)), (2.0f * (xy - wz)), (2.0f * (xz + wy)), 0.0f,
652  (2.0f * (xy + wz)), (1.0f - 2.0f * (x2 + z2)), (2.0f * (yz - wx)), 0.0f,
653  (2.0f * (xz - wy)), (2.0f * (yz + wx)), (1.0f - 2.0f * (x2 + y2)), 0.0f,
654  0.0f, 0.0f, 0.0f, 1.0f );
655  }
656  //-----------------------------------------------------------------------------
657  template<typename T_Scalar>
659  {
660  Matrix4<T_Scalar> out;
661  return toMatrix4(out);
662  }
663  //-----------------------------------------------------------------------------
664  template<typename T_Scalar>
666  {
667  T_Scalar x2 = x() * x();
668  T_Scalar y2 = y() * y();
669  T_Scalar z2 = z() * z();
670  T_Scalar xy = x() * y();
671  T_Scalar xz = x() * z();
672  T_Scalar yz = y() * z();
673  T_Scalar wx = w() * x();
674  T_Scalar wy = w() * y();
675  T_Scalar wz = w() * z();
676 
677  return out = Matrix3<T_Scalar>(
678  (1.0f - 2.0f * (y2 + z2)), (2.0f * (xy + wz)), (2.0f * (xz - wy)),
679  (2.0f * (xy - wz)), (1.0f - 2.0f * (x2 + z2)), (2.0f * (yz + wx)),
680  (2.0f * (xz + wy)), (2.0f * (yz - wx)), (1.0f - 2.0f * (x2 + y2)) );
681  }
682  //-----------------------------------------------------------------------------
683  template<typename T_Scalar>
685  {
686  Matrix3<T_Scalar> out;
687  return toMatrix3(out);
688  }
689  //-----------------------------------------------------------------------------
690  template<typename T_Scalar>
692  {
694  getSlerp(q, t, a, b);
695  return q;
696  }
697  //-----------------------------------------------------------------------------
698  template<typename T_Scalar>
700  {
701  T_Scalar scale_a, scale_b, omega, sinom;
702  T_Scalar cosom = a.dot(b);
703 
704  Quaternion<T_Scalar> b2(b);
705 
706  if ( cosom < 0 )
707  {
708  cosom = -cosom;
709  b2 = -b;
710  }
711 
712  // clamp rounding errors
713  cosom = cosom > (T_Scalar)1 ? (T_Scalar)1 : cosom;
714 
715  if( cosom < (T_Scalar)1.0 )
716  {
717  omega = acos(cosom);
718  sinom = sin(omega);
719  VL_CHECK(sinom != 0)
720  scale_a = sin(((T_Scalar)1.0-t) * omega) / sinom;
721  scale_b = sin(t * omega) / sinom;
722  }
723  else
724  {
725  // linear interpolation for degenerate cases
726  scale_a = (T_Scalar)1.0 - t;
727  scale_b = t;
728  }
729 
730  return out = (a*scale_a) + (b2*scale_b);
731  }
732  //-----------------------------------------------------------------------------
733  template<typename T_Scalar>
735  {
736  Vector3<T_Scalar> a,b;
737  a = from;
738  b = to;
739  a.normalize();
740  b.normalize();
741  Vector3<T_Scalar> axis = cross(a,b);
742  T_Scalar len = 0;
743  axis.normalize(&len);
744  if(len)
745  {
746  T_Scalar cosa = vl::dot(a,b);
747  cosa = clamp(cosa, (T_Scalar)-1.0, (T_Scalar)+1.0);
748  T_Scalar alpha = acos( cosa );
749  setFromAxisAngle(axis, alpha*(T_Scalar)dRAD_TO_DEG);
750  }
751  else
752  setNoRotation();
753  return *this;
754  }
755  //-----------------------------------------------------------------------------
759  //-----------------------------------------------------------------------------
760 }
761 
762 #endif
static Quaternion getFromMatrix(const Matrix4< T_Scalar > &m)
Converts the given rotation matrix into a quaternion.
Definition: Quaternion.hpp:307
const T_Scalar & z() const
Definition: Vector4.hpp:104
float clamp(float x, float minval, float maxval)
Definition: Vector2.hpp:316
Quaternion operator/(T_Scalar val) const
Definition: Quaternion.hpp:178
const Vector3 & normalize(T_Scalar *len=NULL)
Definition: Vector3.hpp:228
Quaternion & operator+=(const Quaternion &q)
Definition: Quaternion.hpp:209
Quaternion & operator*=(T_Scalar val)
Definition: Quaternion.hpp:169
const T_Scalar & x() const
Definition: Vector4.hpp:102
T sqrt(T a)
Definition: glsl_math.hpp:592
Quaternion(const Quaternion &quat)
Copy-constructor.
Definition: Quaternion.hpp:56
const T_Scalar & w() const
Definition: Quaternion.hpp:157
static Quaternion getZero()
Returns the zero quaternion.
Definition: Quaternion.hpp:254
static Quaternion & getNoRotation(Quaternion &q)
Returns the no-rotation quaternion, i.e. Quaternion(0,0,0,1).
Definition: Quaternion.hpp:282
Quaternion & setFromEulerXYZ(T_Scalar degX, T_Scalar degY, T_Scalar degZ)
Definition: Quaternion.hpp:532
T sin(T a)
Definition: glsl_math.hpp:199
T degrees(T radians)
Definition: glsl_math.hpp:173
Quaternion(const Quaternion< T > &q)
Definition: Quaternion.hpp:62
const T_Scalar & z() const
Definition: Vector3.hpp:92
static Quaternion getFromEulerXYZ(T_Scalar degX, T_Scalar degY, T_Scalar degZ)
Definition: Quaternion.hpp:336
void toAxisAngle(Vector3< T_Scalar > &axis, T_Scalar &degrees) const
Converts a quaternion to an axis-angle representation.
Definition: Quaternion.hpp:615
bool operator!=(const Quaternion &q) const
Definition: Quaternion.hpp:119
Quaternion & setFromAxisAngle(const Vector3< T_Scalar > &axis, T_Scalar degrees)
Definition: Quaternion.hpp:601
Quaternion & setZero()
Sets all the components of the quaternion to zero.
Definition: Quaternion.hpp:244
Quaternion & setNoRotation()
Set the quaternion to no-rotation, i.e. Quaternion(0,0,0,1).
Definition: Quaternion.hpp:266
Quaternion< float > fquat
Definition: Quaternion.hpp:756
Vector4< T_Scalar > & xyzw()
Returns the internal vec4 used to contain the xyzw the quaternion components.
Definition: Quaternion.hpp:141
static Quaternion & getFromMatrix(Quaternion &q, const Matrix3< T_Scalar > &m)
Converts the given rotation matrix into a quaternion.
Definition: Quaternion.hpp:329
Quaternion< double > dquat
Definition: Quaternion.hpp:757
T_Scalar lengthSquared() const
Returns the squared length of a quaternion.
Definition: Quaternion.hpp:407
Vector3< T_Scalar > xyz() const
Definition: Vector4.hpp:132
const T_Scalar & e(int i, int j) const
Definition: Matrix3.hpp:524
Quaternion operator*(T_Scalar val) const
Definition: Quaternion.hpp:159
const double dRAD_TO_DEG
Constant to convert radian into degree using double precision.
Definition: std_types.hpp:68
Quaternion & getInverse(Quaternion &q) const
Returns the inverse of a quaternion.
Definition: Quaternion.hpp:432
The Vector4 class is a template class that implements a generic 4 components vector, see also vl::fvec4, vl::dvec4, vl::uvec4, vl::ivec4, vl::svec4, vl::usvec4, vl::bvec4, vl::ubvec4.
Definition: Vector4.hpp:44
fvec3 cross(const fvec3 &v1, const fvec3 &v2)
Definition: Vector3.hpp:278
T_Scalar & y()
Definition: Quaternion.hpp:145
Quaternion & setFromMatrix(const Matrix4< T_Scalar > &m)
Creates a quaternion representing the given rotation matrix.
Definition: Quaternion.hpp:546
const T_Scalar & x() const
Definition: Quaternion.hpp:151
static Quaternion getFromEulerZYX(T_Scalar degZ, T_Scalar degY, T_Scalar degX)
Definition: Quaternion.hpp:348
Quaternion(T_Scalar x, T_Scalar y, T_Scalar z, T_Scalar w)
Constructor.
Definition: Quaternion.hpp:71
static Quaternion & getZero(Quaternion &q)
Returns the zero quaternion.
Definition: Quaternion.hpp:260
const Vector4< T_Scalar > & xyzw() const
Returns the internal vec4 used to contain the xyzw the quaternion components.
Definition: Quaternion.hpp:138
Quaternion(const Vector4< T_Scalar > &v)
Constructor from vec4.
Definition: Quaternion.hpp:86
bool operator<(const Quaternion &other) const
Lexicographic ordering.
Definition: Quaternion.hpp:125
T_Scalar scalar_type
Definition: Quaternion.hpp:47
Implements a Quaternion usually used to represent rotations and orientations.
Definition: Quaternion.hpp:44
Visualization Library main namespace.
Quaternion()
Constructor.
Definition: Quaternion.hpp:50
float dot(float a, float b)
Definition: glsl_math.hpp:1111
const double dDEG_TO_RAD
Constant to convert degree into radian using double precision.
Definition: std_types.hpp:66
Quaternion getNormalized(T_Scalar *len=NULL) const
Returns the normalized version of a quaternion.
Definition: Quaternion.hpp:400
Quaternion & normalize(T_Scalar *len=NULL)
Normalizes a quaternion.
Definition: Quaternion.hpp:396
The Matrix3 class is a template class that implements a generic 3x3 matrix, see also vl::dmat3...
Definition: Matrix3.hpp:48
static Quaternion getNoRotation()
Returns the no-rotation quaternion, i.e. Quaternion(0,0,0,1).
Definition: Quaternion.hpp:276
Matrix3< T_Scalar > get3x3() const
Definition: Matrix4.hpp:328
static Quaternion getFromVectors(const Vector3< T_Scalar > &from, const Vector3< T_Scalar > &to)
Sets the quaternion to represent the rotation transforming from into to.
Definition: Quaternion.hpp:291
static Quaternion & getFromVectors(Quaternion &q, const Vector3< T_Scalar > &from, const Vector3< T_Scalar > &to)
Sets the quaternion to represent the rotation transforming from into to.
Definition: Quaternion.hpp:297
Quaternion operator+(const Quaternion &q) const
Definition: Quaternion.hpp:199
The Vector3 class is a template class that implements a generic 3 components vector, see also vl::fvec3, vl::dvec3, vl::uvec3, vl::ivec3, vl::svec3, vl::usvec3, vl::bvec3, vl::ubvec3.
Definition: Vector3.hpp:44
Quaternion< real > quat
Definition: Quaternion.hpp:758
T_Scalar length() const
Returns the length of a quaternion.
Definition: Quaternion.hpp:392
Quaternion & getNormalized(Quaternion &q, T_Scalar *len=NULL) const
Returns the normalized version of a quaternion.
Definition: Quaternion.hpp:404
const T_Scalar & z() const
Definition: Quaternion.hpp:155
static Quaternion & getFromEulerZYX(Quaternion &q, T_Scalar degZ, T_Scalar degY, T_Scalar degX)
Definition: Quaternion.hpp:353
bool operator==(const Quaternion &q) const
Definition: Quaternion.hpp:114
Quaternion(T_Scalar degrees, const Vector3< T_Scalar > &axis)
Axis-angle constructor.
Definition: Quaternion.hpp:80
T_Scalar & z()
Definition: Quaternion.hpp:147
Matrix4< T_Scalar > toMatrix4() const
Converts a quaternion to a 4x4 rotation matrix.
Definition: Quaternion.hpp:658
Implements the OpenGL Shading Language convenience functions for scalar and vector operations...
static Quaternion & getNlerp(Quaternion &out, T_Scalar t, const Quaternion &a, const Quaternion &b)
Normalized spherical interpolation of two quaternions.
Definition: Quaternion.hpp:473
static Quaternion getFromAxisAngle(const Vector3< T_Scalar > &axis, T_Scalar degrees)
Definition: Quaternion.hpp:360
const T_Scalar & y() const
Definition: Vector3.hpp:91
static Quaternion & getFromMatrix(Quaternion &q, const Matrix4< T_Scalar > &m)
Converts the given rotation matrix into a quaternion.
Definition: Quaternion.hpp:313
const T_Scalar & y() const
Definition: Vector4.hpp:103
Quaternion & setFromEulerZYX(T_Scalar degZ, T_Scalar degY, T_Scalar degX)
Definition: Quaternion.hpp:539
static Quaternion getSquad(T_Scalar t, const Quaternion &a, const Quaternion &p, const Quaternion &q, const Quaternion &b)
Spherical cubic interpolation of two quaternions.
Definition: Quaternion.hpp:449
Quaternion operator-(const Quaternion &q) const
Definition: Quaternion.hpp:218
Quaternion & setFromVectors(const Vector3< T_Scalar > &from, const Vector3< T_Scalar > &to)
Sets the quaternion to represent the rotation transforming from into to.
Definition: Quaternion.hpp:734
T_Scalar & x()
Definition: Quaternion.hpp:143
Quaternion getConjugate() const
Returns the conjugate of a quaternion.
Definition: Quaternion.hpp:413
Quaternion & operator-=(const Quaternion &q)
Definition: Quaternion.hpp:228
The Matrix4 class is a template class that implements a generic 4x4 matrix, see also vl::dmat4...
Definition: Matrix4.hpp:48
#define NULL
Definition: OpenGLDefs.hpp:81
const T_Scalar & y() const
Definition: Quaternion.hpp:153
Quaternion & getConjugate(Quaternion &q) const
Returns the conjugate of a quaternion.
Definition: Quaternion.hpp:419
Vector4< T_Scalar > mXYZW
Definition: Quaternion.hpp:482
Matrix3< T_Scalar > toMatrix3() const
Converts a quaternion to a 3x3 rotation matrix.
Definition: Quaternion.hpp:684
Quaternion & operator/=(T_Scalar val)
Definition: Quaternion.hpp:189
T cos(T a)
Definition: glsl_math.hpp:225
static Quaternion & getSquad(Quaternion &out, T_Scalar t, const Quaternion &a, const Quaternion &p, const Quaternion &q, const Quaternion &b)
Spherical cubic interpolation of two quaternions.
Definition: Quaternion.hpp:455
const T_Scalar & x() const
Definition: Vector3.hpp:90
Quaternion & operator=(const Quaternion &q)
Assignment operator.
Definition: Quaternion.hpp:95
static Quaternion getFromMatrix(const Matrix3< T_Scalar > &m)
Converts the given rotation matrix into a quaternion.
Definition: Quaternion.hpp:323
T acos(T a)
Definition: glsl_math.hpp:329
static Quaternion getNlerp(T_Scalar t, const Quaternion &a, const Quaternion &b)
Normalized spherical interpolation of two quaternions.
Definition: Quaternion.hpp:463
static Quaternion & getFromAxisAngle(Quaternion &q, const Vector3< T_Scalar > &axis, T_Scalar degrees)
Definition: Quaternion.hpp:365
T_Scalar dot(const Quaternion &q) const
Returns the dot product between a quaternion and the given quaternion.
Definition: Quaternion.hpp:386
T_Scalar & w()
Definition: Quaternion.hpp:149
static Quaternion & getFromEulerXYZ(Quaternion &q, T_Scalar degX, T_Scalar degY, T_Scalar degZ)
Definition: Quaternion.hpp:341
#define VL_CHECK(expr)
Definition: checks.hpp:73
Quaternion operator-() const
Returns the negated quaternion.
Definition: Quaternion.hpp:238
Quaternion & operator=(const Vector4< T_Scalar > &v)
Assignment operator for vec4.
Definition: Quaternion.hpp:105
const T_Scalar & w() const
Definition: Vector4.hpp:105
static Quaternion getSlerp(T_Scalar t, const Quaternion &a, const Quaternion &b)
Spherical linear interpolation of two quaternions.
Definition: Quaternion.hpp:691
Quaternion getInverse() const
Returns the inverse of a quaternion.
Definition: Quaternion.hpp:426