Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpThetaUVector.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Theta U parameterization for the rotation.
32  *
33  * Authors:
34  * Eric Marchand
35  *
36  *****************************************************************************/
37 
44 #include <cmath> // std::fabs
45 #include <limits> // numeric_limits
46 
47 #include <visp3/core/vpThetaUVector.h>
48 
49 const double vpThetaUVector::minimum = 0.0001;
50 
53  : vpRotationVector(3)
54 {}
57  : vpRotationVector(tu)
58 {}
61  : vpRotationVector(3)
62 {
63  if (tu.size() != 3) {
64  throw(vpException(vpException::dimensionError, "Cannot construct a theta-u vector from a %d-dimension col vector", tu.size()));
65  }
66  for (unsigned int i=0; i< 3; i++)
67  data[i] = tu[i];
68 }
69 
74  : vpRotationVector(3)
75 {
76  buildFrom(M) ;
77 }
82  : vpRotationVector(3)
83 {
84  buildFrom(p) ;
85 }
90  : vpRotationVector(3)
91 {
92  buildFrom(R) ;
93 }
94 
100  : vpRotationVector(3)
101 {
102  buildFrom(rzyx) ;
103 }
109  : vpRotationVector(3)
110 {
111  buildFrom(rzyz) ;
112 }
118  : vpRotationVector(3)
119 {
120  buildFrom(rxyz) ;
121 }
127  : vpRotationVector(4)
128 {
129  buildFrom(q) ;
130 }
131 
135 vpThetaUVector::vpThetaUVector(const double tux, const double tuy, const double tuz)
136  : vpRotationVector (3)
137 {
138  buildFrom(tux, tuy, tuz);
139 }
140 
146 {
148 
149  M.extract(R);
150  buildFrom(R);
151 
152  return *this ;
153 }
160 {
161  for(unsigned int i=0; i<3; i++)
162  data[i] = p[i+3];
163 
164  return *this ;
165 }
166 
172 {
173  double s,c,theta;
174 
175  s = (R[1][0]-R[0][1])*(R[1][0]-R[0][1])
176  + (R[2][0]-R[0][2])*(R[2][0]-R[0][2])
177  + (R[2][1]-R[1][2])*(R[2][1]-R[1][2]);
178  s = sqrt(s)/2.0;
179  c = (R[0][0]+R[1][1]+R[2][2]-1.0)/2.0;
180  theta=atan2(s,c); /* theta in [0, PI] since s > 0 */
181 
182  // General case when theta != pi. If theta=pi, c=-1
183  if ( (1+c) > minimum) // Since -1 <= c <= 1, no fabs(1+c) is required
184  {
185  double sinc = vpMath::sinc(s,theta);
186 
187  data[0] = (R[2][1]-R[1][2])/(2*sinc);
188  data[1] = (R[0][2]-R[2][0])/(2*sinc);
189  data[2] = (R[1][0]-R[0][1])/(2*sinc);
190  }
191  else /* theta near PI */
192  {
193  if ( (R[0][0]-c) < std::numeric_limits<double>::epsilon() )
194  data[0] = 0.;
195  else
196  data[0] = theta*(sqrt((R[0][0]-c)/(1-c)));
197  if ((R[2][1]-R[1][2]) < 0) data[0] = -data[0];
198 
199  if ( (R[1][1]-c) < std::numeric_limits<double>::epsilon() )
200  data[1] = 0.;
201  else
202  data[1] = theta*(sqrt((R[1][1]-c)/(1-c)));
203 
204  if ((R[0][2]-R[2][0]) < 0) data[1] = -data[1];
205 
206  if ( (R[2][2]-c) < std::numeric_limits<double>::epsilon() )
207  data[2] = 0.;
208  else
209  data[2] = theta*(sqrt((R[2][2]-c)/(1-c)));
210 
211  if ((R[1][0]-R[0][1]) < 0) data[2] = -data[2];
212  }
213 
214  return *this ;
215 }
222 {
223  vpRotationMatrix R(rzyx) ;
224 
225  buildFrom(R) ;
226  return *this ;
227 }
234 {
235  vpRotationMatrix R(rzyz) ;
236 
237  buildFrom(R) ;
238  return *this ;
239 }
246 {
247  vpRotationMatrix R(rxyz) ;
248 
249  buildFrom(R) ;
250  return *this ;
251 }
252 
259 {
260  vpRotationMatrix R(q) ;
261 
262  buildFrom(R) ;
263  return *this ;
264 }
265 
288 {
289  for (unsigned int i=0; i< dsize; i++)
290  data[i] = v;
291 
292  return *this;
293 }
294 
317 {
318  if (tu.size() != 3) {
319  throw(vpException(vpException::dimensionError, "Cannot set a theta-u vector from a %d-dimension col vector", tu.size()));
320  }
321  for (unsigned int i=0; i< 3; i++)
322  data[i] = tu[i];
323 
324  return *this;
325 }
326 
355 void
356 vpThetaUVector::extract(double &theta, vpColVector &u) const
357 {
358  u.resize(3);
359 
360  theta = getTheta();
361  //if (theta == 0) {
362  if (std::fabs(theta) <= std::numeric_limits<double>::epsilon()) {
363  u = 0;
364  return;
365  }
366  for (unsigned int i=0 ; i < 3 ; i++)
367  u[i] = data[i] / theta ;
368 }
369 
392 {
393  return sqrt(data[0]*data[0] + data[1]*data[1] + data[2]*data[2]);
394 }
395 
419 {
420  vpColVector u(3);
421 
422  double theta = getTheta();
423  //if (theta == 0) {
424  if (std::fabs(theta) <= std::numeric_limits<double>::epsilon()) {
425  u = 0;
426  return u;
427  }
428  for (unsigned int i=0 ; i < 3 ; i++)
429  u[i] = data[i] / theta;
430  return u;
431 }
432 
433 
437 void
438 vpThetaUVector::buildFrom(const double tux, const double tuy, const double tuz)
439 {
440  data[0] = tux;
441  data[1] = tuy;
442  data[2] = tuz;
443 }
vpThetaUVector & operator=(const vpColVector &tu)
Implementation of a generic rotation vector.
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpColVector getU() const
error that can be emited by ViSP classes.
Definition: vpException.h:73
double * data
Address of the first element of the data array.
Definition: vpArray2D.h:84
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:156
Implementation of a rotation vector as Euler angle minimal representation.
Definition: vpRzyxVector.h:152
vpThetaUVector buildFrom(const vpHomogeneousMatrix &M)
static double sinc(double x)
Definition: vpMath.cpp:169
Implementation of a rotation matrix and operations on such kind of matrices.
void extract(double &theta, vpColVector &u) const
void extract(vpRotationMatrix &R) const
Implementation of a rotation vector as quaternion angle minimal representation.
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
double getTheta() const
Implementation of a pose vector and operations on poses.
Definition: vpPoseVector.h:93
Implementation of a rotation vector as Euler angle minimal representation.
Definition: vpRxyzVector.h:154
unsigned int dsize
Current array size (rowNum * colNum)
Definition: vpArray2D.h:80
Implementation of a rotation vector as Euler angle minimal representation.
Definition: vpRzyzVector.h:151
Implementation of a rotation vector as axis-angle minimal representation.
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:225