ViSP  2.10.0
vpCircle.cpp
1 /****************************************************************************
2  *
3  * $Id: vpCircle.cpp 4772 2014-07-10 17:05:53Z 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  * Visual feature circle.
36  *
37  * Authors:
38  * Eric Marchand
39  *
40  *****************************************************************************/
41 
42 
43 #include <visp/vpCircle.h>
44 
45 #include <visp/vpFeatureDisplay.h>
46 
47 void
49 {
50 
51  oP.resize(7) ;
52  cP.resize(7) ;
53 
54  p.resize(5) ;
55 }
56 
65 void
67 {
68  this->oP = oP_ ;
69 }
70 
83 void
84 vpCircle::setWorldCoordinates(const double A, const double B, const double C,
85  const double X0, const double Y0, const double Z0,
86  const double R)
87 {
88  oP[0] = A ;
89  oP[1] = B ;
90  oP[2] = C ;
91  oP[3] = X0 ;
92  oP[4] = Y0 ;
93  oP[5] = Z0 ;
94  oP[6] = R ;
95 }
96 
97 
98 
100 {
101  init() ;
102 }
103 
114 {
115  init() ;
116  setWorldCoordinates(oP_) ;
117 }
118 
132 vpCircle::vpCircle(const double A, const double B,
133  const double C,
134  const double X0, const double Y0,
135  const double Z0,
136  const double R)
137 {
138  init() ;
139  setWorldCoordinates(A, B, C,
140  X0, Y0, Z0,
141  R) ;
142 }
143 
145 {
146 }
147 
148 
149 
150 
158 void
160 {
161  projection(cP,p) ;
162 }
163 
176 void
178 {
179  vpColVector K(6) ;
180  {
181  double A = cP_[0] ;
182  double B = cP_[1] ;
183  double C = cP_[2] ;
184 
185  double X0 = cP_[3] ;
186  double Y0 = cP_[4] ;
187  double Z0 = cP_[5] ;
188 
189  double r = cP_[6];
190 
191  // projection
192  double s = X0*X0 + Y0*Y0 + Z0*Z0 - r*r ;
193  double det = A*X0+B*Y0+C*Z0;
194  A = A/det ;
195  B = B/det ;
196  C = C/det ;
197 
198  K[0] = 1 - 2*A*X0 + A*A*s;
199  K[1] = 1 - 2*B*Y0 + B*B*s;
200  K[2] = -A*Y0 - B*X0 + A*B*s;
201  K[3] = -C*X0 - A*Z0 + A*C*s;
202  K[4] = -C*Y0 - B*Z0 + B*C*s;
203  K[5] = 1 - 2*C*Z0 + C*C*s;
204 
205  }
206 
207 // {
208 // std::cout << "K dans vpCircle::projection(): " << std::endl;
209 // for (unsigned int i=1; i<6; i++)
210 // std::cout << K[i]/K[0] << std::endl;
211 // }
212  double det = K[2]*K[2] -K[0]*K[1];
213  if (fabs(det) < 1e-8)
214  {
215  vpERROR_TRACE("division par 0") ;
217  "division par 0")) ;
218  }
219 
220  double xc = (K[1]*K[3]-K[2]*K[4])/det;
221  double yc = (K[0]*K[4]-K[2]*K[3])/det;
222 
223  double c = sqrt( (K[0]-K[1])*(K[0]-K[1]) + 4*K[2]*K[2] );
224  double s = 2*(K[0]*xc*xc + 2*K[2]*xc*yc + K[1]*yc*yc - K[5]);
225 
226  double A,B,E ;
227 
228  //if (fabs(K[2])<1e-6)
229  if (fabs(K[2])<std::numeric_limits<double>::epsilon())
230  {
231  E = 0.0;
232  if (K[0] > K[1])
233  {
234  A = sqrt(s/(K[0] + K[1] + c));
235  B = sqrt(s/(K[0] + K[1] - c));
236  }
237  else
238  {
239  A = sqrt(s/(K[0] + K[1] - c));
240  B = sqrt(s/(K[0] + K[1] + c));
241  }
242  }
243  else
244  {
245  E = (K[1] - K[0] + c)/(2*K[2]);
246  if ( fabs(E) > 1.0)
247  {
248  A = sqrt(s/(K[0] + K[1] + c));
249  B = sqrt(s/(K[0] + K[1] - c));
250  }
251  else
252  {
253  A = sqrt(s/(K[0] + K[1] - c));
254  B = sqrt(s/(K[0] + K[1] + c));
255  E = -1.0/E;
256  }
257  }
258 
259  det = (1.0 + vpMath::sqr(E));
260  double mu20 = (vpMath::sqr(A) + vpMath::sqr(B*E)) /det ;
261  double mu11 = (vpMath::sqr(A) - vpMath::sqr(B)) *E / det ;
262  double mu02 = (vpMath::sqr(B) + vpMath::sqr(A*E)) / det ;
263 
264  p_[0] = xc ;
265  p_[1] = yc ;
266  p_[2] = mu20 ;
267  p_[3] = mu11 ;
268  p_[4] = mu02 ;
269 }
270 
272 void
274 {
275 
276  double A,B,C ;
277  A = cMo[0][0]*oP[0] + cMo[0][1]*oP[1] + cMo[0][2]*oP[2];
278  B = cMo[1][0]*oP[0] + cMo[1][1]*oP[1] + cMo[1][2]*oP[2];
279  C = cMo[2][0]*oP[0] + cMo[2][1]*oP[1] + cMo[2][2]*oP[2];
280 
281  double X0,Y0,Z0 ;
282  X0 = cMo[0][3] + cMo[0][0]*oP[3] + cMo[0][1]*oP[4] + cMo[0][2]*oP[5];
283  Y0 = cMo[1][3] + cMo[1][0]*oP[3] + cMo[1][1]*oP[4] + cMo[1][2]*oP[5];
284  Z0 = cMo[2][3] + cMo[2][0]*oP[3] + cMo[2][1]*oP[4] + cMo[2][2]*oP[5];
285  double R = oP[6] ;
286 
287  cP_[0] = A ;
288  cP_[1] = B ;
289  cP_[2] = C ;
290 
291  cP_[3] = X0 ;
292  cP_[4] = Y0 ;
293  cP_[5] = Z0 ;
294 
295  cP_[6] = R ;
296 
297  // vpTRACE("_cP :") ; std::cout << _cP.t() ;
298 
299 }
300 
302 void
304 {
305 
306  double A,B,C ;
307  A = cMo[0][0]*oP[0] + cMo[0][1]*oP[1] + cMo[0][2]*oP[2];
308  B = cMo[1][0]*oP[0] + cMo[1][1]*oP[1] + cMo[1][2]*oP[2];
309  C = cMo[2][0]*oP[0] + cMo[2][1]*oP[1] + cMo[2][2]*oP[2];
310 
311  double X0,Y0,Z0 ;
312  X0 = cMo[0][3] + cMo[0][0]*oP[3] + cMo[0][1]*oP[4] + cMo[0][2]*oP[5];
313  Y0 = cMo[1][3] + cMo[1][0]*oP[3] + cMo[1][1]*oP[4] + cMo[1][2]*oP[5];
314  Z0 = cMo[2][3] + cMo[2][0]*oP[3] + cMo[2][1]*oP[4] + cMo[2][2]*oP[5];
315  double R = oP[6] ;
316 
317  cP[0] = A ;
318  cP[1] = B ;
319  cP[2] = C ;
320 
321  cP[3] = X0 ;
322  cP[4] = Y0 ;
323  cP[5] = Z0 ;
324 
325  cP[6] = R ;
326 
327  // vpTRACE("_cP :") ; std::cout << _cP.t() ;
328 
329 }
330 
332  const vpCameraParameters &cam,
333  const vpColor &color,
334  const unsigned int thickness)
335 {
336  vpFeatureDisplay::displayEllipse(p[0],p[1],p[2],p[3], p[4],
337  cam, I, color, thickness) ;
338 }
339 
340 // non destructive wrt. cP and p
342  const vpHomogeneousMatrix &cMo,
343  const vpCameraParameters &cam,
344  const vpColor &color,
345  const unsigned int thickness)
346 {
347  vpColVector _cP, _p ;
348  changeFrame(cMo,_cP) ;
349  projection(_cP,_p) ;
350  vpFeatureDisplay::displayEllipse(_p[0],_p[1],_p[2],_p[3], _p[4],
351  cam, I, color, thickness) ;
352 
353 }
356 {
357  vpCircle *feature = new vpCircle(*this) ;
358  return feature ;
359 }
void init()
Definition: vpCircle.cpp:48
static void displayEllipse(double x, double y, double mu20, double mu11, double m02, const vpCameraParameters &cam, const vpImage< unsigned char > &I, const vpColor &color=vpColor::green, unsigned int thickness=1)
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &cP)
perspective projection of the circle
Definition: vpCircle.cpp:273
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
#define vpERROR_TRACE
Definition: vpDebug.h:395
Class to define colors available for display functionnalities.
Definition: vpColor.h:125
error that can be emited by ViSP classes.
Definition: vpException.h:76
virtual ~vpCircle()
Definition: vpCircle.cpp:144
vpColVector cP
Definition: vpTracker.h:82
void projection()
Definition: vpCircle.cpp:159
vpCircle()
Definition: vpCircle.cpp:99
static double sqr(double x)
Definition: vpMath.h:106
vpCircle * duplicate() const
for memory issue (used by the vpServo class only)
Definition: vpCircle.cpp:355
Generic class defining intrinsic camera parameters.
void display(const vpImage< unsigned char > &I, const vpCameraParameters &cam, const vpColor &color=vpColor::green, const unsigned int thickness=1)
Definition: vpCircle.cpp:331
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 defines what is a circle.
Definition: vpCircle.h:61
vpColVector p
Definition: vpTracker.h:78
void setWorldCoordinates(const vpColVector &oP)
Definition: vpCircle.cpp:66
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:98