ViSP  2.9.0
vpThetaUVector.cpp
1 /****************************************************************************
2 *
3 * $Id: vpThetaUVector.cpp 4632 2014-02-03 17:06:40Z fspindle $
4 *
5 * This file is part of the ViSP software.
6 * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7 *
8 * This software is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * ("GPL") version 2 as published by the Free Software Foundation.
11 * See the file LICENSE.txt at the root directory of this source
12 * distribution for additional information about the GNU GPL.
13 *
14 * For using ViSP with software that can not be combined with the GNU
15 * GPL, please contact INRIA about acquiring a ViSP Professional
16 * Edition License.
17 *
18 * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19 *
20 * This software was developed at:
21 * INRIA Rennes - Bretagne Atlantique
22 * Campus Universitaire de Beaulieu
23 * 35042 Rennes Cedex
24 * France
25 * http://www.irisa.fr/lagadic
26 *
27 * If you have questions regarding the use of this file, please contact
28 * INRIA at visp@inria.fr
29 *
30 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32 *
33 *
34 * Description:
35 * Theta U parameterization for the rotation.
36 *
37 * Authors:
38 * Eric Marchand
39 *
40 *****************************************************************************/
41 
50 #include <visp/vpThetaUVector.h>
51 #include <cmath> // std::fabs
52 #include <limits> // numeric_limits
53 #define vpDEBUG_LEVEL1 0
54 
55 const double vpThetaUVector::minimum = 0.0001;
56 
61 {
62  buildFrom(M) ;
63 }
68 {
69  buildFrom(R) ;
70 }
71 
77 {
78  buildFrom(rzyx) ;
79 }
85 {
86  buildFrom(rzyz) ;
87 }
93 {
94  buildFrom(rxyz) ;
95 }
96 
102 {
104 
105  M.extract(R);
106  buildFrom(R);
107 
108  return *this ;
109 }
110 
116 {
117  double s,c,theta,sinc;
118 
119  s = (R[1][0]-R[0][1])*(R[1][0]-R[0][1])
120  + (R[2][0]-R[0][2])*(R[2][0]-R[0][2])
121  + (R[2][1]-R[1][2])*(R[2][1]-R[1][2]);
122  s = sqrt(s)/2.0;
123  c = (R[0][0]+R[1][1]+R[2][2]-1.0)/2.0;
124  theta=atan2(s,c); /* theta in [0, PI] since s > 0 */
125 
126  // General case when theta != pi. If theta=pi, c=-1
127  if ( (1+c) > minimum) // Since -1 <= c <= 1, no fabs(1+c) is required
128  {
129  sinc = vpMath::sinc(s,theta);
130 
131  r[0] = (R[2][1]-R[1][2])/(2*sinc);
132  r[1] = (R[0][2]-R[2][0])/(2*sinc);
133  r[2] = (R[1][0]-R[0][1])/(2*sinc);
134  }
135  else /* theta near PI */
136  {
137  if ( (R[0][0]-c) < std::numeric_limits<double>::epsilon() )
138  r[0] = 0.;
139  else
140  r[0] = theta*(sqrt((R[0][0]-c)/(1-c)));
141  if ((R[2][1]-R[1][2]) < 0) r[0] = -r[0];
142 
143  if ( (R[1][1]-c) < std::numeric_limits<double>::epsilon() )
144  r[1] = 0.;
145  else
146  r[1] = theta*(sqrt((R[1][1]-c)/(1-c)));
147 
148  if ((R[0][2]-R[2][0]) < 0) r[1] = -r[1];
149 
150  if ( (R[2][2]-c) < std::numeric_limits<double>::epsilon() )
151  r[2] = 0.;
152  else
153  r[2] = theta*(sqrt((R[2][2]-c)/(1-c)));
154 
155  if ((R[1][0]-R[0][1]) < 0) r[2] = -r[2];
156  }
157 
158 #if (vpDEBUG_LEVEL1) // test new version wrt old version
159  {
160  // old version
161  int i;
162  // double s,c;
163  double ang;
164  double r2[3]; // has to be replaced by r below if good version
165 
166  s = (R[1][0]-R[0][1])*(R[1][0]-R[0][1])
167  + (R[2][0]-R[0][2])*(R[2][0]-R[0][2])
168  + (R[2][1]-R[1][2])*(R[2][1]-R[1][2]);
169  s = sqrt(s)/2.0;
170  c = (R[0][0]+R[1][1]+R[2][2]-1)/2.0;
171  ang=atan2(s,c);
172  if (ang > minimum)
173  {
174  if (s > minimum)
175  {
176  r2[0] = (R[2][1]-R[1][2])/(2*s);
177  r2[1] = (R[0][2]-R[2][0])/(2*s);
178  r2[2] = (R[1][0]-R[0][1])/(2*s);
179  }
180  else
181  {
182  r2[0] = (sqrt((R[0][0]-c)/(1-c)));
183  if ((R[2][1]-R[1][2]) < 0) r2[0] = -r2[0];
184  r2[1] = (sqrt((R[1][1]-c)/(1-c)));
185  if ((R[0][2]-R[2][0]) < 0) r2[1] = -r2[1];
186  r2[2] = (sqrt((R[2][2]-c)/(1-c)));
187  if ((R[1][0]-R[0][1]) < 0) r2[2] = -r2[2];
188  }
189  for (i=0;i<3;i++) r2[i] = r2[i]*ang;
190  }
191  else
192  {
193  r2[0] = r2[1] = r2[2] = 0.0;
194  }
195  // end old version
196  // verification of the new version
197  int pb = 0;
198 
199  for (i=0;i<3;i++)
200  {
201  if (fabs(r[i] - r2[i]) > 1e-5) pb = 1;
202  }
203  if (pb == 1)
204  {
205  printf("vpThetaUVector::buildFrom(const vpRotationMatrix& R)\n");
206  printf(" r : %lf %lf %lf\n",r[0],r[1],r[2]);
207  printf(" r2 : %lf %lf %lf\n",r2[0],r2[1],r2[2]);
208  printf(" r - r2 : %lf %lf %lf\n",r[0]-r2[0],r[1]-r2[1],r[2]-r2[2]);
209  }
210  // end of the verification
211  }
212 #endif
213  return *this ;
214 }
221 {
222  vpRotationMatrix R(rzyx) ;
223 
224  buildFrom(R) ;
225  return *this ;
226 }
233 {
234  vpRotationMatrix R(rzyz) ;
235 
236  buildFrom(R) ;
237  return *this ;
238 }
245 {
246  vpRotationMatrix R(rxyz) ;
247 
248  buildFrom(R) ;
249  return *this ;
250 }
251 
274 {
275  for (int i=0; i< 3; i++)
276  r[i] = v;
277 
278  return *this;
279 }
280 
292 void
293 vpThetaUVector::extract(double &theta, vpColVector &u) const
294 {
295  u.resize(3);
296 
297  theta = sqrt(r[0]*r[0] + r[1]*r[1] + r[2]*r[2]);
298  //if (theta == 0) {
299  if (std::fabs(theta) <= std::numeric_limits<double>::epsilon()) {
300  u = 0;
301  return;
302  }
303  for (unsigned int i=0 ; i < 3 ; i++)
304  u[i] = r[i] / theta ;
305 }
306 
307 #undef vpDEBUG_LEVEL1
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
Class that consider the case of the Euler angle using the z-y-x convention, where are respectively ...
Definition: vpRzyxVector.h:151
vpThetaUVector buildFrom(const vpHomogeneousMatrix &M)
static double sinc(double x)
Definition: vpMath.h:301
The vpRotationMatrix considers the particular case of a rotation matrix.
vpThetaUVector & operator=(double x)
void extract(double &theta, vpColVector &u) const
void extract(vpRotationMatrix &R) const
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
Class that consider the case of the Euler angle using the x-y-z convention, where are respectively ...
Definition: vpRxyzVector.h:152
Class that consider the case of the Euler angles using the z-y-z convention, where are respectively...
Definition: vpRzyzVector.h:150
Class that consider the case of the parameterization for the rotation.
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:94