Visual Servoing Platform  version 3.6.1 under development (2025-01-20)
vpSphere.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
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 https://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  * Sphere feature.
32  *
33 *****************************************************************************/
34 
35 #include <visp3/core/vpFeatureDisplay.h>
36 #include <visp3/core/vpSphere.h>
37 
38 BEGIN_VISP_NAMESPACE
43 {
44  const unsigned int val_4 = 4;
45  const unsigned int val_5 = 5;
46  oP.resize(val_4);
47  cP.resize(val_4);
48 
49  p.resize(val_5);
50 }
51 
61 void vpSphere::setWorldCoordinates(const vpColVector &oP_) { this->oP = oP_; }
62 
72 void vpSphere::setWorldCoordinates(double oX, double oY, double oZ, double R)
73 {
74  const unsigned int index_0 = 0;
75  const unsigned int index_1 = 1;
76  const unsigned int index_2 = 2;
77  const unsigned int index_3 = 3;
78  oP[index_0] = oX;
79  oP[index_1] = oY;
80  oP[index_2] = oZ;
81  oP[index_3] = R;
82 }
83 
88 
98 {
99  init();
100  setWorldCoordinates(oP_);
101 }
102 
112 vpSphere::vpSphere(double oX, double oY, double oZ, double R)
113 {
114  init();
115  setWorldCoordinates(oX, oY, oZ, R);
116 }
117 
126 
141 void vpSphere::projection(const vpColVector &cP_, vpColVector &p_) const
142 {
143  const unsigned int val_5 = 5;
144  p_.resize(val_5, false);
145  double x0, y0, z0;
146  double E, A, B;
147  const unsigned int index_0 = 0;
148  const unsigned int index_1 = 1;
149  const unsigned int index_2 = 2;
150  const unsigned int index_3 = 3;
151  const unsigned int index_4 = 4;
152 
153  // calcul des parametres M20, M11, M02 de l'ellipse
154  double s, r;
155  r = cP_[index_3];
156 
157  x0 = cP_[index_0];
158  y0 = cP_[index_1];
159  z0 = cP_[index_2];
160 
161  s = (r * r) - (y0 * y0) - (z0 * z0);
162 
163  if ((s = ((z0 * z0) - (r * r))) < 0.0) {
164  throw(vpException(vpException::fatalError, "Error: Sphere is behind image plane"));
165  }
166 
167  p_[0] = (x0 * z0) / s; // x
168  p_[1] = (y0 * z0) / s; // y
169 
170  if (fabs(x0) > 1e-6) {
171  double e = y0 / x0;
172  double b = r / sqrt(s);
173  double a = ((x0 * x0) + (y0 * y0) + (z0 * z0)) - (r * r);
174  if (a < 0.0) {
175  throw(vpException(vpException::fatalError, "Error: Sphere is behind image plane"));
176  }
177  a = (r * sqrt(a)) / s;
178  if (fabs(e) <= 1.0) {
179  E = e;
180  A = a;
181  B = b;
182  }
183  else {
184  E = -1.0 / e;
185  A = b;
186  B = a;
187  }
188  }
189  else {
190  E = 0.0;
191  A = r / sqrt(s);
192  B = (r * sqrt(((y0 * y0) + (z0 * z0)) - (r * r))) / s;
193  }
194 
195  // Chaumette PhD Thesis 1990, eq 2.72 divided by 4 since n_ij = mu_ij_chaumette_thesis / 4
196  double det = 4 * (1.0 + vpMath::sqr(E));
197  double n20 = (vpMath::sqr(A) + vpMath::sqr(B * E)) / det;
198  double n11 = ((vpMath::sqr(A) - vpMath::sqr(B)) * E) / det;
199  double n02 = (vpMath::sqr(B) + vpMath::sqr(A * E)) / det;
200 
201  p_[index_2] = n20;
202  p_[index_3] = n11;
203  p_[index_4] = n02;
204 }
205 
213 
222 {
223  const unsigned int val_4 = 4;
224  cP_.resize(val_4, false);
225 
226  const unsigned int index_0 = 0;
227  const unsigned int index_1 = 1;
228  const unsigned int index_2 = 2;
229  const unsigned int index_3 = 3;
230 
231  double x0, y0, z0; // variables intermediaires
232 
233  x0 = (cMo[index_0][0] * oP[0]) + (cMo[index_0][1] * oP[1]) + (cMo[index_0][index_2] * oP[index_2]) + cMo[index_0][index_3];
234  y0 = (cMo[index_1][0] * oP[0]) + (cMo[index_1][1] * oP[1]) + (cMo[index_1][index_2] * oP[index_2]) + cMo[index_1][index_3];
235  z0 = (cMo[index_2][0] * oP[0]) + (cMo[index_2][1] * oP[1]) + (cMo[index_2][index_2] * oP[index_2]) + cMo[index_2][index_3];
236 
237  cP_[index_3] = oP[index_3];
238 
239  cP_[index_0] = x0;
240  cP_[index_1] = y0;
241  cP_[index_2] = z0;
242 }
243 
246 {
247  vpSphere *feature = new vpSphere(*this);
248  return feature;
249 }
250 
263  const vpColor &color, unsigned int thickness)
264 {
265  vpColVector v_cP, v_p;
266  changeFrame(cMo, v_cP);
267  projection(v_cP, v_p);
268  const unsigned int index_0 = 0;
269  const unsigned int index_1 = 1;
270  const unsigned int index_2 = 2;
271  const unsigned int index_3 = 3;
272  const unsigned int index_4 = 4;
273  vpFeatureDisplay::displayEllipse(v_p[index_0], v_p[index_1], v_p[index_2], v_p[index_3], v_p[index_4], cam, I, color, thickness);
274 }
275 
288  const vpColor &color, unsigned int thickness)
289 {
290  vpColVector v_cP, v_p;
291  changeFrame(cMo, v_cP);
292  projection(v_cP, v_p);
293  const unsigned int index_0 = 0;
294  const unsigned int index_1 = 1;
295  const unsigned int index_2 = 2;
296  const unsigned int index_3 = 3;
297  const unsigned int index_4 = 4;
298  vpFeatureDisplay::displayEllipse(v_p[index_0], v_p[index_1], v_p[index_2], v_p[index_3], v_p[index_4], cam, I, color, thickness);
299 }
300 
309 void vpSphere::display(const vpImage<unsigned char> &I, const vpCameraParameters &cam, const vpColor &color,
310  unsigned int thickness)
311 {
312  const unsigned int index_0 = 0;
313  const unsigned int index_1 = 1;
314  const unsigned int index_2 = 2;
315  const unsigned int index_3 = 3;
316  const unsigned int index_4 = 4;
317  vpFeatureDisplay::displayEllipse(p[index_0], p[index_1], p[index_2], p[index_3], p[index_4], cam, I, color, thickness);
318 }
319 
328 void vpSphere::display(const vpImage<vpRGBa> &I, const vpCameraParameters &cam, const vpColor &color,
329  unsigned int thickness)
330 {
331  const unsigned int index_0 = 0;
332  const unsigned int index_1 = 1;
333  const unsigned int index_2 = 2;
334  const unsigned int index_3 = 3;
335  const unsigned int index_4 = 4;
336  vpFeatureDisplay::displayEllipse(p[index_0], p[index_1], p[index_2], p[index_3], p[index_4], cam, I, color, thickness);
337 }
338 END_VISP_NAMESPACE
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
void resize(unsigned int i, bool flagNullify=true)
Definition: vpColVector.h:1143
Class to define RGB colors available for display functionalities.
Definition: vpColor.h:157
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ fatalError
Fatal error.
Definition: vpException.h:72
static void displayEllipse(double x, double y, double n20, double n11, double n02, const vpCameraParameters &cam, const vpImage< unsigned char > &I, const vpColor &color=vpColor::green, unsigned int thickness=1)
Implementation of an homogeneous matrix and operations on such kind of matrices.
static double sqr(double x)
Definition: vpMath.h:203
Class that defines a 3D sphere in the object frame and allows forward projection of a 3D sphere in th...
Definition: vpSphere.h:80
void display(const vpImage< unsigned char > &I, const vpCameraParameters &cam, const vpColor &color=vpColor::green, unsigned int thickness=1) VP_OVERRIDE
Definition: vpSphere.cpp:309
void init() VP_OVERRIDE
Definition: vpSphere.cpp:42
void setWorldCoordinates(const vpColVector &oP) VP_OVERRIDE
Definition: vpSphere.cpp:61
void projection() VP_OVERRIDE
Definition: vpSphere.cpp:125
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &cP) const VP_OVERRIDE
Definition: vpSphere.cpp:221
vpSphere * duplicate() const VP_OVERRIDE
For memory issue (used by the vpServo class only).
Definition: vpSphere.cpp:245
vpSphere()
Definition: vpSphere.cpp:87
vpColVector cP
Definition: vpTracker.h:73
vpColVector p
Definition: vpTracker.h:69