HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
quaternion.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_BASE_GF_QUATERNION_H
8 #define PXR_BASE_GF_QUATERNION_H
9 
10 /// \file gf/quaternion.h
11 /// \ingroup group_gf_LinearAlgebra
12 
13 #include "pxr/pxr.h"
14 #include "pxr/base/gf/api.h"
15 #include "pxr/base/gf/vec3d.h"
16 #include "pxr/base/tf/hash.h"
17 
18 #include <iosfwd>
19 
21 
22 /// \class GfQuaternion
23 /// \ingroup group_gf_LinearAlgebra
24 ///
25 /// Basic type: complex number with scalar real part and vector imaginary
26 /// part.
27 ///
28 /// This class represents a generalized complex number that has a scalar real
29 /// part and a vector of three imaginary values. Quaternions are used by the
30 /// \c GfRotation class to represent arbitrary-axis rotations.
31 ///
33 {
34  public:
35 
36  /// The default constructor leaves the quaternion undefined.
38  }
39 
40  /// This constructor initializes the real part to the argument and
41  /// the imaginary parts to zero.
42  ///
43  /// Since quaternions typically need to be normalized, the only reasonable
44  /// values for \p realVal are -1, 0, or 1. Other values are legal but are
45  /// likely to be meaningless.
46  explicit GfQuaternion(int realVal)
47  : _real(realVal), _imaginary(0)
48  {
49  }
50 
51  /// This constructor initializes the real and imaginary parts.
52  GfQuaternion(double real, const GfVec3d &imaginary)
53  : _real(real), _imaginary(imaginary) {
54  }
55 
56  /// Sets the real part of the quaternion.
57  void SetReal(double real) {
58  _real = real;
59  }
60 
61  /// Sets the imaginary part of the quaternion.
62  void SetImaginary(const GfVec3d &imaginary) {
63  _imaginary = imaginary;
64  }
65 
66  /// Returns the real part of the quaternion.
67  double GetReal() const {
68  return _real;
69  }
70 
71  /// Returns the imaginary part of the quaternion.
72  const GfVec3d & GetImaginary() const {
73  return _imaginary;
74  }
75 
76  /// Returns the zero quaternion, which has a real part of 0 and
77  /// an imaginary part of (0,0,0).
78  static GfQuaternion GetZero() {
79  return GfQuaternion(0.0, GfVec3d(0.0, 0.0, 0.0));
80  }
81 
82  /// Returns the identity quaternion, which has a real part of 1 and
83  /// an imaginary part of (0,0,0).
85  return GfQuaternion(1.0, GfVec3d(0.0, 0.0, 0.0));
86  }
87 
88  /// Returns geometric length of this quaternion.
89  GF_API
90  double GetLength() const;
91 
92  /// Returns a normalized (unit-length) version of this quaternion.
93  /// direction as this. If the length of this quaternion is smaller than \p
94  /// eps, this returns the identity quaternion.
95  GF_API
97 
98  /// Normalizes this quaternion in place to unit length, returning the
99  /// length before normalization. If the length of this quaternion is
100  /// smaller than \p eps, this sets the quaternion to identity.
101  GF_API
102  double Normalize(double eps = GF_MIN_VECTOR_LENGTH);
103 
104  /// Returns the inverse of this quaternion.
105  GF_API
106  GfQuaternion GetInverse() const;
107 
108  /// Hash.
109  friend inline size_t hash_value(const GfQuaternion &q) {
110  return TfHash::Combine(q.GetReal(), q.GetImaginary());
111  }
112 
113  /// Component-wise quaternion equality test. The real and imaginary parts
114  /// must match exactly for quaternions to be considered equal.
115  bool operator ==(const GfQuaternion &q) const {
116  return (GetReal() == q.GetReal() &&
117  GetImaginary() == q.GetImaginary());
118  }
119 
120  /// Component-wise quaternion inequality test. The real and imaginary
121  /// parts must match exactly for quaternions to be considered equal.
122  bool operator !=(const GfQuaternion &q) const {
123  return ! (*this == q);
124  }
125 
126  /// Post-multiplies quaternion \p q into this quaternion.
127  GF_API
129 
130  /// Scales this quaternion by \p s.
131  GF_API
132  GfQuaternion & operator *=(double s);
133 
134  /// Scales this quaternion by 1 / \p s.
136  return (*this) *= 1.0 / s;
137  }
138 
139  /// Component-wise unary sum operator.
141  _real += q._real;
142  _imaginary += q._imaginary;
143  return *this;
144  }
145 
146  /// Component-wise unary difference operator.
148  _real -= q._real;
149  _imaginary -= q._imaginary;
150  return *this;
151  }
152 
153  /// Component-wise binary sum operator.
155  const GfQuaternion &q2) {
156  GfQuaternion qt = q1;
157  return qt += q2;
158  }
159 
160  /// Component-wise binary difference operator.
162  const GfQuaternion &q2) {
163  GfQuaternion qt = q1;
164  return qt -= q2;
165  }
166 
167  /// Returns the product of quaternions \p q1 and \p q2.
169  const GfQuaternion &q2) {
170  GfQuaternion qt = q1;
171  return qt *= q2;
172  }
173 
174  /// Returns the product of quaternion \p q and scalar \p s.
175  friend GfQuaternion operator *(const GfQuaternion &q, double s) {
176  GfQuaternion qt = q;
177  return qt *= s;
178  }
179 
180  /// Returns the product of quaternion \p q and scalar \p s.
181  friend GfQuaternion operator *(double s, const GfQuaternion &q) {
182  GfQuaternion qt = q;
183  return qt *= s;
184  }
185 
186  /// Returns the product of quaternion \p q and scalar 1 / \p s.
187  friend GfQuaternion operator /(const GfQuaternion &q, double s) {
188  GfQuaternion qt = q;
189  return qt /= s;
190  }
191 
192  /// Spherically interpolate between \p q0 and \p q1.
193  ///
194  /// If the interpolant \p alpha
195  /// is zero, then the result is \p q0, while \p alpha of one yields
196  /// \p q1.
197  GF_API
198  friend GfQuaternion GfSlerp(double alpha,
199  const GfQuaternion& q0,
200  const GfQuaternion& q1);
201 
202  // TODO Remove this legacy alias/overload.
203  friend GF_API GfQuaternion GfSlerp(const GfQuaternion& q0,
204  const GfQuaternion& q1,
205  double alpha);
206 
207  private:
208  /// Real part
209  double _real;
210  /// Imaginary part
211  GfVec3d _imaginary;
212 
213  /// Returns the square of the length
214  double _GetLengthSquared() const {
215  return (_real * _real + GfDot(_imaginary, _imaginary));
216  }
217 };
218 
219 // Friend functions must be declared.
220 GF_API GfQuaternion GfSlerp(double alpha, const GfQuaternion& q0, const GfQuaternion& q1);
221 GF_API GfQuaternion GfSlerp(const GfQuaternion& q0, const GfQuaternion& q1, double alpha);
222 
223 /// Output a GfQuaternion using the format (r + (x, y, z)).
224 /// \ingroup group_gf_DebuggingOutput
225 GF_API std::ostream& operator<<(std::ostream& out, const GfQuaternion& q);
226 
227 
228 /// Returns the dot (inner) product of two quaternions.
229 inline double
230 GfDot(const GfQuaternion &q1, const GfQuaternion &q2) {
231  return (q1.GetReal() * q2.GetReal()) + GfDot(q1.GetImaginary(), q2.GetImaginary());
232 }
233 
235 
236 #endif // PXR_BASE_GF_QUATERNION_H
GfQuaternion & operator/=(double s)
Scales this quaternion by 1 / s.
Definition: quaternion.h:135
GF_API GfQuaternion & operator*=(const GfQuaternion &q)
Post-multiplies quaternion q into this quaternion.
void SetReal(double real)
Sets the real part of the quaternion.
Definition: quaternion.h:57
friend size_t hash_value(const GfQuaternion &q)
Hash.
Definition: quaternion.h:109
GF_API GfQuaternion GfSlerp(double alpha, const GfQuaternion &q0, const GfQuaternion &q1)
GF_API GfQuaternion GetNormalized(double eps=GF_MIN_VECTOR_LENGTH) const
GfQuaternion()
The default constructor leaves the quaternion undefined.
Definition: quaternion.h:37
friend GfQuaternion operator+(const GfQuaternion &q1, const GfQuaternion &q2)
Component-wise binary sum operator.
Definition: quaternion.h:154
GF_API friend GfQuaternion GfSlerp(double alpha, const GfQuaternion &q0, const GfQuaternion &q1)
double GetReal() const
Returns the real part of the quaternion.
Definition: quaternion.h:67
GLdouble s
Definition: glad.h:3009
bool operator==(const GfQuaternion &q) const
Definition: quaternion.h:115
GLdouble GLdouble GLdouble q
Definition: glad.h:2445
GF_API GfQuaternion GetInverse() const
Returns the inverse of this quaternion.
GfQuaternion & operator+=(const GfQuaternion &q)
Component-wise unary sum operator.
Definition: quaternion.h:140
GF_API std::ostream & operator<<(std::ostream &out, const GfQuaternion &q)
double GfDot(const GfQuaternion &q1, const GfQuaternion &q2)
Returns the dot (inner) product of two quaternions.
Definition: quaternion.h:230
friend GfQuaternion operator*(const GfQuaternion &q1, const GfQuaternion &q2)
Returns the product of quaternions q1 and q2.
Definition: quaternion.h:168
GLfloat GLfloat GLfloat alpha
Definition: glcorearb.h:112
GfQuaternion(int realVal)
Definition: quaternion.h:46
void SetImaginary(const GfVec3d &imaginary)
Sets the imaginary part of the quaternion.
Definition: quaternion.h:62
static GfQuaternion GetZero()
Definition: quaternion.h:78
friend GfQuaternion operator/(const GfQuaternion &q, double s)
Returns the product of quaternion q and scalar 1 / s.
Definition: quaternion.h:187
GfQuaternion(double real, const GfVec3d &imaginary)
This constructor initializes the real and imaginary parts.
Definition: quaternion.h:52
friend GfQuaternion operator-(const GfQuaternion &q1, const GfQuaternion &q2)
Component-wise binary difference operator.
Definition: quaternion.h:161
GF_API double Normalize(double eps=GF_MIN_VECTOR_LENGTH)
static size_t Combine(Args &&...args)
Produce a hash code by combining the hash codes of several objects.
Definition: hash.h:487
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
static GfQuaternion GetIdentity()
Definition: quaternion.h:84
Definition: vec3d.h:45
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
bool operator!=(const GfQuaternion &q) const
Definition: quaternion.h:122
GfQuaternion & operator-=(const GfQuaternion &q)
Component-wise unary difference operator.
Definition: quaternion.h:147
const GfVec3d & GetImaginary() const
Returns the imaginary part of the quaternion.
Definition: quaternion.h:72
#define GF_MIN_VECTOR_LENGTH
Definition: limits.h:17
GF_API double GetLength() const
Returns geometric length of this quaternion.
#define GF_API
Definition: api.h:23