KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
g_quaternion.h
Go to the documentation of this file.
1 
2 /* $Id: g_quaternion.h 18278 2014-11-25 01:42:10Z ksimek $ */
3 
4 /* =========================================================================== *
5 |
6 | Copyright (c) 1994-2008 by Kobus Barnard (author).
7 |
8 | Personal and educational use of this code is granted, provided that this
9 | header is kept intact, and that the authorship is not misrepresented, that
10 | its use is acknowledged in publications, and relevant papers are cited.
11 |
12 | For other use contact the author (kobus AT cs DOT arizona DOT edu).
13 |
14 | Please note that the code in this file has not necessarily been adequately
15 | tested. Naturally, there is no guarantee of performance, support, or fitness
16 | for any particular task. Nonetheless, I am interested in hearing about
17 | problems that you encounter.
18 |
19 * =========================================================================== */
20 
21 #ifndef KJB_QUATERNION_H
22 #define KJB_QUATERNION_H
23 
24 #include <iosfwd>
25 
26 #include "m_cpp/m_matrix.h"
27 #include "m_cpp/m_vector.h"
28 
29 #ifdef KJB_HAVE_BST_SERIAL
30 #include <boost/serialization/access.hpp>
31 #endif
32 
33 namespace kjb {
34 
35 //forward declarations
36 template <size_t D>
37 class Vector_d;
38 typedef Vector_d<3> Vector3;
39 
41 {
42 #ifdef KJB_HAVE_BST_SERIAL
43  friend class boost::serialization::access;
44 #endif
45  friend Quaternion slerp(const Quaternion& q1, const Quaternion& q2, double t);
46  friend Quaternion slerp2(const Quaternion& q1, const Quaternion& q2, double t);
47  friend Quaternion nlerp(const Quaternion& q1, const Quaternion& q2, double t);
48 
49  friend std::ostream & operator<<(std::ostream & out, const Quaternion & q);
50 
51  typedef Quaternion Self;
52 
53 public:
54 /********** BEGIN SHOEMAKE ADAPTATION *********/
55  enum Euler_mode {
56  XESS = 0, XYXS, // both are equivalent
80  };
81 
82  enum Euler_axis {
83  EulX = 0,
84  EulY = 1,
85  EulZ = 2
86  };
87 
88  enum Euler_parity {
91  };
92 
93  enum Euler_repeat {
94  EulRepNo = 0,
96  };
97 
98  enum Euler_frame {
99  EulFrmS = 0,
101  };
102 
103 /********** END SHOEMAKE ADAPTATION *********/
104 
105  Quaternion();
106  Quaternion(double x, double y, double z, double w);
107  Quaternion(double phi, double theta, double psi, Euler_mode mode = DEFAULT_EULER_MODE);
108  Quaternion(const Matrix& rotation_matrix);
109  Quaternion(const Vector& x, const Vector& y, const Vector& z);
110  /* initialize from axis/angle */
111  Quaternion(const Vector& axis, double angle);
112 
113  /* @brief quick copy. Use clone or assignment operator to
114  * copy all derived representations (rotation matrix, euler
115  * angles, etc) */
116  Quaternion(const Quaternion &);
117 
118  Quaternion clone() const;
119 
120  void swap(Self& other);
121 
123 
124  bool is_identity() const
125  {
126  return _q.x == 0 && _q.y == 0 && _q.z == 0 && _q.w == 1.0;
127  }
128 
129  /* @brief returns 4x4 homogeneous rotation matrix */
130  const Matrix& get_rotation_matrix() const;
131  const Vector& get_axis() const ;
132 
133  Vector get_axis_angle() const ;
134 
135  double get_angle() const ;
137  const Vector& get_euler_angles() const;
138 
140  Vector get_imag() const;
142  double get_real() const;
143 
145  Quaternion & set_axis_angle(const Vector&, double angle);
146  Quaternion & set_axis_angle(const Vector& axis_angle);
147 
149  Quaternion & set_from_directions(const Vector& d1, const Vector& d2);
150 
151  Quaternion & set_from_directions(const Vector3& d1, const Vector3& d2);
152 
153  Quaternion & set_euler_angles(double phi, double theta, double psi);
154  Quaternion & set_euler_phi(double phi);
155  Quaternion & set_euler_theta(double theta);
156  Quaternion & set_euler_psi(double psi);
157 
158 
160  Euler_mode get_euler_mode() const;
161 
162  static void set_default_euler_mode(Euler_mode m);
164 
165  static void set_gimbal_lock_epsilon(float e);
166  static float get_gimbal_lock_epsilon();
167 
168  static void set_epsilon(float e);
169  static float get_epsilon();
170 
171  Vector rotate(const Vector& v) const;
172 
173  Vector3 rotate(const Vector3& v) const;
174 
175  Quaternion conj() const;
176 
178  double norm(unsigned int l = 2) const;
179 
180  double magnitude() const { return norm(); }
181 
182  double magnitude_squared() const
183  {
184  return _q.w*_q.w + _q.x*_q.x + _q.y*_q.y + _q.z*_q.z;
185  }
186 
187  /***********************************
188  * Assignment Operator
189  * *********************************/
190  Quaternion & operator=(const Quaternion &);
191 
192  /***********************************
193  * Mutating Arithmetic Operators
194  * *********************************/
195 
196  Quaternion& operator*=(const Quaternion &);
197  Quaternion& operator/=(const Quaternion &);
198  Quaternion& operator+=(const Quaternion &);
199  Quaternion& operator-=(const Quaternion &);
200 
201  // these operators don't make sense from a user's perspective, but they're usefull in class implementation (e.g. normalize(), mean())
202  Quaternion & operator*=(double);
203  Quaternion & operator/=(double);
204 
205 
206 // Quaternion & operator+=(float);
207 // Quaternion & operator-=(float);
208 
209  /***********************************
210  * Binary Arithmetic Operators
211  * *********************************/
212  Quaternion operator*(const Quaternion &) const;
213  Quaternion operator/(const Quaternion &) const;
214 
215 
217  {
218  Quaternion result(*this);
219  result += q;
220  return result;
221  }
222 
224  {
225  Quaternion result(*this);
226  result -= q;
227  return result;
228  }
229 
230 
231 // Quaternion operator*(float);
232 // Quaternion operator/(float);
233 // Quaternion operator+(float);
234 // Quaternion operator-(float);
235 
236  /***********************************
237  * Logical Operators
238  * *********************************/
239  bool operator==(const Quaternion &) const;
240  bool operator!=(const Quaternion &) const;
241 
242  mutable bool _gimbal_lock;
243 
244 private:
245 
246  const static float NORMALIZED_TOLERANCE;
247  static float EPSILON; // currently arbitrary
248  static float GIMBAL_LOCK_EPSILON; // derived from tests
249  static Euler_mode DEFAULT_EULER_MODE;
250 
251  mutable Matrix _rotation_matrix;
252  mutable bool _rotation_matrix_dirty;
253 
254  mutable Vector _axis;
255  mutable double _angle;
256  mutable bool _axis_angle_dirty;
257 
258  mutable Vector _eulers;
259  mutable bool _eulers_dirty;
260 
263  Euler_mode _euler_mode; // note to self: this should NOT be mutable -KLS, Aug 2010
264 
265  struct Quat{
266  double x;
267  double y;
268  double z;
269  double w;
270  } _q;
271 
272 private:
273  /* Create a quaternion representing a vector */
274  explicit Quaternion(const Vector& v);
275 
276  /*********************************
277  * State-syncronization functions
278  *********************************/
279  void _update_rotation_matrix() const;
280  void _update_axis_angle() const;
281  void _update_euler_angles() const;
282 
283  void _update_from_rotation_matrix();
284  void _update_from_axis_angle();
285  void _update_from_euler_angles();
286 
287 
288  /**********************
289  * Utility Functions
290  **********************/
291  void _dirty_all();
292  void _fix_angles() const;
293  void _fix_axis_angle() const;
294  Quaternion & _normalize();
295 
296 
297 
298  /*
299  * A significant portion of the heavy lifting in this class
300  * is done by Ken Shoemake's code in Graphics Gems IV for
301  * converting between euler/matrix/quaternion.
302  * It was originally written in C, and I've adapted it for
303  * use in this class. Part of adapting it is converting
304  * #define constants to enum types and #define macros to
305  * inline functions. The following block defines these.
306  */
307 /********** BEGIN SHOEMAKE ADAPTATION *********/
308 public:
309 
310  static const Euler_axis EulSafe[4];
311  static const Euler_axis EulNext[4];
312 
313 private:
314  int _euler_order;
315  void _update_euler_order();
316  static int _eul_ord(Euler_axis i, Euler_parity p, Euler_repeat r, Euler_frame f);
317  static void _eul_get_ord(int ord, Euler_axis &i, Euler_axis &j, Euler_axis &k, Euler_axis&h, Euler_parity &n, Euler_repeat &s, Euler_frame &f);
318 /********** END SHOEMAKE ADAPTATION *********/
319 
320 #ifdef KJB_HAVE_BST_SERIAL
321  template <class Archive>
322  void serialize(Archive& ar, const unsigned int /* version */)
323  {
324 
325  ar & _euler_mode;
326  ar & _q.x;
327  ar & _q.y;
328  ar & _q.z;
329  ar & _q.w;
330 
331  if(Archive::is_loading::value == true)
332  _update_euler_order();
333  }
334 #endif
335 
336 };
337 
338 /**** INLINE DEFINITIONS ******/
339 
340 inline void Quaternion::_dirty_all()
341 {
342  _rotation_matrix_dirty = true;
343  _axis_angle_dirty = true;
344  _eulers_dirty = true;
345 }
346 
347 // Bit-packs the representation for the euler-angle convention
348 // Adapted from Ken Shoemake's EulOrd macro in "Graphic Gems IV"
349 // This will be used later, to do conversion between eulers,
350 // matrices, and quaternions.
351 inline int Quaternion::_eul_ord(Euler_axis i, Euler_parity p, Euler_repeat r, Euler_frame f)
352 {
353  return (((((((i)<<1)+(p))<<1)+(r))<<1)+(f));
354 }
355 
356 // Adapted from Ken Shoemake's EulGetOrd macro in "Graphic Gems IV"
357 inline void Quaternion::_eul_get_ord(int ord, Euler_axis &i, Euler_axis &j, Euler_axis &k, Euler_axis &h, Euler_parity &n, Euler_repeat &s, Euler_frame &f)
358 {
359  unsigned int o=ord;
360  f=Euler_frame(o&1);
361  o=o>>1;
362  s=Euler_repeat(o&1);
363  o=o>>1;
364  n=Euler_parity(o&1);
365  o=o>>1;
366  i=EulSafe[o&3];
367  j=EulNext[i+n];
368  k=EulNext[i+1-n];
369  h=s?k:i;
370 }
371 
372 inline double norm(const Quaternion& q, unsigned int l = 2)
373 {
374  return q.norm(l);
375 }
376 
377 //template <class Iterator>
378 //Quaternion mean(Iterator begin, Iterator end, const Quaternion& /* dummy */)
379 //{
380 // Quaternion q_sum;
381 //
382 // // first += second + ... + end;
383 // q_sum = std::accumulate(
384 // begin,
385 // end,
386 // Quaternion(0.0, 0.0, 0.0, 0.0));
387 //
388 // q_sum /= norm(q_sum, 2);
389 // return q_sum;
390 //}
391 //
398 inline Quaternion difference(const Quaternion& q1, const Quaternion& q2)
399 {
400  Quaternion result = q2.conj() * q1;
401  return result /= norm(result);
402 }
403 
405 Quaternion slerp(const Quaternion& q1, const Quaternion& q2, double t);
406 
408 Quaternion slerp2(const Quaternion& q1, const Quaternion& q2, double t);
409 
413 Quaternion nlerp(const Quaternion& q1, const Quaternion& q2, double t);
414 
416 inline void swap(Quaternion& q1, Quaternion& q2) { q1.swap(q2); }
417 
418 } // namespace kjb
419 #endif
Definition: g_quaternion.h:71
Quaternion conj() const
Definition: g_quaternion.cpp:808
friend Quaternion slerp(const Quaternion &q1, const Quaternion &q2, double t)
Definition: g_quaternion.cpp:1366
bool operator!=(const Quaternion &) const
Definition: g_quaternion.cpp:802
Vector rotate(const Vector &v) const
Definition: g_quaternion.cpp:565
friend std::ostream & operator<<(std::ostream &out, const Quaternion &q)
Definition for the Matrix class, a thin wrapper on the KJB Matrix struct and its related functionalit...
Quaternion difference(const Quaternion &q1, const Quaternion &q2)
Definition: g_quaternion.h:398
Quaternion & set_euler_psi(double psi)
Definition: g_quaternion.cpp:509
bool is_identity() const
Definition: g_quaternion.h:124
Vector_d< 3 > Vector3
Definition: g_quaternion.h:37
Euler_parity
Definition: g_quaternion.h:88
Definition: g_quaternion.h:69
static const Euler_axis EulNext[4]
Definition: g_quaternion.h:311
Quaternion & set_rotation_matrix(const Matrix &)
Definition: g_quaternion.cpp:326
Definition: g_quaternion.h:63
Definition: g_quaternion.h:68
Definition: g_quaternion.h:90
friend Quaternion slerp2(const Quaternion &q1, const Quaternion &q2, double t)
Definition: g_quaternion.cpp:1402
Definition: g_quaternion.h:100
Definition: g_quaternion.h:79
Quaternion nlerp(const Quaternion &q1, const Quaternion &q2, double t)
Definition: g_quaternion.cpp:1442
theta
Definition: APPgetLargeConnectedEdges.m:108
Definition: g_quaternion.h:78
Definition: g_quaternion.h:73
Quaternion operator/(const Quaternion &) const
Definition: g_quaternion.cpp:871
void swap(Perspective_camera &cam1, Perspective_camera &cam2)
Swap two cameras.
Definition: perspective_camera.h:599
Definition: g_quaternion.h:75
for k
Definition: APPgetLargeConnectedEdges.m:61
Euler_frame
Definition: g_quaternion.h:98
static void set_default_euler_mode(Euler_mode m)
Definition: g_quaternion.cpp:534
r
Definition: APPgetLargeConnectedEdges.m:127
const Matrix & get_rotation_matrix() const
Definition: g_quaternion.cpp:282
Definition: g_quaternion.h:69
double magnitude_squared() const
Definition: g_quaternion.h:182
This class implements vectors, in the linear-algebra sense, with real-valued elements.
Definition: m_vector.h:87
Quaternion operator+(const Quaternion &q) const
Definition: g_quaternion.h:216
static void set_epsilon(float e)
Definition: g_quaternion.cpp:554
Euler_mode
Definition: g_quaternion.h:55
Definition: g_quaternion.h:79
Quaternion & set_euler_phi(double phi)
Definition: g_quaternion.cpp:491
Definition: g_quaternion.h:64
Definition: g_quaternion.h:72
Definition: g_quaternion.h:74
Vector get_imag() const
returns vector [x, y, z]
Definition: g_quaternion.cpp:314
Definition: g_quaternion.h:61
Definition: g_quaternion.h:61
Definition: g_quaternion.h:99
Definition: g_quaternion.h:66
bool operator==(const Quaternion &) const
Definition: g_quaternion.cpp:793
Definition: g_quaternion.h:56
double get_real() const
returns w
Definition: g_quaternion.cpp:324
static const Euler_axis EulSafe[4]
Definition: g_quaternion.h:310
Definition: g_quaternion.h:94
Definition: g_quaternion.h:58
Definition: g_quaternion.h:77
Definition: g_quaternion.h:71
Definition: g_quaternion.h:62
Definition: g_quaternion.h:63
Quaternion & operator-=(const Quaternion &)
This is simple 4-vector subtraction. If you want to invert a rotation, don't use this–multiply by the...
Definition: g_quaternion.cpp:713
Definition: g_quaternion.h:40
Definition: g_quaternion.h:85
Definition: g_quaternion.h:64
Quaternion clone() const
Definition: g_quaternion.cpp:243
Quaternion & set_from_directions(const Vector &d1, const Vector &d2)
Find quaternion that rotates vector d1 to vector d2 in the smallest angle.
Definition: g_quaternion.cpp:412
Definition: g_quaternion.h:66
x
Definition: APPgetLargeConnectedEdges.m:100
Definition: g_quaternion.h:89
Definition: g_quaternion.h:65
Definition: g_quaternion.h:62
Quaternion slerp(const Quaternion &q1, const Quaternion &q2, double t)
Definition: g_quaternion.cpp:1366
void swap(Self &other)
Definition: g_quaternion.cpp:250
bool _gimbal_lock
Definition: g_quaternion.h:242
Definition: g_quaternion.h:83
Vector get_axis_angle() const
Definition: g_quaternion.cpp:300
Definition: g_quaternion.h:65
double norm(const Quaternion &q, unsigned int l=2)
Definition: g_quaternion.h:372
Definition: g_quaternion.h:59
Definition: g_quaternion.h:67
Euler_axis
Definition: g_quaternion.h:82
Quaternion & set_axis_angle(const Vector &, double angle)
Definition: g_quaternion.cpp:370
Definition: g_quaternion.h:68
double magnitude() const
Definition: g_quaternion.h:180
Quaternion & operator=(const Quaternion &)
Definition: g_quaternion.cpp:617
const Vector & get_axis() const
Definition: g_quaternion.cpp:288
Quaternion & set_euler_mode(Euler_mode m)
Definition: g_quaternion.cpp:516
Definition: g_quaternion.h:75
Euler_mode get_euler_mode() const
Definition: g_quaternion.cpp:529
Quaternion & init_identity()
Definition: g_quaternion.cpp:270
Definition: g_quaternion.h:70
Definition: g_quaternion.h:76
friend Quaternion nlerp(const Quaternion &q1, const Quaternion &q2, double t)
Definition: g_quaternion.cpp:1442
const Vector & get_euler_angles() const
returns vector [phi, theta, psi]
Definition: g_quaternion.cpp:308
Definition: g_quaternion.h:56
Definition: g_quaternion.h:73
Quaternion operator*(const Quaternion &) const
Definition: g_quaternion.cpp:862
Quaternion & set_euler_angles(double phi, double theta, double psi)
Definition: g_quaternion.cpp:471
double norm(unsigned int l=2) const
compute the L-* norm
Definition: g_quaternion.cpp:826
Quaternion & operator+=(const Quaternion &)
Definition: g_quaternion.cpp:690
Definition: g_quaternion.h:59
Definition: g_quaternion.h:57
Quaternion operator-(const Quaternion &q) const
Definition: g_quaternion.h:223
Definition: g_quaternion.h:72
double get_angle() const
Definition: g_quaternion.cpp:294
static void set_gimbal_lock_epsilon(float e)
Definition: g_quaternion.cpp:544
Definition: g_quaternion.h:67
Definition: g_quaternion.h:60
Definition: g_quaternion.h:37
get the indices of edges in each direction for i
Definition: APPgetLargeConnectedEdges.m:48
static float get_epsilon()
Definition: g_quaternion.cpp:559
Definition: g_quaternion.h:57
Euler_repeat
Definition: g_quaternion.h:93
Definition: g_quaternion.h:58
This class implements matrices, in the linear-algebra sense, with real-valued elements.
Definition: m_matrix.h:94
Quaternion & operator*=(const Quaternion &)
Definition: g_quaternion.cpp:637
for m
Definition: APPgetLargeConnectedEdges.m:64
Definition: g_quaternion.h:60
static Euler_mode get_default_euler_mode()
Definition: g_quaternion.cpp:539
Definition: g_quaternion.h:77
static float get_gimbal_lock_epsilon()
Definition: g_quaternion.cpp:549
Definition: g_quaternion.h:74
Definition: g_quaternion.h:84
Definition for the Vector class, a thin wrapper on the KJB Vector struct and its related functionalit...
Quaternion & set_euler_theta(double theta)
Definition: g_quaternion.cpp:500
Definition: g_quaternion.h:76
Quaternion & operator/=(const Quaternion &)
Definition: g_quaternion.cpp:662
Quaternion()
Definition: g_quaternion.cpp:45
Definition: g_quaternion.h:78
Definition: g_quaternion.h:95
Quaternion slerp2(const Quaternion &q1, const Quaternion &q2, double t)
Definition: g_quaternion.cpp:1402
Definition: g_quaternion.h:70