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