Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
RMatrixBase.hh
1 /* This file is part of the BIAS library (Basic ImageAlgorithmS).
2 
3  Copyright (C) 2003-2009 (see file CONTACT for details)
4  Multimediale Systeme der Informationsverarbeitung
5  Institut fuer Informatik
6  Christian-Albrechts-Universitaet Kiel
7 
8  BIAS is free software; you can redistribute it and/or modify
9  it under the terms of the GNU Lesser General Public License as published by
10  the Free Software Foundation; either version 2.1 of the License, or
11  (at your option) any later version.
12 
13  BIAS is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License
19  along with BIAS; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22 
23 #ifndef __RMatrixBase_hh__
24 #define __RMatrixBase_hh__
25 #include "bias_config.h"
26 
27 #include <Base/Math/Vector3.hh>
28 #include <Base/Math/Matrix3x3.hh>
29 #include <Base/Debug/Debug.hh>
30 
31 namespace BIAS {
32 
33 #define ROTATION_MATRIX_TYPE double
34 
35 #define ROTATION_MATRIX_EPSILON DBL_EPSILON
36 
37  template<class T> class BIASGeometryBase_EXPORT Quaternion;
38 
39  /** @class RMatrixBase
40  @ingroup g_geometry
41  @brief Implements a 3D rotation matrix.
42  @author frahm, woelk
43  */
44  class BIASGeometryBase_EXPORT RMatrixBase
45  : public Matrix3x3<ROTATION_MATRIX_TYPE>
46  {
47  public:
48 
49  /** @brief Constructor setting matrix to identity */
50  RMatrixBase();
51 
52  /** @brief Constructor setting matrix to identity or zero
53  @deprecated Only identity is allowed here!
54  @author koeser
55  */
56  explicit RMatrixBase(const MatrixInitType& i);
57 
58  /** @brief Copy constructor from rotation matrix */
59  RMatrixBase(const RMatrixBase& r);
60 
61  /** @brief Copy constructor from 3x3 matrix
62  @attention Orthonormality of matrix is enforced automatically! */
64 
65  /** @brief Initialization from rotation axis w and angle phi (in rad)
66  using Rodrigues' formula */
68  const ROTATION_MATRIX_TYPE phi);
69 
70  /** @brief Copy constructor from 3x3 matrix
71  @attention Orthonormality of matrix is enforced automatically! */
73 
74  virtual ~RMatrixBase();
75 
76  /** @brief Set Euler angles (in rad) in order XYZ
77 
78  Set angles either in order 1. x, 2. y, 3. z and moving axes
79  or in order 1. z, 2. y, 3. x and fixed axes.
80  Angles are measured as in mathematics (counter-clockwise), i.e.
81  Set(x, 0, 0) results in the following matrix:
82 
83  | 1 0 0 |
84  | 0 cos(x) -sin(x) |
85  | 0 sin(x) cos(x) |
86 
87  (*this) = Rx*Ry*Rz =
88 
89  | c(y)c(z) -c(y)s(z) s(y) |
90  | c(z)s(x)s(y)+c(x)s(z) c(x)c(z)-s(x)s(y)s(z) -c(y)s(x) |
91  | -c(x)c(z)s(y)+s(x)s(z) c(z)s(x)+c(x)s(y)s(z) c(x)c(y) |
92 
93  with s(g) = sin(g), c(g) = cos(g), x = PhiX, y = PhiY and z = PhiZ
94 
95  @author frahm, woelk
96  */
97  void SetXYZ(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY,
98  ROTATION_MATRIX_TYPE PhiZ);
99 
100  /** @brief Set Euler angles (in rad) in order XYZ from vector */
101  inline void SetXYZ(const Vector3<ROTATION_MATRIX_TYPE>& r)
102  { SetXYZ(r[0], r[1], r[2]); }
103 
104  /** @brief Set Euler angles (in rad) in order ZYX
105 
106  Set angles either in order 1. z, 2. y, 3. x and moving axes
107  or in order 1. x, 2. y, 3. z and fixed axes.
108  Angles are measured as in mathematics (counter-clockwise), i.e.
109  Set(x, 0, 0) results in the following matrix:
110 
111  | 1 0 0 |
112  | 0 cos(x) -sin(x) |
113  | 0 sin(x) cos(x) |
114 
115  (*this) = Rz*Ry*Rx =
116 
117  | c(y)c(z) s(x)s(y)c(z)-c(x)s(z) c(x)s(y)c(z)+s(x)s(z) |
118  | c(y)s(z) s(x)s(y)s(z)+c(x)c(z) c(x)s(y)s(z)-s(x)s(z) |
119  | -s(y) s(x)c(y) c(x)c(y) |
120 
121  with s(g) = sin(g), c(g) = cos(g), x = PhiX, y = PhiY and z = PhiZ
122 
123  @author frahm, woelk
124  */
125  void SetZYX(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY,
126  ROTATION_MATRIX_TYPE PhiZ);
127 
128  /** @brief Set Euler angles (in rad) in order ZYX from vector */
129  inline void SetZYX(const Vector3<ROTATION_MATRIX_TYPE>& r)
130  { SetZYX(r[0], r[1], r[2]); }
131 
132  /** @brief Set Euler angles (in rad) in order ZXY
133 
134  Set angles either in order 1. z, 2. x, 3. y and moving axes
135  or in order 1. y, 2. x, 3. z and fixed axes.
136  Angles are measured as in mathematics (counter-clockwise), i.e.
137  Set(x, 0, 0) results in the following matrix:
138 
139  | 1 0 0 |
140  | 0 cos(x) -sin(x) |
141  | 0 sin(x) cos(x) |
142 
143  (*this) = Rz*Rx*Ry =
144 
145  | c(y)c(z)-s(x)s(y)s(z), c(x)s(z), s(y)c(z)+s(x)c(y)s(z) |
146  | s(z)c(y)+s(x)s(y)c(z), c(x)c(z), s(y)*s(z)+s(x)-c(y)c(z) |
147  | -c(x)s(y) , s(x) , c(x)c(y) |
148 
149  with s(g) = sin(g), c(g) = cos(g), x = PhiX, y = PhiY and z = PhiZ
150 
151  @author haase
152  */
153  void SetZXY(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY,
154  ROTATION_MATRIX_TYPE PhiZ);
155 
156  /** @brief Set Euler angles (in rad) in order ZXY from vector */
157  inline void SetZXY(const Vector3<ROTATION_MATRIX_TYPE>& r)
158  { SetZXY(r[0], r[1], r[2]); }
159 
160  /** @brief Set Euler angles (in rad) in order YXZ
161 
162  Set angles either in order 1. y, 2. x, 3. z and moving axes
163  or in order 1. z, 2. x, 3. y and fixed axes.
164  Angles are measured as in mathematics (counter-clockwise), i.e.
165  Set(x, 0, 0) results in the following matrix:
166 
167  | 1 0 0 |
168  | 0 cos(x) -sin(x) |
169  | 0 sin(x) cos(x) |
170 
171  (*this) = Ry*Rx*Rz
172 
173  @author haase
174  */
175  void SetYXZ(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY,
176  ROTATION_MATRIX_TYPE PhiZ);
177 
178  /** @brief Set Euler angles (in rad) in order YXZ from vector */
179  inline void SetYXZ(const Vector3<ROTATION_MATRIX_TYPE>& r)
180  { SetYXZ(r[0], r[1], r[2]); }
181 
182  /** @brief Set Euler angles (in rad) in order XZY
183 
184  Set angles either in order 1. x, 2. z, 3. y and moving axes
185  or in order 1. y, 2. z, 3. x and fixed axes.
186 
187  @author esquivel
188  */
189  void SetXZY(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY,
190  ROTATION_MATRIX_TYPE PhiZ);
191 
192  /** @brief Set Euler angles (in rad) in order XZY from vector */
193  inline void SetXZY(const Vector3<ROTATION_MATRIX_TYPE>& r)
194  { SetXZY(r[0], r[1], r[2]); }
195 
196  /** @brief Set Euler angles (in rad) in order YZX
197 
198  Set angles either in order 1. y, 2. z, 3. x and moving axes
199  or in order 1. x, 2. z, 3. y and fixed axes.
200 
201  @author esquivel
202 
203  */
204  void SetYZX(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY,
205  ROTATION_MATRIX_TYPE PhiZ);
206 
207  /** @brief Set Euler angles (in rad) in order YZX from vector */
208  inline void SetYZX(const Vector3<ROTATION_MATRIX_TYPE>& r)
209  { SetYZX(r[0], r[1], r[2]); }
210 
211  /** @brief Set from rotation axis w and angle phi (in rad)
212  @param w Axis vector w will be normalized to length 1, so we need
213  |w|>1e-6 if phi != 0, otherwise an exception is thrown
214  @param phi Rotation angle is given in radians
215  @author evers, woelk */
216  void Set(const Vector3<ROTATION_MATRIX_TYPE> &w,
217  const ROTATION_MATRIX_TYPE phi);
218 
219  /** @brief Set from rotation axis * angle (modified Rodrigues vector)
220  @author evers */
221  void SetFromAxisAngle(Vector3<ROTATION_MATRIX_TYPE> w);
222 
223  /* @brief Set rotation matrix from an orthogonal basis given in world
224  coordinate system (WCS)
225 
226  As R' is expressing the transformation from WCS to ICS (image
227  coordinate system), R is ICS to WCS and hereby represents the ICS
228  base vectors expressed in WCS. These are the *rows* of R because
229  the transformation is the scalar product.
230 
231  Assume ex,ey,ez are right-hand orthogonal (RHS), e.g. the orthogonal
232  image coordinate system (ICS) base vectors expressed in world
233  coordinates (WCS).
234  (Inverse doesn't make sense because base would be identity then).
235  Normal vectors of length 1 are computed.
236 
237  @todo Warning if (ex,ey,ez) are not an orthogonal basis!
238 
239  @author jw 09/2003, added exception
240  */
241  void SetFromOrthogonalBasis(const BIAS::Vector3<ROTATION_MATRIX_TYPE> &ex,
244 
245  /** @brief Set rotation matrix from two vectors from an orthonormal basis
246  @param xh represents the first base vector and is left unchanged
247  @param vy should be orthogonal to xh, it is orthogonalized otherwise
248 
249  You can think of this routine as computing R from an image plane
250  given by two (usually orthogonal) base vectors.
251  If the given base vectors are not orthogonal, xh is kept and yv is
252  orthogonalized appropriately.
253 
254  @author jw
255  */
256  void SetFromHV(const BIAS::Vector3<ROTATION_MATRIX_TYPE> &xh,
258 
259  /** @brief Calculates quaternion representation for this rotation matrix
260  @attention Scalar part of quaternion will always be non-negative
261  for sake of uniqueness of the resulting quaternion!
262  @author woelk 12/2003
263  @author esquivel 03/2011 (changed algorithm, bugfix) */
264  int GetQuaternion(Quaternion<ROTATION_MATRIX_TYPE> &quat) const ;
265 
266  /** @brief Set rotation matrix from a quaternion
267  @author grest 06/2003 */
268  int SetFromQuaternion(const Quaternion<ROTATION_MATRIX_TYPE> &q);
269 
270  /** @brief Set rotation matrix from orientation and up vector
271  @note This is openGL conform, similar to gluLookAt(), i.e. if
272  ori is (0,0,-1) and up is (0,1,0) the resulting matrix is identity.
273  @author grest 12/2005 */
274  int SetFromOriUpGL(BIAS::Vector3<ROTATION_MATRIX_TYPE> ori,
276 
277  /** @brief Set rotation matrix from orientation and up vector*/
278  int SetFromOriUp(BIAS::Vector3<ROTATION_MATRIX_TYPE> ori,
280 
281  /** @brief Calculates angle and rotation axis representation for
282  this rotation matrix
283  @param angle Rotation angle is returned in radians
284  @author woelk 12/2003 */
285  int GetRotationAxisAngle(Vector3<ROTATION_MATRIX_TYPE>& axis,
286  ROTATION_MATRIX_TYPE& angle) const;
287 
288  /** @brief Interface for axis component of GetRotationAxisAngle() */
289  BIAS::Vector3<ROTATION_MATRIX_TYPE> GetRotationAxis() const;
290 
291  /** @brief Interface for angle component of GetRotationAxisAngle() */
292  ROTATION_MATRIX_TYPE GetRotationAngle() const;
293 
294  /** @brief Calculates the angle * rotation axis representation for
295  this rotation matrix (modified Rodrigues vector)
296  @author evers */
297  int GetRotationAxisAngle(Vector3<ROTATION_MATRIX_TYPE>& w) const;
298 
299  /** @brief Get Euler angles for this rotation matrix in order XYZ
300  @attention Representation is not unique and has singularities at
301  +-pi/2. Assume for example (*this) = Rx * Ry * Rz, then we have
302  either Euler angles in order 1. x, 2. y, 3. z and moving axes
303  or in order 1. z, 2. y, 3. x and fixed axes.
304  @author woelk 01/2003
305  */
306  int GetRotationAnglesXYZ(double& PhiX, double& PhiY, double& PhiZ) const;
307 
308  /** @brief Get Euler angles for this rotation matrix in order XYZ
309  @see GetRotationAnglesXYZ(double&, double&, double&) */
311  { return GetRotationAnglesXYZ(r[0], r[1], r[2]); }
312 
313  /** @brief Get Euler angles for this rotation matrix in order ZYX
314  @attention Representation is not unique and has singularities at
315  +-pi/2. Assume for example (*this) = Rz * Ry * Rx, then we have
316  either Euler angles in order 1. z, 2. y, 3. x and moving axes
317  or in order 1. x, 2. y, 3. z and fixed axes.
318  @author woelk 01/2003
319  */
320  int GetRotationAnglesZYX(double& PhiX, double& PhiY, double& PhiZ) const;
321 
322  /** @brief Get Euler angles for this rotation matrix in order ZYX
323  @see GetRotationAnglesZYX(double&, double&, double&) */
325  { return GetRotationAnglesZYX(r[0], r[1], r[2]); }
326 
327  /** @brief Get Euler angles for this rotation matrix in order ZXY
328  @attention Representation is not unique and has singularities at
329  +-pi/2. Rotation order is 1. z, 2. x, 3. y with moving axes or
330  1. y, 2. x, 3. z with fixed axes.
331  @author haase 2007
332  */
333  int GetRotationAnglesZXY(double& PhiX, double& PhiY, double& PhiZ) const;
334 
335  /** @brief Get Euler angles for this rotation matrix in order ZXY
336  @see GetRotationAnglesZXY(double&, double&, double&) */
338  { return GetRotationAnglesZXY(r[0], r[1], r[2]); }
339 
340  /** @brief Get Euler angles for this rotation matrix in order YXZ
341  @attention Representation is not unique and has singularities at
342  +-pi/2. Rotation order is 1. y, 2. x, 3. z with moving axes or
343  1. z, 2. x, 3. y with fixed axes.
344  @author haase 2007 */
345  int GetRotationAnglesYXZ(double& PhiX, double& PhiY, double& PhiZ) const;
346 
347  /** @brief Get Euler angles for this rotation matrix in order YXZ
348  @see GetRotationAnglesYXZ(double&, double&, double&) */
350  { return GetRotationAnglesYXZ(r[0], r[1], r[2]); }
351 
352  /** @brief Get Euler angles for this rotation matrix in order YZX
353  @attention Representation is not unique and has singularities at
354  +-pi/2. Rotation order is 1. y, 2. z, 3. x with moving axes or
355  1. x, 2. z, 3. y with fixed axes.
356  @author esquivel 2014 */
357  int GetRotationAnglesYZX(double& PhiX, double& PhiY, double& PhiZ) const;
358 
359  /** @brief Get Euler angles for this rotation matrix in order YZX
360  @see GetRotationAnglesYZX(double&, double&, double&) */
362  { return GetRotationAnglesYZX(r[0], r[1], r[2]); }
363 
364  /** @brief Get Euler angles for this rotation matrix in order XZY
365  @attention Representation is not unique and has singularities at
366  +-pi/2. Rotation order is 1. x, 2. z, 3. y with moving axes or
367  1. y, 2. z, 3. x with fixed axes.
368  @author esquivel 2014 */
369  int GetRotationAnglesXZY(double& PhiX, double& PhiY, double& PhiZ) const;
370 
371  /** @brief Get Euler angles for this rotation matrix in order XZY
372  @see GetRotationAnglesXZY(double&, double&, double&) */
374  { return GetRotationAnglesXZY(r[0], r[1], r[2]); }
375 
376  // DLL HACK (jw)
377  friend bool BIASGeometryBase_EXPORT
378  operator==(const RMatrixBase& left, const RMatrixBase& right);
379 
380  /** @brief Check if this is a rotation matrix, i.e. if the determinant
381  is +1 and the columns are orthonormal
382  @param eps Numerical limit for constraint evaluation
383  @param verbose Show reason in case of failure */
384  bool Check(const double eps =
385  std::numeric_limits<double>::epsilon(),
386  const bool verbose = false) const;
387 
388  /** @brief Return the reason for the constraint check failure in a
389  human readable string
390  @param eps Numerical limit for constraint evaluation
391  @return empty string when check succeeds, error message otherwise */
392  std::string GetCheckFailureReason(const double eps =
393  std::numeric_limits<double>::epsilon()) const;
394 
395  /** @brief Enforce orthonormality constraint on rotation matrix and
396  sets determinant to +1 */
397  virtual void EnforceConstraints();
398 
399  /** @brief Setting to zero is forbidden since the zero matrix is not
400  a valid rotation matrix! */
401  void SetZero() { BIASABORT; }
402 
403  }; // class
404 
405 } // namespace BIAS
406 
407 
408 #endif // __RMatrixBase_hh__
MatrixInitType
can be passed to matrix constructors to init the matrix with the most often used values ...
Definition: Matrix.hh:59
void SetYXZ(const Vector3< ROTATION_MATRIX_TYPE > &r)
Set Euler angles (in rad) in order YXZ from vector.
Definition: RMatrixBase.hh:179
void SetZero()
Setting to zero is forbidden since the zero matrix is not a valid rotation matrix! ...
Definition: RMatrixBase.hh:401
class BIASGeometryBase_EXPORT RMatrixBase
Definition: PMatrixBase.hh:52
void SetXYZ(const Vector3< ROTATION_MATRIX_TYPE > &r)
Set Euler angles (in rad) in order XYZ from vector.
Definition: RMatrixBase.hh:101
int GetRotationAnglesZXY(Vector3< ROTATION_MATRIX_TYPE > &r) const
Get Euler angles for this rotation matrix in order ZXY.
Definition: RMatrixBase.hh:337
int GetRotationAnglesYXZ(Vector3< ROTATION_MATRIX_TYPE > &r) const
Get Euler angles for this rotation matrix in order YXZ.
Definition: RMatrixBase.hh:349
int GetRotationAnglesYZX(Vector3< ROTATION_MATRIX_TYPE > &r) const
Get Euler angles for this rotation matrix in order YZX.
Definition: RMatrixBase.hh:361
void SetXZY(const Vector3< ROTATION_MATRIX_TYPE > &r)
Set Euler angles (in rad) in order XZY from vector.
Definition: RMatrixBase.hh:193
void SetYZX(const Vector3< ROTATION_MATRIX_TYPE > &r)
Set Euler angles (in rad) in order YZX from vector.
Definition: RMatrixBase.hh:208
is a &#39;fixed size&#39; quadratic matrix of dim.
Definition: Matrix.hh:54
class Vector3 contains a Vector of fixed dim.
Definition: Matrix.hh:53
Implements a 3D rotation matrix.
Definition: RMatrixBase.hh:44
int GetRotationAnglesXYZ(Vector3< ROTATION_MATRIX_TYPE > &r) const
Get Euler angles for this rotation matrix in order XYZ.
Definition: RMatrixBase.hh:310
void SetZXY(const Vector3< ROTATION_MATRIX_TYPE > &r)
Set Euler angles (in rad) in order ZXY from vector.
Definition: RMatrixBase.hh:157
class for rotation with axis and angle
int GetRotationAnglesXZY(Vector3< ROTATION_MATRIX_TYPE > &r) const
Get Euler angles for this rotation matrix in order XZY.
Definition: RMatrixBase.hh:373
int GetRotationAnglesZYX(Vector3< ROTATION_MATRIX_TYPE > &r) const
Get Euler angles for this rotation matrix in order ZYX.
Definition: RMatrixBase.hh:324
void SetZYX(const Vector3< ROTATION_MATRIX_TYPE > &r)
Set Euler angles (in rad) in order ZYX from vector.
Definition: RMatrixBase.hh:129