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 Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_BASE_GF_QUATERNION_H
25 #define PXR_BASE_GF_QUATERNION_H
26 
27 /// \file gf/quaternion.h
28 /// \ingroup group_gf_LinearAlgebra
29 
30 #include "pxr/pxr.h"
31 #include "pxr/base/gf/api.h"
32 #include "pxr/base/gf/vec3d.h"
33 #include "pxr/base/tf/hash.h"
34 
35 #include <iosfwd>
36 
38 
39 /// \class GfQuaternion
40 /// \ingroup group_gf_LinearAlgebra
41 ///
42 /// Basic type: complex number with scalar real part and vector imaginary
43 /// part.
44 ///
45 /// This class represents a generalized complex number that has a scalar real
46 /// part and a vector of three imaginary values. Quaternions are used by the
47 /// \c GfRotation class to represent arbitrary-axis rotations.
48 ///
50 {
51  public:
52 
53  /// The default constructor leaves the quaternion undefined.
55  }
56 
57  /// This constructor initializes the real part to the argument and
58  /// the imaginary parts to zero.
59  ///
60  /// Since quaternions typically need to be normalized, the only reasonable
61  /// values for \p realVal are -1, 0, or 1. Other values are legal but are
62  /// likely to be meaningless.
63  explicit GfQuaternion(int realVal)
64  : _real(realVal), _imaginary(0)
65  {
66  }
67 
68  /// This constructor initializes the real and imaginary parts.
69  GfQuaternion(double real, const GfVec3d &imaginary)
70  : _real(real), _imaginary(imaginary) {
71  }
72 
73  /// Sets the real part of the quaternion.
74  void SetReal(double real) {
75  _real = real;
76  }
77 
78  /// Sets the imaginary part of the quaternion.
79  void SetImaginary(const GfVec3d &imaginary) {
80  _imaginary = imaginary;
81  }
82 
83  /// Returns the real part of the quaternion.
84  double GetReal() const {
85  return _real;
86  }
87 
88  /// Returns the imaginary part of the quaternion.
89  const GfVec3d & GetImaginary() const {
90  return _imaginary;
91  }
92 
93  /// Returns the zero quaternion, which has a real part of 0 and
94  /// an imaginary part of (0,0,0).
95  static GfQuaternion GetZero() {
96  return GfQuaternion(0.0, GfVec3d(0.0, 0.0, 0.0));
97  }
98 
99  /// Returns the identity quaternion, which has a real part of 1 and
100  /// an imaginary part of (0,0,0).
102  return GfQuaternion(1.0, GfVec3d(0.0, 0.0, 0.0));
103  }
104 
105  /// Returns geometric length of this quaternion.
106  GF_API
107  double GetLength() const;
108 
109  /// Returns a normalized (unit-length) version of this quaternion.
110  /// direction as this. If the length of this quaternion is smaller than \p
111  /// eps, this returns the identity quaternion.
112  GF_API
113  GfQuaternion GetNormalized(double eps = GF_MIN_VECTOR_LENGTH) const;
114 
115  /// Normalizes this quaternion in place to unit length, returning the
116  /// length before normalization. If the length of this quaternion is
117  /// smaller than \p eps, this sets the quaternion to identity.
118  GF_API
119  double Normalize(double eps = GF_MIN_VECTOR_LENGTH);
120 
121  /// Returns the inverse of this quaternion.
122  GF_API
123  GfQuaternion GetInverse() const;
124 
125  /// Hash.
126  friend inline size_t hash_value(const GfQuaternion &q) {
127  return TfHash::Combine(q.GetReal(), q.GetImaginary());
128  }
129 
130  /// Component-wise quaternion equality test. The real and imaginary parts
131  /// must match exactly for quaternions to be considered equal.
132  bool operator ==(const GfQuaternion &q) const {
133  return (GetReal() == q.GetReal() &&
134  GetImaginary() == q.GetImaginary());
135  }
136 
137  /// Component-wise quaternion inequality test. The real and imaginary
138  /// parts must match exactly for quaternions to be considered equal.
139  bool operator !=(const GfQuaternion &q) const {
140  return ! (*this == q);
141  }
142 
143  /// Post-multiplies quaternion \p q into this quaternion.
144  GF_API
146 
147  /// Scales this quaternion by \p s.
148  GF_API
149  GfQuaternion & operator *=(double s);
150 
151  /// Scales this quaternion by 1 / \p s.
153  return (*this) *= 1.0 / s;
154  }
155 
156  /// Component-wise unary sum operator.
158  _real += q._real;
159  _imaginary += q._imaginary;
160  return *this;
161  }
162 
163  /// Component-wise unary difference operator.
165  _real -= q._real;
166  _imaginary -= q._imaginary;
167  return *this;
168  }
169 
170  /// Component-wise binary sum operator.
172  const GfQuaternion &q2) {
173  GfQuaternion qt = q1;
174  return qt += q2;
175  }
176 
177  /// Component-wise binary difference operator.
179  const GfQuaternion &q2) {
180  GfQuaternion qt = q1;
181  return qt -= q2;
182  }
183 
184  /// Returns the product of quaternions \p q1 and \p q2.
186  const GfQuaternion &q2) {
187  GfQuaternion qt = q1;
188  return qt *= q2;
189  }
190 
191  /// Returns the product of quaternion \p q and scalar \p s.
192  friend GfQuaternion operator *(const GfQuaternion &q, double s) {
193  GfQuaternion qt = q;
194  return qt *= s;
195  }
196 
197  /// Returns the product of quaternion \p q and scalar \p s.
198  friend GfQuaternion operator *(double s, const GfQuaternion &q) {
199  GfQuaternion qt = q;
200  return qt *= s;
201  }
202 
203  /// Returns the product of quaternion \p q and scalar 1 / \p s.
204  friend GfQuaternion operator /(const GfQuaternion &q, double s) {
205  GfQuaternion qt = q;
206  return qt /= s;
207  }
208 
209  /// Spherically interpolate between \p q0 and \p q1.
210  ///
211  /// If the interpolant \p alpha
212  /// is zero, then the result is \p q0, while \p alpha of one yields
213  /// \p q1.
214  GF_API
215  friend GfQuaternion GfSlerp(double alpha,
216  const GfQuaternion& q0,
217  const GfQuaternion& q1);
218 
219  // TODO Remove this legacy alias/overload.
220  friend GF_API GfQuaternion GfSlerp(const GfQuaternion& q0,
221  const GfQuaternion& q1,
222  double alpha);
223 
224  private:
225  /// Real part
226  double _real;
227  /// Imaginary part
228  GfVec3d _imaginary;
229 
230  /// Returns the square of the length
231  double _GetLengthSquared() const {
232  return (_real * _real + GfDot(_imaginary, _imaginary));
233  }
234 };
235 
236 // Friend functions must be declared.
237 GF_API GfQuaternion GfSlerp(double alpha, const GfQuaternion& q0, const GfQuaternion& q1);
238 GF_API GfQuaternion GfSlerp(const GfQuaternion& q0, const GfQuaternion& q1, double alpha);
239 
240 /// Output a GfQuaternion using the format (r + (x, y, z)).
241 /// \ingroup group_gf_DebuggingOutput
242 GF_API std::ostream& operator<<(std::ostream& out, const GfQuaternion& q);
243 
244 
245 /// Returns the dot (inner) product of two quaternions.
246 inline double
247 GfDot(const GfQuaternion &q1, const GfQuaternion &q2) {
248  return (q1.GetReal() * q2.GetReal()) + GfDot(q1.GetImaginary(), q2.GetImaginary());
249 }
250 
252 
253 #endif // PXR_BASE_GF_QUATERNION_H
GfQuaternion & operator/=(double s)
Scales this quaternion by 1 / s.
Definition: quaternion.h:152
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:74
friend size_t hash_value(const GfQuaternion &q)
Hash.
Definition: quaternion.h:126
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:54
friend GfQuaternion operator+(const GfQuaternion &q1, const GfQuaternion &q2)
Component-wise binary sum operator.
Definition: quaternion.h:171
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:84
GLdouble s
Definition: glad.h:3009
bool operator==(const GfQuaternion &q) const
Definition: quaternion.h:132
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:157
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:247
friend GfQuaternion operator*(const GfQuaternion &q1, const GfQuaternion &q2)
Returns the product of quaternions q1 and q2.
Definition: quaternion.h:185
GLfloat GLfloat GLfloat alpha
Definition: glcorearb.h:112
GfQuaternion(int realVal)
Definition: quaternion.h:63
void SetImaginary(const GfVec3d &imaginary)
Sets the imaginary part of the quaternion.
Definition: quaternion.h:79
static GfQuaternion GetZero()
Definition: quaternion.h:95
friend GfQuaternion operator/(const GfQuaternion &q, double s)
Returns the product of quaternion q and scalar 1 / s.
Definition: quaternion.h:204
GfQuaternion(double real, const GfVec3d &imaginary)
This constructor initializes the real and imaginary parts.
Definition: quaternion.h:69
friend GfQuaternion operator-(const GfQuaternion &q1, const GfQuaternion &q2)
Component-wise binary difference operator.
Definition: quaternion.h:178
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:519
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
static GfQuaternion GetIdentity()
Definition: quaternion.h:101
Definition: vec3d.h:62
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
bool operator!=(const GfQuaternion &q) const
Definition: quaternion.h:139
GfQuaternion & operator-=(const GfQuaternion &q)
Component-wise unary difference operator.
Definition: quaternion.h:164
const GfVec3d & GetImaginary() const
Returns the imaginary part of the quaternion.
Definition: quaternion.h:89
#define GF_MIN_VECTOR_LENGTH
Definition: limits.h:34
GF_API double GetLength() const
Returns geometric length of this quaternion.
#define GF_API
Definition: api.h:40