Visual Servoing Platform  version 3.6.1 under development (2024-11-14)
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  oP.resize(4);
45  cP.resize(4);
46 
47  p.resize(5);
48 }
49 
59 void vpSphere::setWorldCoordinates(const vpColVector &oP_) { this->oP = oP_; }
60 
70 void vpSphere::setWorldCoordinates(double oX, double oY, double oZ, double R)
71 {
72  const unsigned int index_0 = 0;
73  const unsigned int index_1 = 1;
74  const unsigned int index_2 = 2;
75  const unsigned int index_3 = 3;
76  oP[index_0] = oX;
77  oP[index_1] = oY;
78  oP[index_2] = oZ;
79  oP[index_3] = R;
80 }
81 
86 
96 {
97  init();
99 }
100 
110 vpSphere::vpSphere(double oX, double oY, double oZ, double R)
111 {
112  init();
113  setWorldCoordinates(oX, oY, oZ, R);
114 }
115 
124 
139 void vpSphere::projection(const vpColVector &cP_, vpColVector &p_) const
140 {
141  p_.resize(5, false);
142  double x0, y0, z0;
143  double E, A, B;
144  const unsigned int index_0 = 0;
145  const unsigned int index_1 = 1;
146  const unsigned int index_2 = 2;
147  const unsigned int index_3 = 3;
148  const unsigned int index_4 = 4;
149 
150  // calcul des parametres M20, M11, M02 de l'ellipse
151  double s, r;
152  r = cP_[index_3];
153 
154  x0 = cP_[index_0];
155  y0 = cP_[index_1];
156  z0 = cP_[index_2];
157 
158  s = (r * r) - (y0 * y0) - (z0 * z0);
159 
160  if ((s = ((z0 * z0) - (r * r))) < 0.0) {
161  throw(vpException(vpException::fatalError, "Error: Sphere is behind image plane"));
162  }
163 
164  p_[0] = (x0 * z0) / s; // x
165  p_[1] = (y0 * z0) / s; // y
166 
167  if (fabs(x0) > 1e-6) {
168  double e = y0 / x0;
169  double b = r / sqrt(s);
170  double a = ((x0 * x0) + (y0 * y0) + (z0 * z0)) - (r * r);
171  if (a < 0.0) {
172  throw(vpException(vpException::fatalError, "Error: Sphere is behind image plane"));
173  }
174  a = (r * sqrt(a)) / s;
175  if (fabs(e) <= 1.0) {
176  E = e;
177  A = a;
178  B = b;
179  }
180  else {
181  E = -1.0 / e;
182  A = b;
183  B = a;
184  }
185  }
186  else {
187  E = 0.0;
188  A = r / sqrt(s);
189  B = (r * sqrt(((y0 * y0) + (z0 * z0)) - (r * r))) / s;
190  }
191 
192  // Chaumette PhD Thesis 1990, eq 2.72 divided by 4 since n_ij = mu_ij_chaumette_thesis / 4
193  double det = 4 * (1.0 + vpMath::sqr(E));
194  double n20 = (vpMath::sqr(A) + vpMath::sqr(B * E)) / det;
195  double n11 = ((vpMath::sqr(A) - vpMath::sqr(B)) * E) / det;
196  double n02 = (vpMath::sqr(B) + vpMath::sqr(A * E)) / det;
197 
198  p_[index_2] = n20;
199  p_[index_3] = n11;
200  p_[index_4] = n02;
201 }
202 
210 
219 {
220  cP_.resize(4, false);
221 
222  const unsigned int index_0 = 0;
223  const unsigned int index_1 = 1;
224  const unsigned int index_2 = 2;
225  const unsigned int index_3 = 3;
226 
227  double x0, y0, z0; // variables intermediaires
228 
229  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];
230  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];
231  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];
232 
233  cP_[index_3] = oP[index_3];
234 
235  cP_[index_0] = x0;
236  cP_[index_1] = y0;
237  cP_[index_2] = z0;
238 }
239 
242 {
243  vpSphere *feature = new vpSphere(*this);
244  return feature;
245 }
246 
259  const vpColor &color, unsigned int thickness)
260 {
261  vpColVector v_cP, v_p;
262  changeFrame(cMo, v_cP);
263  projection(v_cP, v_p);
264  const unsigned int index_0 = 0;
265  const unsigned int index_1 = 1;
266  const unsigned int index_2 = 2;
267  const unsigned int index_3 = 3;
268  const unsigned int index_4 = 4;
269  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);
270 }
271 
284  const vpColor &color, unsigned int thickness)
285 {
286  vpColVector v_cP, v_p;
287  changeFrame(cMo, v_cP);
288  projection(v_cP, v_p);
289  const unsigned int index_0 = 0;
290  const unsigned int index_1 = 1;
291  const unsigned int index_2 = 2;
292  const unsigned int index_3 = 3;
293  const unsigned int index_4 = 4;
294  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);
295 }
296 
305 void vpSphere::display(const vpImage<unsigned char> &I, const vpCameraParameters &cam, const vpColor &color,
306  unsigned int thickness)
307 {
308  const unsigned int index_0 = 0;
309  const unsigned int index_1 = 1;
310  const unsigned int index_2 = 2;
311  const unsigned int index_3 = 3;
312  const unsigned int index_4 = 4;
313  vpFeatureDisplay::displayEllipse(p[index_0], p[index_1], p[index_2], p[index_3], p[index_4], cam, I, color, thickness);
314 }
315 
324 void vpSphere::display(const vpImage<vpRGBa> &I, const vpCameraParameters &cam, const vpColor &color,
325  unsigned int thickness)
326 {
327  const unsigned int index_0 = 0;
328  const unsigned int index_1 = 1;
329  const unsigned int index_2 = 2;
330  const unsigned int index_3 = 3;
331  const unsigned int index_4 = 4;
332  vpFeatureDisplay::displayEllipse(p[index_0], p[index_1], p[index_2], p[index_3], p[index_4], cam, I, color, thickness);
333 }
334 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:305
void init() VP_OVERRIDE
Definition: vpSphere.cpp:42
void setWorldCoordinates(const vpColVector &oP) VP_OVERRIDE
Definition: vpSphere.cpp:59
void projection() VP_OVERRIDE
Definition: vpSphere.cpp:123
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &cP) const VP_OVERRIDE
Definition: vpSphere.cpp:218
vpSphere * duplicate() const VP_OVERRIDE
For memory issue (used by the vpServo class only).
Definition: vpSphere.cpp:241
vpSphere()
Definition: vpSphere.cpp:85
vpColVector cP
Definition: vpTracker.h:73
vpColVector p
Definition: vpTracker.h:69