Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Quaternion.hh
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 #ifndef __Quaternion_hh__
27 #define __Quaternion_hh__
28 
29 #include <bias_config.h>
30 
31 #include <Base/Math/Vector4.hh>
32 #include <Base/Math/Vector3.hh>
33 #include <Base/Geometry/RMatrixBase.hh>
34 #include <Base/Geometry/QuaternionOperators.hh>
35 
36 namespace BIAS {
37 
38 #define QUATERNION_EPSILON 1E-10 // DBL_EPSILON, too small (dherzog)
39 #define QUATERNION_TYPE double
40 
41  // forward declaration to avoid mutual inclusion
42  class BIASGeometryBase_EXPORT RMatrixBase;
43 
44  /** @class Quaternion
45  * @test tested with TestRotationConversion.cpp
46  @ingroup g_geometry
47  @brief class for rotation with axis and angle
48 
49  Quaternions can be used for rotation around an axis through the
50  origin by spcecifing the normal direction vector of the axis and
51  an angle.
52 
53  The rotation for positive angles is clockwise,
54  when looking in direction of the axis.
55 
56  Contains qx=[0], qy=[1], qz=[2], qw=[3].
57 
58  Not every quaternion describes a rotation.
59  Only quaternions of the form:
60 
61  qx = x * sin(phi/2) , which is the imaginary part i
62 
63  qy = y * sin(phi/2) , which is the imaginary part j
64 
65  qz = z * sin(phi/2) , which is the imaginary part k
66 
67  qw = cos(phi/2), , which is the real part
68 
69  where (x, y, z) is the normalized direction vector of the axis
70  and phi is the angle of rtoation.
71 
72  Some usefull quaternions:
73  x y z w Description
74  0 0 0 1 Identity quaternion,
75  no rotation
76  1 0 0 0 180' turn around X axis
77  0 1 0 0 180' turn around Y axis
78  0 0 1 0 180' turn around Z axis
79  sqrt(0.5) 0 0 sqrt(0.5) 90' rotation around X axis
80  0 sqrt(0.5) 0 sqrt(0.5) 90' rotation around Y axis
81  0 0 sqrt(0.5) sqrt(0.5) 90' rotation around Z axis
82  -sqrt(0.5) 0 0 sqrt(0.5) -90' rotation around X axis
83  0 -sqrt(0.5) 0 sqrt(0.5) -90' rotation around Y axis
84  0 0 -sqrt(0.5) sqrt(0.5) -90' rotation around Z axis
85 
86  @author grest 06/2003
87  */
88  template<class QUAT_TYPE>
89  class BIASGeometryBase_EXPORT Quaternion
90  : public Vector4<QUAT_TYPE>
91  {
92  public:
93 
94  ~Quaternion();
95 
96  Quaternion();
97 
99 
100  /** copy constructor
101  @author Daniel Grest (06/2003) */
102  inline Quaternion(const Quaternion<QUAT_TYPE> &q);
103 
104  Quaternion(QUAT_TYPE i, QUAT_TYPE j, QUAT_TYPE k,
105  QUAT_TYPE r);
106 
107  inline void SetIdentity();
108 
109  /**
110  * Sets all parts of quaternion in mathematical order,
111  * real part first, then 1.,2. and 3. imaginary part
112  */
113  inline void SetQuaternion(QUAT_TYPE real, QUAT_TYPE i,
114  QUAT_TYPE j, QUAT_TYPE k);
115 
116  /** returns the Inverse rotation Quaternion
117  */
118  inline Quaternion<QUAT_TYPE> Inverse() const;
119 
120  /** inverts this, by changing the rotation axis by *=-1
121  */
122  inline void Invert();
123 
124  /** makes Quaternion-representation uniqe, ensuring vector lies
125  in upper (by real part) hemisphere. (inplace)
126  */
127  inline void MakeUnique();
128 
129  /** quaternion multiplication: this= this * quat
130  */
131  inline void Mult(const Quaternion<QUAT_TYPE> &quat);
132 
133  /** quaternion multiplication: res = this * arg
134  */
135  inline void Mult(const Quaternion<QUAT_TYPE> &arg,
137 
138  /** quaternion multiplication: this = quat * this
139  */
140  inline void MultLeft(const Quaternion<QUAT_TYPE> &quat);
141 
142  /** rotates the given Vector qith the quaternion ( q v q* )
143  the resulting vector is given in res
144  @returns 0 in case of no error
145  @author Daniel Grest, June 2003
146  */
147  inline int MultVec(const Vector3<QUAT_TYPE> &vec,
148  Vector3<QUAT_TYPE> &res) const;
149 
150  /* rets result from MultVec()
151  @author herzog 2005-07-15 */
152  inline Vector3<QUAT_TYPE>
153  MultVec(const Vector3<QUAT_TYPE> &vec) const;
154 
155  /** Computes this^(scale), which scales the angle from axis/angle-
156  representation with 'scale'. This is the same like inter-/extra-
157  polating between (0,0,0,1)-quaternion and this!
158  */
159  Quaternion<QUAT_TYPE> Power(const QUAT_TYPE & scale) const;
160 
161  /** Linear interpolation between this and given quaternion.
162  @note Quaternions are assumed to be unit quaternions! */
163  Quaternion<QUAT_TYPE> InterpolateLinear(const Quaternion<QUAT_TYPE> &to,
164  const QUAT_TYPE & t) const;
165 
166  /** Spherical interpolation between this and given quaternion.
167  @note Quaternions are assumed to be unit quaternions! */
169  const QUAT_TYPE & t) const;
170 
171  /** sets the quaternion with given rotation axis and angle (in rad)
172  @returns 0 in case of no error
173  @author Daniel Grest, June 2003
174  */
175  inline void SetValueAsAxisRad(const Vector3<QUAT_TYPE> &axis,
176  QUAT_TYPE angle);
177 
178  /** sets the quaternion with given rotation axis and angle (in rad)
179  @returns 0 in case of no error
180  @author Daniel Grest, June 2003
181  */
182 
183  inline void SetValueAsAxisRad(QUAT_TYPE axisX, QUAT_TYPE axisY,
184  QUAT_TYPE axisZ, QUAT_TYPE angle);
185 
186  /** Returns matrix which expresses (left) quaternion multiplication.
187  * A quaternions stored in an object can be understood as a 4-vector
188  * q =(ix iy iz r)^T.
189  * Left multiplying a quaternion q2 with a quaternion q1 can be
190  * expressed in terms of matrix multiplication as
191  * qRes = q1*q2 = M(q1)*q2.
192  * This method returns the matrix M(*this).
193  */
194  Matrix4x4<QUAT_TYPE> GetQuaternionMultMatrixLeft() const;
195 
196  /** Returns matrix which expresses right quaternion multiplication.
197  * Right multiplying a quaternion q1 with quaternion q2 can be
198  * expressed as qRes = q1*q2 = N(q2)*q1.
199  * This method returns the matrix N(*this).
200  */
201  Matrix4x4<QUAT_TYPE> GetQuaternionMultMatrixRight() const;
202 
203  /** Returns a corresponding (quaternion) rotation matrix.
204  @deprecated Transpose problem! This function is going to be removed!
205  Use RMatrixBase::SetFromQuaternion() instead!
206  @author grest */
207  int GetRotationMatrix(RMatrixBase& R) const;
208 
209  /** Returns rotation axis. See GetRotationAxisAngle().
210  */
211  Vector3<QUAT_TYPE> GetRotationAxis() const;
213  /** Returns rotation angle notation in radians.
214  Note that the returned angle resides in the interval [0,PI)!
215  */
216  QUAT_TYPE GetRotationAngle() const;
217 
218  /** Returns rotation in axis and angle notation (angle in radians).
219  Note that the returned angle resides in the interval [0,PI) and
220  the axis points into the according direction!
221  @author woelk 12 2002 */
222  int GetAxisAngle(Vector3<QUAT_TYPE>& axis, QUAT_TYPE& angle) const;
224  /** Sets quaternion as concatenated rotations around
225  x,y,z-axis; this = q_x * q_y * q_z (BIAS-RMatrix conform)
226  @author herzog 2005-07-19 */
227  int SetXYZ(QUAT_TYPE radX, QUAT_TYPE radY, QUAT_TYPE radZ);
228 
229  /** Sets quaternion as concatenated rotations around
230  x,y,z-axis; this = q_z * q_y * q_x (BIAS-RMatrix conform)
231  @author herzog 2005-07-19 */
232  int SetZYX(QUAT_TYPE radX, QUAT_TYPE radY, QUAT_TYPE radZ);
233 
234 
235  /** Scales quaternion to unit length, i.e. norm equals 1. */
236  inline void Normalize() {
237  (*this) /= (QUAT_TYPE)this->NormL2();
238  }
239 
240  /** assignment operator
241  @author grest 06 2003 */
242  Quaternion<QUAT_TYPE>& operator=(const Quaternion<QUAT_TYPE>& vec);
243 
244  /** @brief Enforce rigid coupling constraint for this and the other given
245  unit quaternion (equal rotation angle/equal scalar part for both).
246  Computes direct simple interpolation of both unit quaternion where
247  the scalar parts of the resulting unit quaternion are identical.
248  This solution can be used as initial guess for numerical refinement.
249  @param[in/out] other Quaternion to enforce rigid coupling constraint with
250  @param[in] useOtherAngle Use rotation angle (= scalar part) of other
251  quaternion instead of interpolating both
252  @author esquivel 02/2012
253  */
254  void EnforceRigidCouplingConstraint(Quaternion<QUAT_TYPE> &other,
255  bool useOtherAngle = false);
256 
257  /** @brief Enforce rigid coupling constraint for all quaternions in given vector.
258  @param[in/out] quats Quaternions to enforce rigid coupling constraint for
259  @param[in] useFirstAngle Use rotation angle (= scalar part) of first
260  quaternion instead of interpolating all
261  @author esquivel 02/2012
262  */
263  static void EnforceRigidCouplingConstraint(
264  std::vector< Quaternion<QUAT_TYPE> > &quats, bool useFirstAngle = false);
265 
266  /** @brief Compute minimal parametrization of unit quaternion by
267  projecting it from the 4d hypersphere onto the 3d equatorial
268  space, as described in:
269  [TCBS+12] Terzakis et al.: A Recipe on the Parameterization of Rotation
270  Matrices for Non-Linear Optimization using Quaternions, 2012.
271  @param[out] p3D Returns 3d point representation of unit quaternion
272  @author esquivel 07/2013
273  */
274  inline void GetEquatorialPoint3D(Vector3<QUAT_TYPE> &p3D) const;
275 
276  /** @brief Set unit quaternion from 3d point in equatorial space by back-
277  projecting it onto the 4d hypersphere, as described in [TCBS+12].
278  @param[in] p3D Constaint 3d point representation of unit quaternion
279  @see GetEquatorialPoint3D
280  @author esquivel 07/2013
281  */
282  inline void SetFromEquatorialPoint3D(const Vector3<QUAT_TYPE> &p3D);
283 
284  }; // class
285 
286  #include <Base/Geometry/QuaternionInl.hh>
287 
288 } // namespace
289 
290 #endif // __Quaternion_hh__
class BIASGeometryBase_EXPORT Quaternion
Definition: RMatrixBase.hh:37
int MultVec(const Vector3< QUAT_TYPE > &vec, Vector3< QUAT_TYPE > &res) const
rotates the given Vector qith the quaternion ( q v q* ) the resulting vector is given in res ...
Definition: Quaternion.hh:136
void Normalize()
Scales quaternion to unit length, i.e.
Definition: Quaternion.hh:236
class Vector4 contains a Vector of dim.
Definition: Vector4.hh:65
class Vector3 contains a Vector of fixed dim.
Definition: Matrix.hh:53
Implements a 3D rotation matrix.
Definition: RMatrixBase.hh:44
is a &#39;fixed size&#39; quadratic matrix of dim.
Definition: Matrix4x4.hh:54
class for rotation with axis and angle