Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ExampleRMatrix.cpp
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 
9  BIAS is free software; you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation; either version 2.1 of the License, or
12  (at your option) any later version.
13 
14  BIAS is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with BIAS; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23 
24 /**
25  @example ExampleRMatrix.cpp
26  @relates RMatrixBase
27  @brief Example for rotation matrix usage and conversion.
28  @ingroup g_examples
29  @author MIP
30 */
31 
32 #include <Base/Geometry/RMatrixBase.hh>
33 #include <Base/Geometry/Quaternion.hh>
34 #ifdef WIN32
35 # ifndef strcasecmp
36 # define strcasecmp _strcmpi
37 # endif
38 #endif
39 #include <string.h>
40 #include <stdio.h>
41 #include <iostream>
42 
43 #define ROT_PARAM_Invalid -1
44 #define ROT_PARAM_Rodrigues 0
45 #define ROT_PARAM_Euler 1
46 #define ROT_PARAM_AxisAngle 2
47 #define ROT_PARAM_Quaternion 3
48 
49 #define ROT_ORDER_XYZ 0
50 #define ROT_ORDER_XZY 1
51 #define ROT_ORDER_YXZ 2
52 #define ROT_ORDER_YZX 3
53 #define ROT_ORDER_ZXY 4
54 #define ROT_ORDER_ZYX 5
55 
56 using namespace BIAS;
57 using namespace std;
58 
59 int main(int argc, char *argv[])
60 {
61  int res = 0;
62  bool showUsage = (argc < 5);
63  int paramType = ROT_PARAM_Invalid, angleOrder = ROT_ORDER_XYZ;
64  if (argc > 1) {
65  if (strcasecmp(argv[1], "Rodrigues") == 0)
66  paramType = ROT_PARAM_Rodrigues;
67  else if (strcasecmp(argv[1], "Euler") == 0)
68  paramType = ROT_PARAM_Euler;
69  else if (strcasecmp(argv[1], "EulerXYZ") == 0) {
70  paramType = ROT_PARAM_Euler; angleOrder = ROT_ORDER_XYZ;
71  } else if (strcasecmp(argv[1], "EulerXZY") == 0) {
72  paramType = ROT_PARAM_Euler; angleOrder = ROT_ORDER_XZY;
73  } else if (strcasecmp(argv[1], "EulerYXZ") == 0) {
74  paramType = ROT_PARAM_Euler; angleOrder = ROT_ORDER_YXZ;
75  } else if (strcasecmp(argv[1], "EulerYZX") == 0) {
76  paramType = ROT_PARAM_Euler; angleOrder = ROT_ORDER_YZX;
77  } else if (strcasecmp(argv[1], "EulerZXY") == 0) {
78  paramType = ROT_PARAM_Euler; angleOrder = ROT_ORDER_ZXY;
79  } else if (strcasecmp(argv[1], "EulerZYX") == 0) {
80  paramType = ROT_PARAM_Euler; angleOrder = ROT_ORDER_ZYX;
81  }
82  else if (strcasecmp(argv[1], "AxisAngle") == 0)
83  paramType = ROT_PARAM_AxisAngle;
84  else if (strcasecmp(argv[1], "Quaternion") == 0)
85  paramType = ROT_PARAM_Quaternion;
86  }
87  if (paramType == ROT_PARAM_Invalid)
88  showUsage = true;
89  else if ((paramType == ROT_PARAM_AxisAngle ||
90  paramType == ROT_PARAM_Quaternion) && argc < 6)
91  showUsage = true;
92 
93  if (showUsage) {
94  cout << "USAGE : ExampleRMatrix Rodrigues <wx> <wy> <wz> [<degree?>]" << endl
95  << " or ExampleRMatrix Euler[<order>] <ax> <ay> <az> [<degree?>]" << endl
96  << " or ExampleRMatrix AxisAngle <rx> <ry> <rz> <a> [<degree?>]" << endl
97  << " or ExampleRMatrix Quaternion <qx> <qy> <qz> <qw>" << endl << endl
98  << "Note that rotation angles and the length of the Rodrigues vector" << endl
99  << "are given in radians by default. Euler must be followed by order" << endl
100  << "of rotation angles (e.g. EulerYZX), otherwise order XYZ is used." << endl
101  << "Use parameter degree = 1 to provide angles in degree instead." << endl << endl;
102  return 0;
103  }
104 
105  bool useDegree = false;
106  if (argc > ((paramType > 1) ? 6 : 5))
107  useDegree = (atoi(argv[(paramType > 1) ? 6 : 5]) != 0);
108  double factor = useDegree ? (M_PI / 180.0) : 1.0;
109  RMatrixBase R;
110  switch (paramType)
111  {
112  case ROT_PARAM_Rodrigues:
113  {
114  BIAS::Vector3<double> w(atof(argv[2]), atof(argv[3]), atof(argv[4]));
115  R.SetFromAxisAngle(w * factor);
116  break;
117  }
118  case ROT_PARAM_Euler:
119  {
120  double ax = atof(argv[2]) * factor;
121  double ay = atof(argv[3]) * factor;
122  double az = atof(argv[4]) * factor;
123  switch (angleOrder)
124  {
125  case ROT_ORDER_XYZ: R.SetXYZ(ax, ay, az); break;
126  case ROT_ORDER_XZY: R.SetXZY(ax, ay, az); break;
127  case ROT_ORDER_YXZ: R.SetYXZ(ax, ay, az); break;
128  case ROT_ORDER_YZX: R.SetYZX(ax, ay, az); break;
129  case ROT_ORDER_ZXY: R.SetZXY(ax, ay, az); break;
130  case ROT_ORDER_ZYX: R.SetZYX(ax, ay, az); break;
131  default:
132  cerr << "ERROR : Invalid Euler angle order!" << endl;
133  res = -1;
134  }
135  break;
136  }
137  case ROT_PARAM_AxisAngle:
138  {
139  BIAS::Vector3<double> r(atof(argv[2]), atof(argv[3]), atof(argv[4]));
140  r.Normalize();
141  double a = atof(argv[5]) * factor;
142  R.SetFromAxisAngle(r * a);
143  break;
144  }
145  case ROT_PARAM_Quaternion:
146  {
147  BIAS::Quaternion<double> q(atof(argv[2]), atof(argv[3]), atof(argv[4]), atof(argv[5]));
148  q.Normalize();
149  R.SetFromQuaternion(q);
150  break;
151  }
152  default:
153  cerr << "ERROR : Invalid rotation parameter type!" << endl;
154  res = -2;
155  }
156  if (res < 0) return res;
157 
158  cout << "Rotation matrix is " << R << endl;
159 
160  double ax, ay, az;
161  if (R.GetRotationAnglesXYZ(ax, ay, az) == 0) {
162  cout << "Rotation angles in order XYZ are ax = " << ax * 180 / M_PI << ", ay = "
163  << ay * 180 / M_PI << ", az = " << az * 180 / M_PI << " degree" << endl;
164  } else {
165  cerr << "ERROR : Failed to get rotation angles in order XYZ!" << endl;
166  res = -3;
167  }
168  if (R.GetRotationAnglesZYX(ax, ay, az) == 0) {
169  cout << "Rotation angles in order ZYX are ax = " << ax * 180 / M_PI << ", ay = "
170  << ay * 180 / M_PI << ", az = " << az * 180 / M_PI << " degree" << endl;
171  } else {
172  cerr << "ERROR : Failed to get rotation angles in order ZYX!" << endl;
173  res = -4;
174  }
175  if (R.GetRotationAnglesYXZ(ax, ay, az) == 0) {
176  cout << "Rotation angles in order YXZ are ax = " << ax * 180 / M_PI << ", ay = "
177  << ay * 180 / M_PI << ", az = " << az * 180 / M_PI << " degree" << endl;
178  } else {
179  cerr << "ERROR : Failed to get rotation angles in order YXZ!" << endl;
180  res = -5;
181  }
182  if (R.GetRotationAnglesZXY(ax, ay, az) == 0) {
183  cout << "Rotation angles in order ZXY are ax = " << ax * 180 / M_PI << ", ay = "
184  << ay * 180 / M_PI << ", az = " << az * 180 / M_PI << " degree" << endl;
185  } else {
186  cerr << "ERROR : Failed to get rotation angles in order ZXY!" << endl;
187  res = -6;
188  }
189  if (R.GetRotationAnglesYZX(ax, ay, az) == 0) {
190  cout << "Rotation angles in order YZX are ax = " << ax * 180 / M_PI << ", ay = "
191  << ay * 180 / M_PI << ", az = " << az * 180 / M_PI << " degree" << endl;
192  } else {
193  cerr << "ERROR : Failed to get rotation angles in order YZX!" << endl;
194  res = -7;
195  }
196  if (R.GetRotationAnglesXZY(ax, ay, az) == 0) {
197  cout << "Rotation angles in order XZY are ax = " << ax * 180 / M_PI << ", ay = "
198  << ay * 180 / M_PI << ", az = " << az * 180 / M_PI << " degree" << endl;
199  } else {
200  cerr << "ERROR : Failed to get rotation angles in order XZY!" << endl;
201  res = -8;
202  }
203 
205  if (R.GetQuaternion(q) == 0) {
206  cout << "Unit quaternion is " << q << endl;
207  } else {
208  cerr << "ERROR : Failed to get unit quaternion!" << endl;
209  res = -9;
210  }
211 
213  double a;
214  if (R.GetRotationAxisAngle(r, a) == 0) {
215  cout << "Rotation axis is " << r << endl
216  << "Rotation angle is " << a * 180.0 / M_PI << " degree" << endl;
217  } else {
218  cerr << "ERROR : Failed to get rotation axis/angle!" << endl;
219  res = -10;
220  }
221 
223  if (R.GetRotationAxisAngle(w) == 0) {
224  cout << "Rodrigues vector is " << w << endl;
225  } else {
226  cerr << "ERROR : Failed to get Rodrigues vector!" << endl;
227  res = -11;
228  }
229 
230  return res;
231 }
int GetRotationAnglesZYX(double &PhiX, double &PhiY, double &PhiZ) const
Get Euler angles for this rotation matrix in order ZYX.
void SetXYZ(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY, ROTATION_MATRIX_TYPE PhiZ)
Set Euler angles (in rad) in order XYZ.
void SetXZY(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY, ROTATION_MATRIX_TYPE PhiZ)
Set Euler angles (in rad) in order XZY.
void SetZYX(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY, ROTATION_MATRIX_TYPE PhiZ)
Set Euler angles (in rad) in order ZYX.
int GetRotationAnglesYZX(double &PhiX, double &PhiY, double &PhiZ) const
Get Euler angles for this rotation matrix in order YZX.
int SetFromQuaternion(const Quaternion< ROTATION_MATRIX_TYPE > &q)
Set rotation matrix from a quaternion.
void SetYXZ(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY, ROTATION_MATRIX_TYPE PhiZ)
Set Euler angles (in rad) in order YXZ.
void SetZXY(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY, ROTATION_MATRIX_TYPE PhiZ)
Set Euler angles (in rad) in order ZXY.
int GetQuaternion(Quaternion< ROTATION_MATRIX_TYPE > &quat) const
Calculates quaternion representation for this rotation matrix.
int GetRotationAnglesXZY(double &PhiX, double &PhiY, double &PhiZ) const
Get Euler angles for this rotation matrix in order XZY.
int GetRotationAnglesZXY(double &PhiX, double &PhiY, double &PhiZ) const
Get Euler angles for this rotation matrix in order ZXY.
void SetFromAxisAngle(Vector3< ROTATION_MATRIX_TYPE > w)
Set from rotation axis * angle (modified Rodrigues vector)
int GetRotationAnglesXYZ(double &PhiX, double &PhiY, double &PhiZ) const
Get Euler angles for this rotation matrix in order XYZ.
Implements a 3D rotation matrix.
Definition: RMatrixBase.hh:44
int GetRotationAxisAngle(Vector3< ROTATION_MATRIX_TYPE > &axis, ROTATION_MATRIX_TYPE &angle) const
Calculates angle and rotation axis representation for this rotation matrix.
int GetRotationAnglesYXZ(double &PhiX, double &PhiY, double &PhiZ) const
Get Euler angles for this rotation matrix in order YXZ.
void SetYZX(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY, ROTATION_MATRIX_TYPE PhiZ)
Set Euler angles (in rad) in order YZX.