ViSP  2.10.0
vpThetaUVector.cpp
1 /****************************************************************************
2 *
3 * $Id: vpThetaUVector.cpp 4792 2014-07-18 11:56:02Z 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(p) ;
70 }
75 {
76  buildFrom(R) ;
77 }
78 
84 {
85  buildFrom(rzyx) ;
86 }
92 {
93  buildFrom(rzyz) ;
94 }
100 {
101  buildFrom(rxyz) ;
102 }
103 
109 {
111 
112  M.extract(R);
113  buildFrom(R);
114 
115  return *this ;
116 }
122 {
123  for(unsigned int i=0; i<3; i++)
124  r[i] = p[i+3];
125 
126  return *this ;
127 }
128 
134 {
135  double s,c,theta,sinc;
136 
137  s = (R[1][0]-R[0][1])*(R[1][0]-R[0][1])
138  + (R[2][0]-R[0][2])*(R[2][0]-R[0][2])
139  + (R[2][1]-R[1][2])*(R[2][1]-R[1][2]);
140  s = sqrt(s)/2.0;
141  c = (R[0][0]+R[1][1]+R[2][2]-1.0)/2.0;
142  theta=atan2(s,c); /* theta in [0, PI] since s > 0 */
143 
144  // General case when theta != pi. If theta=pi, c=-1
145  if ( (1+c) > minimum) // Since -1 <= c <= 1, no fabs(1+c) is required
146  {
147  sinc = vpMath::sinc(s,theta);
148 
149  r[0] = (R[2][1]-R[1][2])/(2*sinc);
150  r[1] = (R[0][2]-R[2][0])/(2*sinc);
151  r[2] = (R[1][0]-R[0][1])/(2*sinc);
152  }
153  else /* theta near PI */
154  {
155  if ( (R[0][0]-c) < std::numeric_limits<double>::epsilon() )
156  r[0] = 0.;
157  else
158  r[0] = theta*(sqrt((R[0][0]-c)/(1-c)));
159  if ((R[2][1]-R[1][2]) < 0) r[0] = -r[0];
160 
161  if ( (R[1][1]-c) < std::numeric_limits<double>::epsilon() )
162  r[1] = 0.;
163  else
164  r[1] = theta*(sqrt((R[1][1]-c)/(1-c)));
165 
166  if ((R[0][2]-R[2][0]) < 0) r[1] = -r[1];
167 
168  if ( (R[2][2]-c) < std::numeric_limits<double>::epsilon() )
169  r[2] = 0.;
170  else
171  r[2] = theta*(sqrt((R[2][2]-c)/(1-c)));
172 
173  if ((R[1][0]-R[0][1]) < 0) r[2] = -r[2];
174  }
175 
176 #if (vpDEBUG_LEVEL1) // test new version wrt old version
177  {
178  // old version
179  int i;
180  // double s,c;
181  double ang;
182  double r2[3]; // has to be replaced by r below if good version
183 
184  s = (R[1][0]-R[0][1])*(R[1][0]-R[0][1])
185  + (R[2][0]-R[0][2])*(R[2][0]-R[0][2])
186  + (R[2][1]-R[1][2])*(R[2][1]-R[1][2]);
187  s = sqrt(s)/2.0;
188  c = (R[0][0]+R[1][1]+R[2][2]-1)/2.0;
189  ang=atan2(s,c);
190  if (ang > minimum)
191  {
192  if (s > minimum)
193  {
194  r2[0] = (R[2][1]-R[1][2])/(2*s);
195  r2[1] = (R[0][2]-R[2][0])/(2*s);
196  r2[2] = (R[1][0]-R[0][1])/(2*s);
197  }
198  else
199  {
200  r2[0] = (sqrt((R[0][0]-c)/(1-c)));
201  if ((R[2][1]-R[1][2]) < 0) r2[0] = -r2[0];
202  r2[1] = (sqrt((R[1][1]-c)/(1-c)));
203  if ((R[0][2]-R[2][0]) < 0) r2[1] = -r2[1];
204  r2[2] = (sqrt((R[2][2]-c)/(1-c)));
205  if ((R[1][0]-R[0][1]) < 0) r2[2] = -r2[2];
206  }
207  for (i=0;i<3;i++) r2[i] = r2[i]*ang;
208  }
209  else
210  {
211  r2[0] = r2[1] = r2[2] = 0.0;
212  }
213  // end old version
214  // verification of the new version
215  int pb = 0;
216 
217  for (i=0;i<3;i++)
218  {
219  if (fabs(r[i] - r2[i]) > 1e-5) pb = 1;
220  }
221  if (pb == 1)
222  {
223  printf("vpThetaUVector::buildFrom(const vpRotationMatrix& R)\n");
224  printf(" r : %lf %lf %lf\n",r[0],r[1],r[2]);
225  printf(" r2 : %lf %lf %lf\n",r2[0],r2[1],r2[2]);
226  printf(" r - r2 : %lf %lf %lf\n",r[0]-r2[0],r[1]-r2[1],r[2]-r2[2]);
227  }
228  // end of the verification
229  }
230 #endif
231  return *this ;
232 }
239 {
240  vpRotationMatrix R(rzyx) ;
241 
242  buildFrom(R) ;
243  return *this ;
244 }
251 {
252  vpRotationMatrix R(rzyz) ;
253 
254  buildFrom(R) ;
255  return *this ;
256 }
263 {
264  vpRotationMatrix R(rxyz) ;
265 
266  buildFrom(R) ;
267  return *this ;
268 }
269 
292 {
293  for (int i=0; i< 3; i++)
294  r[i] = v;
295 
296  return *this;
297 }
298 
310 void
311 vpThetaUVector::extract(double &theta, vpColVector &u) const
312 {
313  u.resize(3);
314 
315  theta = sqrt(r[0]*r[0] + r[1]*r[1] + r[2]*r[2]);
316  //if (theta == 0) {
317  if (std::fabs(theta) <= std::numeric_limits<double>::epsilon()) {
318  u = 0;
319  return;
320  }
321  for (unsigned int i=0 ; i < 3 ; i++)
322  u[i] = r[i] / theta ;
323 }
324 
325 #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
The pose is a complete representation of every rigid motion in the euclidian space.
Definition: vpPoseVector.h:92
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:98