OpenVDB  12.0.0
Quat.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: Apache-2.0
3 
4 #ifndef OPENVDB_MATH_QUAT_H_HAS_BEEN_INCLUDED
5 #define OPENVDB_MATH_QUAT_H_HAS_BEEN_INCLUDED
6 
7 #include "Mat.h"
8 #include "Mat3.h"
9 #include "Math.h"
10 #include "Vec3.h"
11 #include <openvdb/Exceptions.h>
12 #include <openvdb/util/Assert.h>
13 #include <cmath>
14 #include <iostream>
15 #include <sstream>
16 #include <string>
17 
18 
19 namespace openvdb {
21 namespace OPENVDB_VERSION_NAME {
22 namespace math {
23 
24 template<typename T> class Quat;
25 
26 /// Linear interpolation between the two quaternions
27 template <typename T>
28 Quat<T> slerp(const Quat<T> &q1, const Quat<T> &q2, T t, T tolerance=0.00001)
29 {
30  T qdot, angle, sineAngle;
31 
32  qdot = q1.dot(q2);
33 
34  if (fabs(qdot) >= 1.0) {
35  angle = 0; // not necessary but suppresses compiler warning
36  sineAngle = 0;
37  } else {
38  angle = acos(qdot);
39  sineAngle = sin(angle);
40  }
41 
42  //
43  // Denominator close to 0 corresponds to the case where the
44  // two quaternions are close to the same rotation. In this
45  // case linear interpolation is used but we normalize to
46  // guarantee unit length
47  //
48  if (sineAngle <= tolerance) {
49  T s = 1.0 - t;
50 
51  Quat<T> qtemp(s * q1[0] + t * q2[0], s * q1[1] + t * q2[1],
52  s * q1[2] + t * q2[2], s * q1[3] + t * q2[3]);
53  //
54  // Check the case where two close to antipodal quaternions were
55  // blended resulting in a nearly zero result which can happen,
56  // for example, if t is close to 0.5. In this case it is not safe
57  // to project back onto the sphere.
58  //
59  double lengthSquared = qtemp.dot(qtemp);
60 
61  if (lengthSquared <= tolerance * tolerance) {
62  qtemp = (t < 0.5) ? q1 : q2;
63  } else {
64  qtemp *= 1.0 / sqrt(lengthSquared);
65  }
66  return qtemp;
67  } else {
68 
69  T sine = 1.0 / sineAngle;
70  T a = sin((1.0 - t) * angle) * sine;
71  T b = sin(t * angle) * sine;
72  return Quat<T>(a * q1[0] + b * q2[0], a * q1[1] + b * q2[1],
73  a * q1[2] + b * q2[2], a * q1[3] + b * q2[3]);
74  }
75 
76 }
77 
78 template<typename T>
79 class Quat
80 {
81 public:
82  using value_type = T;
83  using ValueType = T;
84  static const int size = 4;
85 
86  /// Trivial constructor, the quaternion is NOT initialized
87  /// @note destructor, copy constructor, assignment operator and
88  /// move constructor are left to be defined by the compiler (default)
89  Quat() = default;
90 
91  /// Constructor with four arguments, e.g. Quatf q(1,2,3,4);
92  Quat(T x, T y, T z, T w)
93  {
94  mm[0] = x;
95  mm[1] = y;
96  mm[2] = z;
97  mm[3] = w;
98 
99  }
100 
101  /// Constructor with array argument, e.g. float a[4]; Quatf q(a);
102  Quat(T *a)
103  {
104  mm[0] = a[0];
105  mm[1] = a[1];
106  mm[2] = a[2];
107  mm[3] = a[3];
108 
109  }
110 
111  /// Constructor given rotation as axis and angle, the axis must be
112  /// unit vector
113  Quat(const Vec3<T> &axis, T angle)
114  {
115  OPENVDB_ASSERT(isApproxEqual(axis.length(), T(1)));
116 
117  T s = T(sin(angle*T(0.5)));
118 
119  mm[0] = axis.x() * s;
120  mm[1] = axis.y() * s;
121  mm[2] = axis.z() * s;
122 
123  mm[3] = T(cos(angle*T(0.5)));
124 
125  }
126 
127  /// Constructor given rotation as axis and angle
129  {
130  T s = T(sin(angle*T(0.5)));
131 
132  mm[0] = (axis==math::X_AXIS) * s;
133  mm[1] = (axis==math::Y_AXIS) * s;
134  mm[2] = (axis==math::Z_AXIS) * s;
135 
136  mm[3] = T(cos(angle*T(0.5)));
137  }
138 
139  /// Constructor given a rotation matrix
140  template<typename T1>
141  Quat(const Mat3<T1> &rot) {
142 
143  // verify that the matrix is really a rotation
144  if(!isUnitary(rot)) { // unitary is reflection or rotation
146  "A non-rotation matrix can not be used to construct a quaternion");
147  }
148  if (!isApproxEqual(rot.det(), T1(1))) { // rule out reflection
150  "A reflection matrix can not be used to construct a quaternion");
151  }
152 
153  T trace(rot.trace());
154  if (trace > 0) {
155 
156  T q_w = 0.5 * std::sqrt(trace+1);
157  T factor = 0.25 / q_w;
158 
159  mm[0] = factor * (rot(1,2) - rot(2,1));
160  mm[1] = factor * (rot(2,0) - rot(0,2));
161  mm[2] = factor * (rot(0,1) - rot(1,0));
162  mm[3] = q_w;
163  } else if (rot(0,0) > rot(1,1) && rot(0,0) > rot(2,2)) {
164 
165  T q_x = 0.5 * sqrt(rot(0,0)- rot(1,1)-rot(2,2)+1);
166  T factor = 0.25 / q_x;
167 
168  mm[0] = q_x;
169  mm[1] = factor * (rot(0,1) + rot(1,0));
170  mm[2] = factor * (rot(2,0) + rot(0,2));
171  mm[3] = factor * (rot(1,2) - rot(2,1));
172  } else if (rot(1,1) > rot(2,2)) {
173 
174  T q_y = 0.5 * sqrt(rot(1,1)-rot(0,0)-rot(2,2)+1);
175  T factor = 0.25 / q_y;
176 
177  mm[0] = factor * (rot(0,1) + rot(1,0));
178  mm[1] = q_y;
179  mm[2] = factor * (rot(1,2) + rot(2,1));
180  mm[3] = factor * (rot(2,0) - rot(0,2));
181  } else {
182 
183  T q_z = 0.5 * sqrt(rot(2,2)-rot(0,0)-rot(1,1)+1);
184  T factor = 0.25 / q_z;
185 
186  mm[0] = factor * (rot(2,0) + rot(0,2));
187  mm[1] = factor * (rot(1,2) + rot(2,1));
188  mm[2] = q_z;
189  mm[3] = factor * (rot(0,1) - rot(1,0));
190  }
191  }
192 
193  /// Reference to the component, e.g. q.x() = 4.5f;
194  T& x() { return mm[0]; }
195  T& y() { return mm[1]; }
196  T& z() { return mm[2]; }
197  T& w() { return mm[3]; }
198 
199  /// Get the component, e.g. float f = q.w();
200  T x() const { return mm[0]; }
201  T y() const { return mm[1]; }
202  T z() const { return mm[2]; }
203  T w() const { return mm[3]; }
204 
205  // Number of elements
206  static unsigned numElements() { return 4; }
207 
208  /// Array style reference to the components, e.g. q[3] = 1.34f;
209  T& operator[](int i) { return mm[i]; }
210 
211  /// Array style constant reference to the components, e.g. float f = q[1];
212  T operator[](int i) const { return mm[i]; }
213 
214  /// Cast to T*
215  operator T*() { return mm; }
216  operator const T*() const { return mm; }
217 
218  /// Alternative indexed reference to the elements
219  T& operator()(int i) { return mm[i]; }
220 
221  /// Alternative indexed constant reference to the elements,
222  T operator()(int i) const { return mm[i]; }
223 
224  /// Return angle of rotation
225  T angle() const
226  {
227  T sqrLength = mm[0]*mm[0] + mm[1]*mm[1] + mm[2]*mm[2];
228 
229  if ( sqrLength > 1.0e-8 ) {
230 
231  return T(T(2.0) * acos(mm[3]));
232 
233  } else {
234 
235  return T(0.0);
236  }
237  }
238 
239  /// Return axis of rotation
240  Vec3<T> axis() const
241  {
242  T sqrLength = mm[0]*mm[0] + mm[1]*mm[1] + mm[2]*mm[2];
243 
244  if ( sqrLength > 1.0e-8 ) {
245 
246  T invLength = T(T(1)/sqrt(sqrLength));
247 
248  return Vec3<T>( mm[0]*invLength, mm[1]*invLength, mm[2]*invLength );
249  } else {
250 
251  return Vec3<T>(1,0,0);
252  }
253  }
254 
255 
256  /// "this" quaternion gets initialized to [x, y, z, w]
257  Quat& init(T x, T y, T z, T w)
258  {
259  mm[0] = x; mm[1] = y; mm[2] = z; mm[3] = w;
260  return *this;
261  }
262 
263  /// "this" quaternion gets initialized to identity, same as setIdentity()
264  Quat& init() { return setIdentity(); }
265 
266  /// Set "this" quaternion to rotation specified by axis and angle,
267  /// the axis must be unit vector
268  Quat& setAxisAngle(const Vec3<T>& axis, T angle)
269  {
270 
271  T s = T(sin(angle*T(0.5)));
272 
273  mm[0] = axis.x() * s;
274  mm[1] = axis.y() * s;
275  mm[2] = axis.z() * s;
276 
277  mm[3] = T(cos(angle*T(0.5)));
278 
279  return *this;
280  } // axisAngleTest
281 
282  /// Set "this" vector to zero
284  {
285  mm[0] = mm[1] = mm[2] = mm[3] = 0;
286  return *this;
287  }
288 
289  /// Set "this" vector to identity
291  {
292  mm[0] = mm[1] = mm[2] = 0;
293  mm[3] = 1;
294  return *this;
295  }
296 
297  /// Returns vector of x,y,z rotational components
298  Vec3<T> eulerAngles(RotationOrder rotationOrder) const
299  { return math::eulerAngles(Mat3<T>(*this), rotationOrder); }
300 
301  /// Equality operator, does exact floating point comparisons
302  bool operator==(const Quat &q) const
303  {
304  return (isExactlyEqual(mm[0],q.mm[0]) &&
305  isExactlyEqual(mm[1],q.mm[1]) &&
306  isExactlyEqual(mm[2],q.mm[2]) &&
307  isExactlyEqual(mm[3],q.mm[3]) );
308  }
309 
310  /// Test if "this" is equivalent to q with tolerance of eps value
311  bool eq(const Quat &q, T eps=1.0e-7) const
312  {
313  return isApproxEqual(mm[0],q.mm[0],eps) && isApproxEqual(mm[1],q.mm[1],eps) &&
314  isApproxEqual(mm[2],q.mm[2],eps) && isApproxEqual(mm[3],q.mm[3],eps) ;
315  } // trivial
316 
317  /// Add quaternion q to "this" quaternion, e.g. q += q1;
318  Quat& operator+=(const Quat &q)
319  {
320  mm[0] += q.mm[0];
321  mm[1] += q.mm[1];
322  mm[2] += q.mm[2];
323  mm[3] += q.mm[3];
324 
325  return *this;
326  }
327 
328  /// Subtract quaternion q from "this" quaternion, e.g. q -= q1;
329  Quat& operator-=(const Quat &q)
330  {
331  mm[0] -= q.mm[0];
332  mm[1] -= q.mm[1];
333  mm[2] -= q.mm[2];
334  mm[3] -= q.mm[3];
335 
336  return *this;
337  }
338 
339  /// Scale "this" quaternion by scalar, e.g. q *= scalar;
340  Quat& operator*=(T scalar)
341  {
342  mm[0] *= scalar;
343  mm[1] *= scalar;
344  mm[2] *= scalar;
345  mm[3] *= scalar;
346 
347  return *this;
348  }
349 
350  /// Return (this+q), e.g. q = q1 + q2;
351  Quat operator+(const Quat &q) const
352  {
353  return Quat<T>(mm[0]+q.mm[0], mm[1]+q.mm[1], mm[2]+q.mm[2], mm[3]+q.mm[3]);
354  }
355 
356  /// Return (this-q), e.g. q = q1 - q2;
357  Quat operator-(const Quat &q) const
358  {
359  return Quat<T>(mm[0]-q.mm[0], mm[1]-q.mm[1], mm[2]-q.mm[2], mm[3]-q.mm[3]);
360  }
361 
362  /// Return (this*q), e.g. q = q1 * q2;
363  Quat operator*(const Quat &q) const
364  {
365  Quat<T> prod;
366 
367  prod.mm[0] = mm[3]*q.mm[0] + mm[0]*q.mm[3] + mm[1]*q.mm[2] - mm[2]*q.mm[1];
368  prod.mm[1] = mm[3]*q.mm[1] + mm[1]*q.mm[3] + mm[2]*q.mm[0] - mm[0]*q.mm[2];
369  prod.mm[2] = mm[3]*q.mm[2] + mm[2]*q.mm[3] + mm[0]*q.mm[1] - mm[1]*q.mm[0];
370  prod.mm[3] = mm[3]*q.mm[3] - mm[0]*q.mm[0] - mm[1]*q.mm[1] - mm[2]*q.mm[2];
371 
372  return prod;
373 
374  }
375 
376  /// Assigns this to (this*q), e.g. q *= q1;
377  Quat operator*=(const Quat &q)
378  {
379  *this = *this * q;
380  return *this;
381  }
382 
383  /// Return (this*scalar), e.g. q = q1 * scalar;
384  Quat operator*(T scalar) const
385  {
386  return Quat<T>(mm[0]*scalar, mm[1]*scalar, mm[2]*scalar, mm[3]*scalar);
387  }
388 
389  /// Return (this/scalar), e.g. q = q1 / scalar;
390  Quat operator/(T scalar) const
391  {
392  return Quat<T>(mm[0]/scalar, mm[1]/scalar, mm[2]/scalar, mm[3]/scalar);
393  }
394 
395  /// Negation operator, e.g. q = -q;
396  Quat operator-() const
397  { return Quat<T>(-mm[0], -mm[1], -mm[2], -mm[3]); }
398 
399  /// this = q1 + q2
400  /// "this", q1 and q2 need not be distinct objects, e.g. q.add(q1,q);
401  Quat& add(const Quat &q1, const Quat &q2)
402  {
403  mm[0] = q1.mm[0] + q2.mm[0];
404  mm[1] = q1.mm[1] + q2.mm[1];
405  mm[2] = q1.mm[2] + q2.mm[2];
406  mm[3] = q1.mm[3] + q2.mm[3];
407 
408  return *this;
409  }
410 
411  /// this = q1 - q2
412  /// "this", q1 and q2 need not be distinct objects, e.g. q.sub(q1,q);
413  Quat& sub(const Quat &q1, const Quat &q2)
414  {
415  mm[0] = q1.mm[0] - q2.mm[0];
416  mm[1] = q1.mm[1] - q2.mm[1];
417  mm[2] = q1.mm[2] - q2.mm[2];
418  mm[3] = q1.mm[3] - q2.mm[3];
419 
420  return *this;
421  }
422 
423  /// this = q1 * q2
424  /// q1 and q2 must be distinct objects than "this", e.g. q.mult(q1,q2);
425  Quat& mult(const Quat &q1, const Quat &q2)
426  {
427  mm[0] = q1.mm[3]*q2.mm[0] + q1.mm[0]*q2.mm[3] +
428  q1.mm[1]*q2.mm[2] - q1.mm[2]*q2.mm[1];
429  mm[1] = q1.mm[3]*q2.mm[1] + q1.mm[1]*q2.mm[3] +
430  q1.mm[2]*q2.mm[0] - q1.mm[0]*q2.mm[2];
431  mm[2] = q1.mm[3]*q2.mm[2] + q1.mm[2]*q2.mm[3] +
432  q1.mm[0]*q2.mm[1] - q1.mm[1]*q2.mm[0];
433  mm[3] = q1.mm[3]*q2.mm[3] - q1.mm[0]*q2.mm[0] -
434  q1.mm[1]*q2.mm[1] - q1.mm[2]*q2.mm[2];
435 
436  return *this;
437  }
438 
439  /// this = scalar*q, q need not be distinct object than "this",
440  /// e.g. q.scale(1.5,q1);
441  Quat& scale(T scale, const Quat &q)
442  {
443  mm[0] = scale * q.mm[0];
444  mm[1] = scale * q.mm[1];
445  mm[2] = scale * q.mm[2];
446  mm[3] = scale * q.mm[3];
447 
448  return *this;
449  }
450 
451  /// Dot product
452  T dot(const Quat &q) const
453  {
454  return (mm[0]*q.mm[0] + mm[1]*q.mm[1] + mm[2]*q.mm[2] + mm[3]*q.mm[3]);
455  }
456 
457  /// Return the quaternion rate corrsponding to the angular velocity omega
458  /// and "this" current rotation
459  Quat derivative(const Vec3<T>& omega) const
460  {
461  return Quat<T>( +w()*omega.x() -z()*omega.y() +y()*omega.z() ,
462  +z()*omega.x() +w()*omega.y() -x()*omega.z() ,
463  -y()*omega.x() +x()*omega.y() +w()*omega.z() ,
464  -x()*omega.x() -y()*omega.y() -z()*omega.z() );
465  }
466 
467  /// this = normalized this
468  bool normalize(T eps = T(1.0e-8))
469  {
470  T d = T(sqrt(mm[0]*mm[0] + mm[1]*mm[1] + mm[2]*mm[2] + mm[3]*mm[3]));
471  if( isApproxEqual(d, T(0.0), eps) ) return false;
472  *this *= ( T(1)/d );
473  return true;
474  }
475 
476  /// this = normalized this
477  Quat unit() const
478  {
479  T d = sqrt(mm[0]*mm[0] + mm[1]*mm[1] + mm[2]*mm[2] + mm[3]*mm[3]);
480  if( isExactlyEqual(d , T(0.0) ) )
482  "Normalizing degenerate quaternion");
483  return *this / d;
484  }
485 
486  /// returns inverse of this
487  Quat inverse(T tolerance = T(0)) const
488  {
489  T d = mm[0]*mm[0] + mm[1]*mm[1] + mm[2]*mm[2] + mm[3]*mm[3];
490  if( isApproxEqual(d, T(0.0), tolerance) )
492  "Cannot invert degenerate quaternion");
493  Quat result = *this/-d;
494  result.mm[3] = -result.mm[3];
495  return result;
496  }
497 
498 
499  /// Return the conjugate of "this", same as invert without
500  /// unit quaternion test
501  Quat conjugate() const
502  {
503  return Quat<T>(-mm[0], -mm[1], -mm[2], mm[3]);
504  }
505 
506  /// Return rotated vector by "this" quaternion
507  Vec3<T> rotateVector(const Vec3<T> &v) const
508  {
509  Mat3<T> m(*this);
510  return m.transform(v);
511  }
512 
513  /// Predefined constants, e.g. Quat q = Quat::identity();
514  static Quat zero() { return Quat<T>(0,0,0,0); }
515  static Quat identity() { return Quat<T>(0,0,0,1); }
516 
517  /// @return string representation of Classname
518  std::string str() const
519  {
520  std::ostringstream buffer;
521 
522  buffer << "[";
523 
524  // For each column
525  for (unsigned j(0); j < 4; j++) {
526  if (j) buffer << ", ";
527  buffer << mm[j];
528  }
529 
530  buffer << "]";
531 
532  return buffer.str();
533  }
534 
535  /// Output to the stream, e.g. std::cout << q << std::endl;
536  friend std::ostream& operator<<(std::ostream &stream, const Quat &q)
537  {
538  stream << q.str();
539  return stream;
540  }
541 
542  friend Quat slerp<>(const Quat &q1, const Quat &q2, T t, T tolerance);
543 
544  void write(std::ostream& os) const { os.write(static_cast<char*>(&mm), sizeof(T) * 4); }
545  void read(std::istream& is) { is.read(static_cast<char*>(&mm), sizeof(T) * 4); }
546 
547 protected:
548  T mm[4];
549 };
550 
551 /// Multiply each element of the given quaternion by @a scalar and return the result.
552 template <typename S, typename T>
553 Quat<T> operator*(S scalar, const Quat<T> &q) { return q*scalar; }
554 
555 
556 /// @brief Interpolate between m1 and m2.
557 /// Converts to quaternion form and uses slerp
558 /// m1 and m2 must be rotation matrices!
559 template <typename T, typename T0>
560 Mat3<T> slerp(const Mat3<T0> &m1, const Mat3<T0> &m2, T t)
561 {
562  using MatType = Mat3<T>;
563 
564  Quat<T> q1(m1);
565  Quat<T> q2(m2);
566 
567  if (q1.dot(q2) < 0) q2 *= -1;
568 
569  Quat<T> qslerp = slerp<T>(q1, q2, static_cast<T>(t));
570  MatType m = rotation<MatType>(qslerp);
571  return m;
572 }
573 
574 
575 
576 /// Interpolate between m1 and m4 by converting m1 ... m4 into
577 /// quaternions and treating them as control points of a Bezier
578 /// curve using slerp in place of lerp in the De Castlejeau evaluation
579 /// algorithm. Just like a cubic Bezier curve, this will interpolate
580 /// m1 at t = 0 and m4 at t = 1 but in general will not pass through
581 /// m2 and m3. Unlike a standard Bezier curve this curve will not have
582 /// the convex hull property.
583 /// m1 ... m4 must be rotation matrices!
584 template <typename T, typename T0>
585 Mat3<T> bezLerp(const Mat3<T0> &m1, const Mat3<T0> &m2,
586  const Mat3<T0> &m3, const Mat3<T0> &m4,
587  T t)
588 {
589  Mat3<T> m00, m01, m02, m10, m11;
590 
591  m00 = slerp(m1, m2, t);
592  m01 = slerp(m2, m3, t);
593  m02 = slerp(m3, m4, t);
594 
595  m10 = slerp(m00, m01, t);
596  m11 = slerp(m01, m02, t);
597 
598  return slerp(m10, m11, t);
599 }
600 
603 
606 
607 } // namespace math
608 
609 
610 template<> inline math::Quats zeroVal<math::Quats >() { return math::Quats::zero(); }
611 template<> inline math::Quatd zeroVal<math::Quatd >() { return math::Quatd::zero(); }
612 
613 } // namespace OPENVDB_VERSION_NAME
614 } // namespace openvdb
615 
616 #endif //OPENVDB_MATH_QUAT_H_HAS_BEEN_INCLUDED
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:443
T & y()
Definition: Vec3.h:87
Quat & add(const Quat &q1, const Quat &q2)
Definition: Quat.h:401
Quat(const Mat3< T1 > &rot)
Constructor given a rotation matrix.
Definition: Quat.h:141
static Quat identity()
Definition: Quat.h:515
Quat & operator-=(const Quat &q)
Subtract quaternion q from "this" quaternion, e.g. q -= q1;.
Definition: Quat.h:329
Quat conjugate() const
Definition: Quat.h:501
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
T & x()
Reference to the component, e.g. q.x() = 4.5f;.
Definition: Quat.h:194
T & operator()(int i)
Alternative indexed reference to the elements.
Definition: Quat.h:219
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
static Quat zero()
Predefined constants, e.g. Quat q = Quat::identity();.
Definition: Quat.h:514
RotationOrder
Definition: Math.h:908
bool operator==(const Quat &q) const
Equality operator, does exact floating point comparisons.
Definition: Quat.h:302
void write(std::ostream &os) const
Definition: Quat.h:544
Vec3< T > axis() const
Return axis of rotation.
Definition: Quat.h:240
Definition: Math.h:903
3x3 matrix class.
Definition: Mat3.h:28
Quat derivative(const Vec3< T > &omega) const
Definition: Quat.h:459
bool eq(const Quat &q, T eps=1.0e-7) const
Test if "this" is equivalent to q with tolerance of eps value.
Definition: Quat.h:311
Quat & mult(const Quat &q1, const Quat &q2)
Definition: Quat.h:425
Vec3< T0 > transform(const Vec3< T0 > &v) const
Definition: Mat3.h:505
bool isApproxEqual(const Type &a, const Type &b, const Type &tolerance)
Return true if a is equal to b to within the given tolerance.
Definition: Math.h:406
Definition: Math.h:904
T & z()
Definition: Vec3.h:88
friend std::ostream & operator<<(std::ostream &stream, const Quat &q)
Output to the stream, e.g. std::cout << q << std::endl;.
Definition: Quat.h:536
Quat & sub(const Quat &q1, const Quat &q2)
Definition: Quat.h:413
Definition: Mat.h:164
Quat unit() const
this = normalized this
Definition: Quat.h:477
Quat operator*(const Quat &q) const
Return (this*q), e.g. q = q1 * q2;.
Definition: Quat.h:363
T & y()
Definition: Quat.h:195
T & z()
Definition: Quat.h:196
Quat(T *a)
Constructor with array argument, e.g. float a[4]; Quatf q(a);.
Definition: Quat.h:102
T angle() const
Return angle of rotation.
Definition: Quat.h:225
Quat(T x, T y, T z, T w)
Constructor with four arguments, e.g. Quatf q(1,2,3,4);.
Definition: Quat.h:92
Quat & operator+=(const Quat &q)
Add quaternion q to "this" quaternion, e.g. q += q1;.
Definition: Quat.h:318
T value_type
Definition: Quat.h:82
Quat operator*(T scalar) const
Return (this*scalar), e.g. q = q1 * scalar;.
Definition: Quat.h:384
Quat & setIdentity()
Set "this" vector to identity.
Definition: Quat.h:290
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:86
Quat & operator*=(T scalar)
Scale "this" quaternion by scalar, e.g. q *= scalar;.
Definition: Quat.h:340
T operator[](int i) const
Array style constant reference to the components, e.g. float f = q[1];.
Definition: Quat.h:212
T mm[4]
Definition: Quat.h:548
Quat & init()
"this" quaternion gets initialized to identity, same as setIdentity()
Definition: Quat.h:264
T & w()
Definition: Quat.h:197
#define OPENVDB_ASSERT(X)
Definition: Assert.h:41
Vec3< T > rotateVector(const Vec3< T > &v) const
Return rotated vector by "this" quaternion.
Definition: Quat.h:507
Axis
Definition: Math.h:901
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:615
Quat(math::Axis axis, T angle)
Constructor given rotation as axis and angle.
Definition: Quat.h:128
T ValueType
Definition: Quat.h:83
T det() const
Determinant of matrix.
Definition: Mat3.h:479
T x() const
Get the component, e.g. float f = q.w();.
Definition: Quat.h:200
Quat(const Vec3< T > &axis, T angle)
Definition: Quat.h:113
Definition: Exceptions.h:13
Quat operator+(const Quat &q) const
Return (this+q), e.g. q = q1 + q2;.
Definition: Quat.h:351
Quat & init(T x, T y, T z, T w)
"this" quaternion gets initialized to [x, y, z, w]
Definition: Quat.h:257
Quat< T > operator*(S scalar, const Quat< T > &q)
Multiply each element of the given quaternion by scalar and return the result.
Definition: Quat.h:553
constexpr T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:70
T angle(const Vec2< T > &v1, const Vec2< T > &v2)
Definition: Vec2.h:446
Quat operator/(T scalar) const
Return (this/scalar), e.g. q = q1 / scalar;.
Definition: Quat.h:390
Quat & setZero()
Set "this" vector to zero.
Definition: Quat.h:283
Quat operator-(const Quat &q) const
Return (this-q), e.g. q = q1 - q2;.
Definition: Quat.h:357
T trace() const
Trace of matrix.
Definition: Mat3.h:488
std::string str() const
Definition: Quat.h:518
Definition: Mat.h:165
bool isUnitary(const MatType &m)
Determine if a matrix is unitary (i.e., rotation or reflection).
Definition: Mat.h:889
Mat3< T > bezLerp(const Mat3< T0 > &m1, const Mat3< T0 > &m2, const Mat3< T0 > &m3, const Mat3< T0 > &m4, T t)
Definition: Quat.h:585
static unsigned numElements()
Definition: Quat.h:206
Mat3< T > slerp(const Mat3< T0 > &m1, const Mat3< T0 > &m2, T t)
Interpolate between m1 and m2. Converts to quaternion form and uses slerp m1 and m2 must be rotation ...
Definition: Quat.h:560
bool normalize(T eps=T(1.0e-8))
this = normalized this
Definition: Quat.h:468
T z() const
Definition: Quat.h:202
T w() const
Definition: Quat.h:203
Definition: Math.h:902
Quat & setAxisAngle(const Vec3< T > &axis, T angle)
Definition: Quat.h:268
Quat< float > Quats
Definition: Quat.h:601
void read(std::istream &is)
Definition: Quat.h:545
Definition: Exceptions.h:56
Vec3< T > eulerAngles(RotationOrder rotationOrder) const
Returns vector of x,y,z rotational components.
Definition: Quat.h:298
T & operator[](int i)
Array style reference to the components, e.g. q[3] = 1.34f;.
Definition: Quat.h:209
T operator()(int i) const
Alternative indexed constant reference to the elements,.
Definition: Quat.h:222
T dot(const Quat &q) const
Dot product.
Definition: Quat.h:452
Quat inverse(T tolerance=T(0)) const
returns inverse of this
Definition: Quat.h:487
T length() const
Length of the vector.
Definition: Vec3.h:201
Quat & scale(T scale, const Quat &q)
Definition: Quat.h:441
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
Vec3< typename MatType::value_type > eulerAngles(const MatType &mat, RotationOrder rotationOrder, typename MatType::value_type eps=static_cast< typename MatType::value_type >(1.0e-8))
Return the Euler angles composing the given rotation matrix.
Definition: Mat.h:333
T y() const
Definition: Quat.h:201
Quat operator*=(const Quat &q)
Assigns this to (this*q), e.g. q *= q1;.
Definition: Quat.h:377
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218
Quat operator-() const
Negation operator, e.g. q = -q;.
Definition: Quat.h:396
#define OPENVDB_IS_POD(Type)
Definition: Math.h:56