rotation.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_ROTATION_H
25 #define PXR_BASE_GF_ROTATION_H
26 
29 
30 #include "pxr/pxr.h"
31 #include "pxr/base/gf/quaternion.h"
32 #include "pxr/base/gf/quatd.h"
33 #include "pxr/base/gf/matrix4d.h"
34 #include "pxr/base/gf/vec3d.h"
35 #include "pxr/base/gf/vec3f.h"
36 #include "pxr/base/gf/api.h"
37 
38 #include <boost/functional/hash.hpp>
39 
40 #include <iosfwd>
41 
42 PXR_NAMESPACE_OPEN_SCOPE
43 
55 class GfRotation {
56 
57  public:
58 
61  }
62 
65  GfRotation(const GfVec3d &axis, double angle) {
66  SetAxisAngle(axis, angle);
67  }
68 
70  GfRotation(const GfQuaternion &quaternion) {
71  SetQuaternion(quaternion);
72  }
73 
77  GfRotation(const GfQuatd &quat) { SetQuat(quat); }
78 
82  GF_API
83  GfRotation(const GfVec3d &rotateFrom, const GfVec3d &rotateTo) {
84  SetRotateInto(rotateFrom, rotateTo);
85  }
86 
88  GfRotation & SetAxisAngle(const GfVec3d &axis, double angle) {
89  _axis = axis;
90  _angle = angle;
91  if (!GfIsClose(_axis * _axis, 1.0, 1e-10))
92  _axis.Normalize();
93  return *this;
94  }
95 
98  GF_API
99  GfRotation & SetQuat(const GfQuatd &quat);
100 
103  return SetQuat(GfQuatd(quat.GetReal(), quat.GetImaginary()));
104  }
105 
109  GF_API
110  GfRotation & SetRotateInto(const GfVec3d &rotateFrom,
111  const GfVec3d &rotateTo);
112 
116  _axis.Set(1.0, 0.0, 0.0);
117  _angle = 0.0;
118  return *this;
119  }
120 
122  const GfVec3d & GetAxis() const {
123  return _axis;
124  }
125 
127  double GetAngle() const {
128  return _angle;
129  }
130 
133  auto quat = GetQuat();
134  return GfQuaternion(quat.GetReal(), quat.GetImaginary());
135  }
136 
138  GF_API
139  GfQuatd GetQuat() const;
140 
143  return GfRotation(_axis, -_angle);
144  }
145 
148  GF_API
149  GfVec3d Decompose( const GfVec3d &axis0,
150  const GfVec3d &axis1,
151  const GfVec3d &axis2 ) const;
152 
153  // Full-featured method to Decompose a rotation matrix into Cardarian
154  // angles.
155  // Axes have must be normalized. If useHint is specified
156  // then the current values stored within thetaTw, thetaFB, thetaLR,
157  // and thetaSw will be treated as hint and used to help choose
158  // an equivalent rotation that is as close as possible to the hints.
159  //
160  // One can use this routine to generate any combination of the three
161  // angles by passing in nullptr for the angle that is to be omitted.
162  //
163  // Passing in valid pointers for all four angles will decompose into
164  // Tw, FB, and LR but allows Sw to be used for best matching of hint
165  // values. It also allows an swShift value to be passed in as a
166  // Sw that is applied after the rotation matrix to get a best fit rotation
167  // in four angles.
168  //
169  // Angles are in radians.
170  //
171  // Specify \p handedness as -1.0 or 1.0, same as for MultiRotate.
172  //
173  // NOTE:
174  // Geppetto math function Originally brought over to extMover
175  // from //depot/main/tools/src/menv/lib/gpt/util.h [10/16/06]
176  // And moved into GfRotation[12/1/08]. Updated for any
177  // combination of three angles [12/1/11].
178  //
179  GF_API
180  static void DecomposeRotation(const GfMatrix4d &rot,
181  const GfVec3d &TwAxis,
182  const GfVec3d &FBAxis,
183  const GfVec3d &LRAxis,
184  double handedness,
185  double *thetaTw,
186  double *thetaFB,
187  double *thetaLR,
188  double *thetaSw = nullptr,
189  bool useHint=false,
190  const double *swShift=nullptr);
191 
192  // This function projects the vectors \p v1 and \p v2 onto the plane
193  // normal to \p axis, and then returns the rotation about \p axis that
194  // brings \p v1 onto \p v2.
195  GF_API
196  static GfRotation RotateOntoProjected(const GfVec3d &v1,
197  const GfVec3d &v2,
198  const GfVec3d &axis);
199 
209  GF_API
210  static void MatchClosestEulerRotation(
211  double targetTw, double targetFB, double targetLR, double targetSw,
212  double *thetaTw, double *thetaFB, double *thetaLR, double *thetaSw);
213 
215  GF_API
216  GfVec3f TransformDir( const GfVec3f &vec ) const;
217 
219  GF_API
220  GfVec3d TransformDir( const GfVec3d &vec ) const;
221 
223  friend inline size_t hash_value(const GfRotation &r) {
224  size_t h = 0;
225  boost::hash_combine(h, r._axis);
226  boost::hash_combine(h, r._angle);
227  return h;
228  }
229 
234  bool operator ==(const GfRotation &r) const {
235  return (_axis == r._axis &&
236  _angle == r._angle);
237  }
238 
243  bool operator !=(const GfRotation &r) const {
244  return ! (*this == r);
245  }
246 
248  GF_API
249  GfRotation & operator *=(const GfRotation &r);
250 
252  GfRotation & operator *=(double scale) {
253  _angle *= scale;
254  return *this;
255  }
256 
258  GfRotation & operator /=(double scale) {
259  _angle /= scale;
260  return *this;
261  }
262 
264  friend GfRotation operator *(const GfRotation &r1,
265  const GfRotation &r2) {
266  GfRotation r = r1;
267  return r *= r2;
268  }
269 
272  friend GfRotation operator *(const GfRotation &r, double scale) {
273  GfRotation rTmp = r;
274  return rTmp *= scale;
275  }
276 
279  friend GfRotation operator *(double scale, const GfRotation &r) {
280  return (r * scale);
281  }
282 
285  friend GfRotation operator /(const GfRotation &r, double scale) {
286  GfRotation rTmp = r;
287  return rTmp /= scale;
288  }
289 
290  private:
293  GfVec3d _axis;
295  double _angle;
296 };
297 
300 GF_API std::ostream& operator<<(std::ostream&, const GfRotation&);
301 
302 PXR_NAMESPACE_CLOSE_SCOPE
303 
304 #endif // PXR_BASE_GF_ROTATION_H
GF_API GfRotation & operator *=(const GfRotation &r)
Post-multiplies rotation r into this rotation.
GfRotation & operator/=(double scale)
Scales rotation angle by dividing by scale.
Definition: rotation.h:258
bool GfIsClose(double a, double b, double epsilon)
Returns true if a and b are with epsilon of each other.
Definition: math.h:42
friend GfRotation operator *(double scale, const GfRotation &r)
Returns a rotation equivalent to r with its angle multiplied by scale.
Definition: rotation.h:279
friend size_t hash_value(const GfRotation &r)
Hash.
Definition: rotation.h:223
Basic type for a vector of 3 float components.
Definition: vec3f.h:63
GfRotation & SetQuaternion(const GfQuaternion &quat)
Sets the rotation from a quaternion.
Definition: rotation.h:102
GF_API GfRotation & SetRotateInto(const GfVec3d &rotateFrom, const GfVec3d &rotateTo)
Sets the rotation to one that brings the rotateFrom vector to align with rotateTo.
Basic type: complex number with scalar real part and vector imaginary part.
Definition: quaternion.h:50
double GetAngle() const
Returns the rotation angle in degrees.
Definition: rotation.h:127
GfVec3d & Set(double s0, double s1, double s2)
Set all elements with passed arguments.
Definition: vec3d.h:130
bool operator==(const GfRotation &r) const
Component-wise rotation equality test.
Definition: rotation.h:234
Stores a 4x4 matrix of double elements.
Definition: matrix4d.h:88
bool operator !=(const GfRotation &r) const
Component-wise rotation inequality test.
Definition: rotation.h:243
GfRotation(const GfQuaternion &quaternion)
This constructor initializes the rotation from a quaternion.
Definition: rotation.h:70
double GetReal() const
Returns the real part of the quaternion.
Definition: quaternion.h:85
GF_API GfVec3d Decompose(const GfVec3d &axis0, const GfVec3d &axis1, const GfVec3d &axis2) const
Decompose rotation about 3 orthogonal axes.
GfRotation & SetAxisAngle(const GfVec3d &axis, double angle)
Sets the rotation to be angle degrees about axis.
Definition: rotation.h:88
GF_API GfQuatd GetQuat() const
Returns the rotation expressed as a quaternion.
static GF_API void MatchClosestEulerRotation(double targetTw, double targetFB, double targetLR, double targetSw, double *thetaTw, double *thetaFB, double *thetaLR, double *thetaSw)
Replace the hint angles with the closest rotation of the given rotation to the hint.
GF_API GfRotation & SetQuat(const GfQuatd &quat)
Sets the rotation from a quaternion.
friend GfRotation operator/(const GfRotation &r, double scale)
Returns a rotation equivalent to r with its angle divided by scale.
Definition: rotation.h:285
Basic type for a vector of 3 double components.
Definition: vec3d.h:63
GF_API GfRotation(const GfVec3d &rotateFrom, const GfVec3d &rotateTo)
This constructor initializes the rotation to one that brings the rotateFrom vector to align with rota...
Definition: rotation.h:83
GfQuaternion GetQuaternion() const
Returns the rotation expressed as a quaternion.
Definition: rotation.h:132
GfRotation(const GfQuatd &quat)
This constructor initializes the rotation from a quaternion.
Definition: rotation.h:77
GfRotation & SetIdentity()
Sets the rotation to an identity rotation.
Definition: rotation.h:115
GF_API GfVec3f TransformDir(const GfVec3f &vec) const
Transforms row vector vec by the rotation, returning the result.
Basic type: a quaternion, a complex number with a real coefficient and three imaginary coefficients,...
Definition: quatd.h:60
GfRotation()
The default constructor leaves the rotation undefined.
Definition: rotation.h:60
const GfVec3d & GetImaginary() const
Returns the imaginary part of the quaternion.
Definition: quaternion.h:90
Basic type: 3-space rotation specification.
Definition: rotation.h:55
friend GfRotation operator *(const GfRotation &r1, const GfRotation &r2)
Returns composite rotation of rotations r1 and r2.
Definition: rotation.h:264
GfRotation & operator *=(double scale)
Scales rotation angle by multiplying by scale.
Definition: rotation.h:252
GF_API std::ostream & operator<<(std::ostream &, const GfRotation &)
Output a GfRotation using the format [(x y z) a].
const GfVec3d & GetAxis() const
Returns the axis of rotation.
Definition: rotation.h:122
friend GfRotation operator *(const GfRotation &r, double scale)
Returns a rotation equivalent to r with its angle multiplied by scale.
Definition: rotation.h:272
GfRotation GetInverse() const
Returns the inverse of this rotation.
Definition: rotation.h:142
GfRotation(const GfVec3d &axis, double angle)
This constructor initializes the rotation to be angle degrees about axis.
Definition: rotation.h:65