ViSP  2.8.0
vpThetaUVector.cpp
1 /****************************************************************************
2 *
3 * $Id: vpThetaUVector.cpp 4056 2013-01-05 13:04:42Z fspindle $
4 *
5 * This file is part of the ViSP software.
6 * Copyright (C) 2005 - 2013 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 
62 {
63  for (int i=0; i<3; i++)
64  {
65  r[i] = m.r[i] ;
66  }
67  return *this;
68 }
69 
70 
75 {
76  *this = m ;
77 }
78 
83 {
84  buildFrom(M) ;
85 }
90 {
91  buildFrom(R) ;
92 }
93 
99 {
100  buildFrom(rzyx) ;
101 }
107 {
108  buildFrom(rzyz) ;
109 }
115 {
116  buildFrom(rxyz) ;
117 }
118 
124 {
126 
127  M.extract(R);
128  buildFrom(R);
129 
130  return *this ;
131 }
132 
138 {
139  double s,c,theta,sinc;
140 
141  s = (R[1][0]-R[0][1])*(R[1][0]-R[0][1])
142  + (R[2][0]-R[0][2])*(R[2][0]-R[0][2])
143  + (R[2][1]-R[1][2])*(R[2][1]-R[1][2]);
144  s = sqrt(s)/2.0;
145  c = (R[0][0]+R[1][1]+R[2][2]-1.0)/2.0;
146  theta=atan2(s,c); /* theta in [0, PI] since s > 0 */
147 
148  // General case when theta != pi. If theta=pi, c=-1
149  if ( (1+c) > minimum) // Since -1 <= c <= 1, no fabs(1+c) is required
150  {
151  sinc = vpMath::sinc(s,theta);
152 
153  r[0] = (R[2][1]-R[1][2])/(2*sinc);
154  r[1] = (R[0][2]-R[2][0])/(2*sinc);
155  r[2] = (R[1][0]-R[0][1])/(2*sinc);
156  }
157  else /* theta near PI */
158  {
159  if ( (R[0][0]-c) < std::numeric_limits<double>::epsilon() )
160  r[0] = 0.;
161  else
162  r[0] = theta*(sqrt((R[0][0]-c)/(1-c)));
163  if ((R[2][1]-R[1][2]) < 0) r[0] = -r[0];
164 
165  if ( (R[1][1]-c) < std::numeric_limits<double>::epsilon() )
166  r[1] = 0.;
167  else
168  r[1] = theta*(sqrt((R[1][1]-c)/(1-c)));
169 
170  if ((R[0][2]-R[2][0]) < 0) r[1] = -r[1];
171 
172  if ( (R[2][2]-c) < std::numeric_limits<double>::epsilon() )
173  r[2] = 0.;
174  else
175  r[2] = theta*(sqrt((R[2][2]-c)/(1-c)));
176 
177  if ((R[1][0]-R[0][1]) < 0) r[2] = -r[2];
178  }
179 
180 #if (vpDEBUG_LEVEL1) // test new version wrt old version
181  {
182  // old version
183  int i;
184  // double s,c;
185  double ang;
186  double r2[3]; // has to be replaced by r below if good version
187 
188  s = (R[1][0]-R[0][1])*(R[1][0]-R[0][1])
189  + (R[2][0]-R[0][2])*(R[2][0]-R[0][2])
190  + (R[2][1]-R[1][2])*(R[2][1]-R[1][2]);
191  s = sqrt(s)/2.0;
192  c = (R[0][0]+R[1][1]+R[2][2]-1)/2.0;
193  ang=atan2(s,c);
194  if (ang > minimum)
195  {
196  if (s > minimum)
197  {
198  r2[0] = (R[2][1]-R[1][2])/(2*s);
199  r2[1] = (R[0][2]-R[2][0])/(2*s);
200  r2[2] = (R[1][0]-R[0][1])/(2*s);
201  }
202  else
203  {
204  r2[0] = (sqrt((R[0][0]-c)/(1-c)));
205  if ((R[2][1]-R[1][2]) < 0) r2[0] = -r2[0];
206  r2[1] = (sqrt((R[1][1]-c)/(1-c)));
207  if ((R[0][2]-R[2][0]) < 0) r2[1] = -r2[1];
208  r2[2] = (sqrt((R[2][2]-c)/(1-c)));
209  if ((R[1][0]-R[0][1]) < 0) r2[2] = -r2[2];
210  }
211  for (i=0;i<3;i++) r2[i] = r2[i]*ang;
212  }
213  else
214  {
215  r2[0] = r2[1] = r2[2] = 0.0;
216  }
217  // end old version
218  // verification of the new version
219  int pb = 0;
220 
221  for (i=0;i<3;i++)
222  {
223  if (fabs(r[i] - r2[i]) > 1e-5) pb = 1;
224  }
225  if (pb == 1)
226  {
227  printf("vpThetaUVector::buildFrom(const vpRotationMatrix& R)\n");
228  printf(" r : %lf %lf %lf\n",r[0],r[1],r[2]);
229  printf(" r2 : %lf %lf %lf\n",r2[0],r2[1],r2[2]);
230  printf(" r - r2 : %lf %lf %lf\n",r[0]-r2[0],r[1]-r2[1],r[2]-r2[2]);
231  }
232  // end of the verification
233  }
234 #endif
235  return *this ;
236 }
243 {
244  vpRotationMatrix R(rzyx) ;
245 
246  buildFrom(R) ;
247  return *this ;
248 }
255 {
256  vpRotationMatrix R(rzyz) ;
257 
258  buildFrom(R) ;
259  return *this ;
260 }
267 {
268  vpRotationMatrix R(rxyz) ;
269 
270  buildFrom(R) ;
271  return *this ;
272 }
273 
296 {
297  for (int i=0; i< 3; i++)
298  r[i] = v;
299 
300  return *this;
301 }
302 
314 void
315 vpThetaUVector::extract(double &theta, vpColVector &u) const
316 {
317  u.resize(3);
318 
319  theta = sqrt(r[0]*r[0] + r[1]*r[1] + r[2]*r[2]);
320  //if (theta == 0) {
321  if (std::fabs(theta) <= std::numeric_limits<double>::epsilon()) {
322  u = 0;
323  return;
324  }
325  for (unsigned int i=0 ; i < 3 ; i++)
326  u[i] = r[i] / theta ;
327 }
328 
329 #undef vpDEBUG_LEVEL1
330 /*
331 * Local variables:
332 * c-basic-offset: 2
333 * End:
334 */
Class that consider the case of a generic rotation vector (cannot be used as is !) consisting in thre...
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.
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
vpThetaUVector & operator=(const vpThetaUVector &tu)
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