Visual Servoing Platform  version 3.6.1 under development (2023-11-29)
vpImageCircle.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2023 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  * Image circle, i.e. circle in the image space.
32  */
33 
34 #include <visp3/core/vpImageCircle.h>
35 #include <visp3/core/vpMath.h>
36 
38  : m_center()
39  , m_radius(0.)
40 {
41 
42 }
43 
44 vpImageCircle::vpImageCircle(const vpImagePoint &center, const float &radius)
45  : m_center(center)
46  , m_radius(radius)
47 {
48 
49 }
50 
51 #ifdef HAVE_OPENCV_CORE
52 vpImageCircle::vpImageCircle(const cv::Vec3f &vec)
53  : m_center(vec[1], vec[0])
54  , m_radius(vec[2])
55 {
56 
57 }
58 #endif
59 
69 void computeIntersectionsLeftBorderOnly(const float &u_c, const float &umin_roi, const float &radius,
70  float &delta_theta)
71 {
72  // umin_roi = u_c + r cos(theta)
73  // theta = acos((umin_roi - u_c) / r)
74  float theta1 = std::acos((umin_roi - u_c)/ radius);
75  theta1 = vpMath::getAngleBetweenMinPiAndPi(theta1);
76  float theta2 = -1.f * theta1;
77  float theta_min = std::min(theta1, theta2);
78  float theta_max = std::max(theta1, theta2);
79  delta_theta = theta_max - theta_min;
80  if (u_c < umin_roi && std::abs(delta_theta - 2 * M_PIf) < 2.f * std::numeric_limits<float>::epsilon()) {
81  delta_theta = 0.f;
82  }
83 }
84 
94 void computeIntersectionsRightBorderOnly(const float &u_c, const float &umax_roi, const float &radius,
95  float &delta_theta)
96 {
97  // u = u_c + r cos(theta)
98  // theta = acos((u - u_c) / r)
99  float theta1 = std::acos((umax_roi - u_c) / radius);
100  theta1 = vpMath::getAngleBetweenMinPiAndPi(theta1);
101  float theta2 = -1.f * theta1;
102  float theta_min = std::min(theta1, theta2);
103  float theta_max = std::max(theta1, theta2);
104  delta_theta = 2.f * M_PIf - (theta_max - theta_min);
105  if (u_c > umax_roi && std::abs(delta_theta - 2 * M_PIf) < 2.f * std::numeric_limits<float>::epsilon()) {
106  delta_theta = 0.f;
107  }
108 }
109 
119 void computeIntersectionsTopBorderOnly(const float &v_c, const float &vmin_roi, const float &radius,
120  float &delta_theta)
121 {
122  // v = vc - r sin(theta) because the v-axis goes down
123  // theta = asin((vc - v)/r)
124  float theta1 = std::asin((v_c - vmin_roi) / radius);
125  theta1 = vpMath::getAngleBetweenMinPiAndPi(theta1);
126 
127  float theta2 = 0.f;
128  if (theta1 >= 0.f) {
129  theta2 = M_PIf - theta1;
130  }
131  else {
132  theta2 = -theta1 - M_PIf;
133  }
134  float theta_min = std::min(theta1, theta2);
135  float theta_max = std::max(theta1, theta2);
136  if (std::abs(theta_max - theta_min) * radius < 1.f) {
137  // Between the maximum and minimum theta there is less than 1 pixel of difference
138  // It meens that the full circle is visible
139  delta_theta = 2.f * M_PIf;
140  }
141  else if (theta1 > 0.f) {
142  delta_theta = 2.f * M_PIf - (theta_max - theta_min);
143  }
144  else {
145  delta_theta = theta_max - theta_min;
146  }
147  if (v_c < vmin_roi && std::abs(delta_theta - 2 * M_PIf) < 2.f * std::numeric_limits<float>::epsilon()) {
148  delta_theta = 0.f;
149  }
150 }
151 
161 void computeIntersectionsBottomBorderOnly(const float &v_c, const float &vmax_roi, const float &radius,
162  float &delta_theta)
163 {
164  // v = vc - r sin(theta) because the v-axis goes down
165  // theta = asin((vc - v)/r)
166  float theta1 = std::asin((v_c - vmax_roi) / radius);
167  theta1 = vpMath::getAngleBetweenMinPiAndPi(theta1);
168 
169  float theta2 = 0.f;
170  if (theta1 >= 0.f) {
171  theta2 = M_PIf - theta1;
172  }
173  else {
174  theta2 = -theta1 - M_PIf;
175  }
176  float theta_min = std::min(theta1, theta2);
177  float theta_max = std::max(theta1, theta2);
178  if (std::abs(theta_max - theta_min) * radius < 1.f) {
179  // Between the maximum and minimum theta there is less than 1 pixel of difference
180  // It meens that the full circle is visible
181  delta_theta = 2.f * M_PIf;
182  }
183  else if (theta1 > 0.f) {
184  delta_theta = theta_max - theta_min;
185  }
186  else {
187  delta_theta = 2.f * M_PIf - (theta_max - theta_min);
188  }
189  if (v_c > vmax_roi && std::abs(delta_theta - 2 * M_PIf) < 2.f * std::numeric_limits<float>::epsilon()) {
190  delta_theta = 0.f;
191  }
192 }
193 
208 void computePerpendicularAxesIntersections(const float &u_c, const float &v_c, const float &radius,
209  const float &crossing_u, const float &crossing_v,
210  std::pair<float, float> &theta_u_cross_min, std::pair<float, float> &theta_u_cross_max,
211  std::pair<float, float> &theta_v_cross_min, std::pair<float, float> &theta_v_cross_max)
212 {
213  // Computing the two angles for which the u-axis is crossed
214  // v = vc - r sin(theta) because the v-axis goes down
215  // theta = asin((vc - v)/r)
216  float theta_u_cross = std::asin((v_c - crossing_u)/radius);
217  theta_u_cross = vpMath::getAngleBetweenMinPiAndPi(theta_u_cross);
218  float theta_u_cross_2 = 0.f;
219  if (theta_u_cross > 0) {
220  theta_u_cross_2 = M_PIf - theta_u_cross;
221  }
222  else {
223  theta_u_cross_2 = -M_PIf - theta_u_cross;
224  }
225  // Computing the corresponding u-coordinates at which the u-axis is crossed
226  float u_ucross = u_c + radius * std::cos(theta_u_cross);
227  float u_ucross2 = u_c + radius * std::cos(theta_u_cross_2);
228  // Sorting the outputs such as theta_X_cross_min.second < theta_X_cross_max.second
229  if (u_ucross < u_ucross2) {
230  theta_u_cross_min.first = theta_u_cross;
231  theta_u_cross_min.second = u_ucross;
232  theta_u_cross_max.first = theta_u_cross_2;
233  theta_u_cross_max.second = u_ucross2;
234  }
235  else {
236  theta_u_cross_min.first = theta_u_cross_2;
237  theta_u_cross_min.second = u_ucross2;
238  theta_u_cross_max.first = theta_u_cross;
239  theta_u_cross_max.second = u_ucross;
240  }
241 
242  // Computing the two angles for which the v-axis is crossed
243  // u = u_c + r cos(theta)
244  // theta = acos((u - u_c) / r)
245  float theta_v_cross = std::acos((crossing_v - u_c)/radius);
246  theta_v_cross = vpMath::getAngleBetweenMinPiAndPi(theta_v_cross);
247  float theta_v_cross_2 = -theta_v_cross;
248  // Computing the corresponding v-coordinates at which the v-axis is crossed
249  // v = v_c - radius sin(theta) because the v-axis is oriented towards the bottom
250  float v_vcross = v_c - radius * std::sin(theta_v_cross);
251  float v_vcross2 = v_c - radius * std::sin(theta_v_cross_2);
252  // Sorting the outputs such as theta_X_cross_min.second < theta_X_cross_max.second
253  if (v_vcross < v_vcross2) {
254  theta_v_cross_min.first = theta_v_cross;
255  theta_v_cross_min.second = v_vcross;
256  theta_v_cross_max.first = theta_v_cross_2;
257  theta_v_cross_max.second = v_vcross2;
258  }
259  else {
260  theta_v_cross_min.first = theta_v_cross_2;
261  theta_v_cross_min.second = v_vcross2;
262  theta_v_cross_max.first = theta_v_cross;
263  theta_v_cross_max.second = v_vcross;
264  }
265 }
266 
278 void computeIntersectionsTopLeft(const float &u_c, const float &v_c, const float &umin_roi, const float &vmin_roi, const float &radius,
279  float &delta_theta)
280 {
281  std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
282  std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
283  float crossing_u = vmin_roi; // We cross the u-axis of the RoI at which v-coordinate
284  float crossing_v = umin_roi; // We cross the v-axis of the RoI at which u-coordinate
285  computePerpendicularAxesIntersections(u_c, v_c, radius, crossing_u, crossing_v,
286  crossing_theta_u_min, crossing_theta_u_max,
287  crossing_theta_v_min, crossing_theta_v_max);
288  float theta_u_min = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
289  float theta_u_max = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
290  float u_umin = crossing_theta_u_min.second;
291  float u_umax = crossing_theta_u_max.second;
292  float v_vmin = crossing_theta_v_min.second;
293  float v_vmax = crossing_theta_v_max.second;
294  if (u_umin < umin_roi && u_umax >= umin_roi && v_vmin < vmin_roi && v_vmax >= vmin_roi) {
295  // The circle crosses only once each axis
296  //Case crossing once
297  delta_theta = theta_u_max - theta_v_max;
298  }
299  else if (u_umin >= umin_roi && u_umax >= umin_roi && v_vmin >= vmin_roi && v_vmax >= vmin_roi) {
300  // The circle crosses twice each axis
301  //Case crossing twice
302  delta_theta = (theta_v_min - theta_u_min) + (theta_u_max - theta_v_max);
303  }
304  else if (u_umin < umin_roi && u_umax < umin_roi && v_vmin >= vmin_roi && v_vmax >= vmin_roi) {
305  // The circle crosses the u-axis outside the roi
306  // so it is equivalent to the case of crossing only the left border
307  //Case left only
308  computeIntersectionsLeftBorderOnly(u_c, umin_roi, radius, delta_theta);
309  }
310  else if (u_umin >= umin_roi && u_umax >= umin_roi && v_vmin <= vmin_roi && v_vmax <= vmin_roi) {
311  // The circle crosses the v-axis outside the roi
312  // so it is equivalent to the case of crossing only the top border
313  //Case top only
314  computeIntersectionsTopBorderOnly(v_c, vmin_roi, radius, delta_theta);
315  }
316 }
317 
329 void computeIntersectionsTopRight(const float &u_c, const float &v_c, const float &vmin_roi, const float &umax_roi, const float &radius,
330  float &delta_theta)
331 {
332  std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
333  std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
334  computePerpendicularAxesIntersections(u_c, v_c, radius, vmin_roi, umax_roi,
335  crossing_theta_u_min, crossing_theta_u_max,
336  crossing_theta_v_min, crossing_theta_v_max);
337  float theta_u_min = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
338  float theta_u_max = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
339  float u_umin = crossing_theta_u_min.second;
340  float u_umax = crossing_theta_u_max.second;
341  float v_vmin = crossing_theta_v_min.second;
342  float v_vmax = crossing_theta_v_max.second;
343  if (u_umin <= umax_roi && v_vmin < vmin_roi && u_umax >= umax_roi && v_vmax >= vmin_roi) {
344  // The circle crosses only once each axis and the center is below the top border
345  //Case crossing once
346  delta_theta = theta_v_max - theta_u_min;
347  if (delta_theta < 0) {
348  // The arc cannot be negative
349  delta_theta += 2.f * M_PIf;
350  }
351  }
352  else if (u_umin <= umax_roi && v_vmin >= vmin_roi && u_umax <= umax_roi && v_vmax >= vmin_roi) {
353  // The circle crosses twice each axis
354  //Case crossing twice
355  delta_theta = 2 * M_PIf - ((theta_u_min - theta_u_max)+(theta_v_min - theta_v_max));
356  }
357  else if (u_umin >= umax_roi && v_vmin >= vmin_roi && u_umax >= umax_roi && v_vmax >= vmin_roi) {
358  // The circle crosses the u-axis outside the roi
359  // so it is equivalent to the case of crossing only the right border
360  //Case crossing right only
361  computeIntersectionsRightBorderOnly(u_c, umax_roi, radius, delta_theta);
362  }
363  else if (u_umin <= umax_roi && v_vmin <= vmin_roi && u_umax <= umax_roi && v_vmax <= vmin_roi) {
364  // The circle crosses the v-axis outside the roi
365  // so it is equivalent to the case of crossing only the top border
366  //Case crossing top only
367  computeIntersectionsTopBorderOnly(v_c, vmin_roi, radius, delta_theta);
368  }
369 }
370 
382 void computeIntersectionsBottomLeft(const float &u_c, const float &v_c, const float &umin_roi, const float &vmax_roi, const float &radius,
383  float &delta_theta)
384 {
385  std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
386  std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
387  float crossing_u = vmax_roi; // We cross the u-axis of the RoI at which v-coordinate
388  float crossing_v = umin_roi; // We cross the v-axis of the RoI at which u-coordinate
389  computePerpendicularAxesIntersections(u_c, v_c, radius, crossing_u, crossing_v,
390  crossing_theta_u_min, crossing_theta_u_max,
391  crossing_theta_v_min, crossing_theta_v_max);
392  float theta_u_min = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
393  float theta_u_max = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
394  float u_umin = crossing_theta_u_min.second;
395  float u_umax = crossing_theta_u_max.second;
396  float v_vmin = crossing_theta_v_min.second;
397  float v_vmax = crossing_theta_v_max.second;
398  if (u_umin < umin_roi && u_umax >= umin_roi && v_vmin <= vmax_roi && v_vmax > vmax_roi) {
399  // The circle crosses only once each axis
400  //Case crossing once
401  delta_theta = theta_v_min - theta_u_max;
402  }
403  else if (u_umin >= umin_roi && u_umax >= umin_roi && v_vmin <= vmax_roi && v_vmax <= vmax_roi) {
404  // The circle crosses twice each axis
405  //Case crossing twice
406  delta_theta = (theta_v_min - theta_u_max) + (theta_u_min - theta_v_max);
407  }
408  else if (u_umin < umin_roi && u_umax < umin_roi && v_vmin <= vmax_roi && v_vmax <= vmax_roi) {
409  // The circle crosses the u-axis outside the roi
410  // so it is equivalent to the case of crossing only the left border
411  //Case left only
412  computeIntersectionsLeftBorderOnly(u_c, umin_roi, radius, delta_theta);
413  }
414  else if (u_umin >= umin_roi && u_umax >= umin_roi && v_vmin >= vmax_roi && v_vmax >= vmax_roi) {
415  // The circle crosses the v-axis outside the roi
416  // so it is equivalent to the case of crossing only the bottom border
417  //Case bottom only
418  computeIntersectionsBottomBorderOnly(v_c, vmax_roi, radius, delta_theta);
419  }
420 }
421 
433 void computeIntersectionsBottomRight(const float &u_c, const float &v_c, const float &vmax_roi, const float &umax_roi, const float &radius,
434  float &delta_theta)
435 {
436  std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
437  std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
438  float crossing_u = vmax_roi; // We cross the u-axis of the RoI at the maximum v-coordinate of the RoI
439  float crossing_v = umax_roi; // We cross the v-axis of the RoI at the maximum u-coordinate of the RoI
440  computePerpendicularAxesIntersections(u_c, v_c, radius, crossing_u, crossing_v,
441  crossing_theta_u_min, crossing_theta_u_max,
442  crossing_theta_v_min, crossing_theta_v_max);
443  float theta_u_min = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
444  float theta_u_max = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
445  float u_umin = crossing_theta_u_min.second;
446  float u_umax = crossing_theta_u_max.second;
447  float v_vmin = crossing_theta_v_min.second;
448  float v_vmax = crossing_theta_v_max.second;
449  if (u_umin <= umax_roi && u_umax > umax_roi && v_vmin <= vmax_roi && v_vmax > vmax_roi) {
450  // The circle crosses only once each axis
451  //Case crossing once
452  delta_theta = theta_u_min - theta_v_min;
453  if (delta_theta < 0) {
454  // An arc length cannot be negative it means that theta_u_max was comprise in the bottom left quadrant of the circle
455  delta_theta += 2.f * M_PIf;
456  }
457  }
458  else if (u_umin <= umax_roi && u_umax <= umax_roi && v_vmin <= vmax_roi && v_vmax <= vmax_roi) {
459  // The circle crosses twice each axis
460  //Case crossing twice
461  delta_theta = 2.f * M_PIf - ((theta_v_min - theta_v_max) + (theta_u_max - theta_u_min));
462  }
463  else if (u_umin > umax_roi && u_umax > umax_roi && v_vmin <= vmax_roi && v_vmax <= vmax_roi) {
464  // The circle crosses the u-axis outside the roi
465  // so it is equivalent to the case of crossing only the right border
466  //Case left only
467  computeIntersectionsRightBorderOnly(u_c, umax_roi, radius, delta_theta);
468  }
469  else if (u_umin <= umax_roi && u_umax <= umax_roi && v_vmin > vmax_roi && v_vmax > vmax_roi) {
470  // The circle crosses the v-axis outside the roi
471  // so it is equivalent to the case of crossing only the bottom border
472  //Case bottom only
473  computeIntersectionsBottomBorderOnly(v_c, vmax_roi, radius, delta_theta);
474  }
475 }
476 
489 void computeIntersectionsTopLeftBottom(const float &u_c, const float &v_c, const float &umin_roi, const float &vmin_roi,
490  const float &vmax_roi, const float &radius, float &delta_theta)
491 {
492  // Computing the intersections with the top and left axes
493  std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
494  std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
495  float crossing_u_top = vmin_roi; // We cross the u-axis of the top axis of the RoI at the minimum v-coordinate of the RoI
496  float crossing_v = umin_roi; // We cross the v-axis of the RoI at the minimum u-coordinate of the RoI
497  computePerpendicularAxesIntersections(u_c, v_c, radius, crossing_u_top, crossing_v,
498  crossing_theta_u_min, crossing_theta_u_max,
499  crossing_theta_v_min, crossing_theta_v_max);
500  float theta_u_min_top = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
501  float theta_u_max_top = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
502  float u_umin_top = crossing_theta_u_min.second;
503  float u_umax_top = crossing_theta_u_max.second;
504  float v_vmin = crossing_theta_v_min.second;
505  float v_vmax = crossing_theta_v_max.second;
506 
507  // Computing the intersections with the bottom and left axes
508  float crossing_u_bottom = vmax_roi; // We cross the u-axis of the RoI at the maximum v-coordinate of the RoI
509  computePerpendicularAxesIntersections(u_c, v_c, radius, crossing_u_bottom, crossing_v,
510  crossing_theta_u_min, crossing_theta_u_max,
511  crossing_theta_v_min, crossing_theta_v_max);
512  float theta_u_min_bottom = crossing_theta_u_min.first;
513  float theta_u_max_bottom = crossing_theta_u_max.first;
514  float u_umin_bottom = crossing_theta_u_min.second;
515  float u_umax_bottom = crossing_theta_u_max.second;
516  if (u_umin_top >= umin_roi && u_umin_bottom >= umin_roi && v_vmin >= vmin_roi && v_vmax <= vmax_roi) {
517  // case intersection top + left + bottom twice
518  delta_theta = (theta_v_min - theta_u_min_top) + (theta_u_max_top - theta_u_max_bottom) + (theta_u_min_bottom - theta_v_max);
519  }
520  else if (u_umin_top <= umin_roi && v_vmin <= vmin_roi && u_umin_bottom <= umin_roi && v_vmax >= vmax_roi) {
521  // case intersection top and bottom
522  delta_theta = (theta_u_max_top - theta_u_max_bottom);
523  }
524  else if (u_umax_top <= umin_roi && u_umax_bottom <= umin_roi && v_vmin >= vmin_roi && v_vmax <= vmax_roi) {
525  // case left only
526  computeIntersectionsLeftBorderOnly(u_c, umin_roi, radius, delta_theta);
527  }
528  else if (u_umax_bottom > umin_roi && v_vmin >= vmin_roi) {
529  // case bottom/left corner
530  computeIntersectionsBottomLeft(u_c, v_c, umin_roi, vmax_roi, radius, delta_theta);
531  }
532  else if (u_umax_top > umin_roi && v_vmax <= vmax_roi) {
533  // case top/left corner
534  computeIntersectionsTopLeft(u_c, v_c, umin_roi, vmin_roi, radius, delta_theta);
535  }
536 }
537 
550 void computeIntersectionsTopRightBottom(const float &u_c, const float &v_c, const float &umax_roi, const float &vmin_roi, const float &vmax_roi,
551  const float &radius, float &delta_theta)
552 {
553  // Computing the intersections with the top and right axes
554  std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
555  std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
556  float crossing_u_top = vmin_roi; // We cross the u-axis of the top axis of the RoI at the minimum v-coordinate of the RoI
557  float crossing_v = umax_roi; // We cross the v-axis of the right axis of the RoI at the maximum u-coordinate of the RoI
558  computePerpendicularAxesIntersections(u_c, v_c, radius, crossing_u_top, crossing_v,
559  crossing_theta_u_min, crossing_theta_u_max,
560  crossing_theta_v_min, crossing_theta_v_max);
561  float theta_u_min_top = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
562  float theta_u_max_top = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
563  float u_umin_top = crossing_theta_u_min.second;
564  float u_umax_top = crossing_theta_u_max.second;
565  float v_vmin = crossing_theta_v_min.second;
566  float v_vmax = crossing_theta_v_max.second;
567 
568  // Computing the intersections with the bottom and right axes
569  float crossing_u_bottom = vmax_roi; // We cross the u-axis of the RoI at the maximum v-coordinate of the RoI
570  computePerpendicularAxesIntersections(u_c, v_c, radius, crossing_u_bottom, crossing_v,
571  crossing_theta_u_min, crossing_theta_u_max,
572  crossing_theta_v_min, crossing_theta_v_max);
573  float theta_u_min_bottom = crossing_theta_u_min.first;
574  float theta_u_max_bottom = crossing_theta_u_max.first;
575  float u_umin_bottom = crossing_theta_u_min.second;
576  float u_umax_bottom = crossing_theta_u_max.second;
577  if (u_umax_top <= umax_roi && u_umax_bottom <= umax_roi && v_vmin >= vmin_roi && v_vmax <= vmax_roi) {
578  // case intersection top + right + bottom twice
579  delta_theta = 2.f * M_PIf - ((theta_u_min_top - theta_u_max_top) + (theta_v_min - theta_v_max) + (theta_u_max_bottom - theta_u_min_bottom));
580  }
581  else if (u_umin_top <= umax_roi && u_umax_top > umax_roi && v_vmin <= vmin_roi && u_umin_bottom <= umax_roi && u_umax_bottom > umax_roi && v_vmax >= vmax_roi) {
582  // case intersection top and bottom
583  delta_theta = (theta_u_max_top - theta_u_max_bottom);
584  }
585  else if (u_umin_top >= umax_roi && u_umin_bottom >= umax_roi && v_vmin >= vmin_roi && v_vmax <= vmax_roi) {
586  // case right only
587  computeIntersectionsRightBorderOnly(u_c, umax_roi, radius, delta_theta);
588  }
589  else if (u_umin_bottom <= umax_roi && v_vmin >= vmin_roi) {
590  // case bottom/right corner
591  computeIntersectionsBottomRight(u_c, v_c, vmax_roi, umax_roi, radius, delta_theta);
592  }
593  else if (u_umin_top <= umax_roi && v_vmax <= vmax_roi) {
594  // case top/right corner
595  computeIntersectionsTopRight(u_c, v_c, vmin_roi, umax_roi, radius, delta_theta);
596  }
597 }
598 
610 void computeIntersectionsTopBottomOnly(const float &u_c, const float &v_c, const float &vmin_roi, const float &vmax_roi, const float &radius,
611  float &delta_theta)
612 {
613  // Computing the two angles for which the u-axis is crossed at the top of the RoI
614  // v = vc - r sin(theta) because the v-axis goes down
615  // theta = asin((vc - vmin_roi)/r)
616  float theta_u_cross_top = std::asin((v_c - vmin_roi)/radius);
617  theta_u_cross_top = vpMath::getAngleBetweenMinPiAndPi(theta_u_cross_top);
618  float theta_u_cross_top_2 = 0.f;
619  if (theta_u_cross_top > 0) {
620  theta_u_cross_top_2 = M_PIf - theta_u_cross_top;
621  }
622  else {
623  theta_u_cross_top_2 = -M_PIf - theta_u_cross_top;
624  }
625 
626  // Computing the corresponding u-coordinates at which the u-axis is crossed
627  float u_ucross_top = u_c + radius * std::cos(theta_u_cross_top);
628  float u_ucross_top_2 = u_c + radius * std::cos(theta_u_cross_top_2);
629  // Sorting the outputs such as u(theta_u_cross_top_min) < u(theta_u_cross_top_max)
630  float theta_u_cross_top_min = 0.f, theta_u_cross_top_max = 0.f;
631  if (u_ucross_top < u_ucross_top_2) {
632  theta_u_cross_top_min = theta_u_cross_top;
633  theta_u_cross_top_max = theta_u_cross_top_2;
634  }
635  else {
636  theta_u_cross_top_min = theta_u_cross_top_2;
637  theta_u_cross_top_max = theta_u_cross_top;
638  }
639 
640  // Computing the two angles for which the u-axis is crossed at the bottom of the RoI
641  // v = vc - r sin(theta) because the v-axis goes down
642  // theta = asin((vc - vmax_roi)/r)
643  float theta_u_cross_bottom = std::asin((v_c - vmax_roi)/radius);
644  theta_u_cross_bottom = vpMath::getAngleBetweenMinPiAndPi(theta_u_cross_bottom);
645  float theta_u_cross_bottom_2 = 0.f;
646  if (theta_u_cross_bottom > 0) {
647  theta_u_cross_bottom_2 = M_PIf - theta_u_cross_bottom;
648  }
649  else {
650  theta_u_cross_bottom_2 = -M_PIf - theta_u_cross_bottom;
651  }
652 
653  // Computing the corresponding u-coordinates at which the u-axis is crossed
654  float u_ucross_bottom = u_c + radius * std::cos(theta_u_cross_bottom);
655  float u_ucross_bottom_2 = u_c + radius * std::cos(theta_u_cross_bottom_2);
656 
657  // Sorting the outputs such as u(theta_u_cross_bottom_min) < u(theta_u_cross_bottom_max)
658  float theta_u_cross_bottom_min = 0.f, theta_u_cross_bottom_max = 0.f;
659  if (u_ucross_bottom < u_ucross_bottom_2) {
660  theta_u_cross_bottom_min = theta_u_cross_bottom;
661  theta_u_cross_bottom_max = theta_u_cross_bottom_2;
662  }
663  else {
664  theta_u_cross_bottom_min = theta_u_cross_bottom_2;
665  theta_u_cross_bottom_max = theta_u_cross_bottom;
666  }
667 
668  // Computing the the length of the angular interval of the circle when it intersects
669  // only with the top and bottom borders of the Region of Interest (RoI)
670  delta_theta = 2.f * M_PIf - ((theta_u_cross_top_min - theta_u_cross_top_max) + (theta_u_cross_bottom_max - theta_u_cross_bottom_min));
671 }
672 
685 void computeIntersectionsLeftRightTop(const float &u_c, const float &v_c, const float &umin_roi, const float &umax_roi,
686  const float &vmin_roi, const float &radius, float &delta_theta)
687 {
688  // Computing the intersections with the top and left axes
689  std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
690  std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
691  float crossing_u = vmin_roi; // We cross the u-axis of the RoI at the minimum v-coordinate of the RoI
692  float crossing_v_left = umin_roi; // We cross the v-axis of the left of the RoI at the minimum u-coordinate of the RoI
693  computePerpendicularAxesIntersections(u_c, v_c, radius, crossing_u, crossing_v_left,
694  crossing_theta_u_min, crossing_theta_u_max,
695  crossing_theta_v_min, crossing_theta_v_max);
696  float theta_u_min = crossing_theta_u_min.first;
697  float theta_u_max = crossing_theta_u_max.first;
698  float u_umin = crossing_theta_u_min.second;
699  float u_umax = crossing_theta_u_max.second;
700  float theta_v_min_left = crossing_theta_v_min.first;
701  float theta_v_max_left = crossing_theta_v_max.first;
702  float v_vmin_left = crossing_theta_v_min.second;
703  float v_vmax_left = crossing_theta_v_max.second;
704 
705  // Computing the intersections with the rigt and top axes
706  float crossing_v_right = umax_roi; // We cross the v-axis of the right of the RoI at the maximum u-coordinate of the RoI
707  computePerpendicularAxesIntersections(u_c, v_c, radius, crossing_u, crossing_v_right,
708  crossing_theta_u_min, crossing_theta_u_max,
709  crossing_theta_v_min, crossing_theta_v_max);
710  float theta_v_min_right = crossing_theta_v_min.first;
711  float theta_v_max_right = crossing_theta_v_max.first;
712  float v_vmin_right = crossing_theta_v_min.second;
713  float v_vmax_right = crossing_theta_v_max.second;
714 
715  if (u_umin >= umin_roi && u_umax <= umax_roi && v_vmin_left >= vmin_roi && v_vmin_right >= vmin_roi) {
716  // case intersection left + right + top twice
717  delta_theta = (theta_v_min_left - theta_u_min) + (theta_u_max - theta_v_min_right) + (theta_v_max_right - theta_v_max_left);
718  }
719  else if (u_umin <= umin_roi && u_umax >= umax_roi && v_vmax_left >= vmin_roi && v_vmax_right >= vmin_roi) {
720  // case intersection left + right
721  delta_theta = (theta_v_max_right - theta_v_max_left);
722  }
723  else if (v_vmax_left <= vmin_roi && v_vmax_right <= vmin_roi && u_umin >= umin_roi && u_umax <= umax_roi) {
724  // case top only
725  computeIntersectionsTopBorderOnly(v_c, vmin_roi, radius, delta_theta);
726  }
727  else if (u_umax >= umin_roi && v_vmax_left >= vmin_roi) {
728  // case top/left corner
729  computeIntersectionsTopLeft(u_c, v_c, umin_roi, vmin_roi, radius, delta_theta);
730  }
731  else if (u_umin <= umax_roi && v_vmax_right >= vmin_roi) {
732  // case top/right corner
733  computeIntersectionsTopRight(u_c, v_c, vmin_roi, umax_roi, radius, delta_theta);
734  }
735 }
736 
749 void computeIntersectionsLeftRightBottom(const float &u_c, const float &v_c, const float &umin_roi, const float &umax_roi,
750  const float &vmax_roi, const float &radius, float &delta_theta)
751 {
752  // Computing the intersections with the bottom and left axes
753  std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
754  std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
755  float crossing_u = vmax_roi; // We cross the u-axis of the bottom axis of the RoI at the maximum v-coordinate of the RoI
756  float crossing_v_left = umin_roi; // We cross the v-axis of the left of the RoI at the minimum u-coordinate of the RoI
757  computePerpendicularAxesIntersections(u_c, v_c, radius, crossing_u, crossing_v_left,
758  crossing_theta_u_min, crossing_theta_u_max,
759  crossing_theta_v_min, crossing_theta_v_max);
760  float theta_u_min = crossing_theta_u_min.first;
761  float theta_u_max = crossing_theta_u_max.first;
762  float u_umin = crossing_theta_u_min.second;
763  float u_umax = crossing_theta_u_max.second;
764  float theta_v_min_left = crossing_theta_v_min.first;
765  float theta_v_max_left = crossing_theta_v_max.first;
766  float v_vmin_left = crossing_theta_v_min.second;
767  // float v_vmax_left = crossing_theta_v_max.second;
768 
769  // Computing the intersections with the bottom and right axes
770  float crossing_v_right = umax_roi; // We cross the v-axis of the right of the RoI at the maximum u-coordinate of the RoI
771  computePerpendicularAxesIntersections(u_c, v_c, radius, crossing_u, crossing_v_right,
772  crossing_theta_u_min, crossing_theta_u_max,
773  crossing_theta_v_min, crossing_theta_v_max);
774  float theta_v_min_right = crossing_theta_v_min.first;
775  float theta_v_max_right = crossing_theta_v_max.first;
776  float v_vmin_right = crossing_theta_v_min.second;
777  // float v_vmax_right = crossing_theta_v_max.second;
778 
779  if (u_umin >= umin_roi && u_umax <= umax_roi && v_vmin_left <= vmax_roi && v_vmin_right <= vmax_roi) {
780  // case intersection left + right + bottom twice
781  delta_theta = (theta_v_min_left - theta_v_min_right) + (theta_v_max_right - theta_u_max) + (theta_u_min - theta_v_max_left);
782  }
783  else if (u_umin <= umin_roi && u_umax >= umax_roi && v_vmin_left <= vmax_roi && v_vmin_right <= vmax_roi) {
784  // case intersection left + right
785  delta_theta = (theta_v_min_left - theta_v_min_right);
786  }
787  else if (v_vmin_left >= vmax_roi && v_vmin_right >= vmax_roi && u_umin >= umin_roi && u_umax <= umax_roi) {
788  // case bottom only
789  computeIntersectionsBottomBorderOnly(v_c, vmax_roi, radius, delta_theta);
790  }
791  else if (u_umax >= umin_roi && v_vmin_right >= vmax_roi) {
792  // case bottom/left corner
793  computeIntersectionsBottomLeft(u_c, v_c, umin_roi, vmax_roi, radius, delta_theta);
794  }
795  else if (u_umin <= umax_roi && v_vmin_right <= vmax_roi) {
796  // case bottom/right corner
797  computeIntersectionsBottomRight(u_c, v_c, vmax_roi, umax_roi, radius, delta_theta);
798  }
799 }
800 
812 void computeIntersectionsLeftRightOnly(const float &u_c, const float &v_c, const float &umin_roi, const float &umax_roi, const float &radius,
813  float &delta_theta)
814 {
815  // Computing the two angles for which the v-axis is crossed at the left of the RoI
816  // umin_roi = u_c + r cos(theta)
817  // theta = acos((umin_roi - u_c)/r)
818  // theta_min = -theta_max
819  float theta_v_cross_left = std::acos((umin_roi - u_c)/radius);
820  theta_v_cross_left = vpMath::getAngleBetweenMinPiAndPi(theta_v_cross_left);
821  float theta_v_cross_left_2 = -theta_v_cross_left;
822 
823  // Computing the corresponding v-coordinates at which the v-axis is crossed
824  float v_vcross_left = v_c - radius * std::sin(theta_v_cross_left);
825  float v_vcross_left_2 = v_c - radius * std::sin(theta_v_cross_left_2);
826  // Sorting the outputs such as v(theta_v_cross_left_min) < v(theta_v_cross_left_max)
827  float theta_v_cross_left_min = 0.f, theta_v_cross_left_max = 0.f;
828  if (v_vcross_left < v_vcross_left_2) {
829  theta_v_cross_left_min = theta_v_cross_left;
830  theta_v_cross_left_max = theta_v_cross_left_2;
831  }
832  else {
833  theta_v_cross_left_min = theta_v_cross_left_2;
834  theta_v_cross_left_max = theta_v_cross_left;
835  }
836 
837  // Computing the two angles for which the v-axis is crossed at the right of the RoI
838  // umax_roi = u_c + r cos(theta)
839  // theta = acos((umin_roi - u_c)/r)
840  // theta_min = -theta_max
841  float theta_v_cross_right = std::acos((umax_roi - u_c)/radius);
842  theta_v_cross_right = vpMath::getAngleBetweenMinPiAndPi(theta_v_cross_right);
843  float theta_v_cross_right_2 = -theta_v_cross_right;
844 
845  // Computing the corresponding v-coordinates at which the v-axis is crossed
846  float v_vcross_right = v_c - radius * std::sin(theta_v_cross_right);
847  float v_vcross_right_2 = v_c - radius * std::sin(theta_v_cross_right_2);
848 
849  // Sorting the outputs such as v(theta_v_cross_right_min) < v(theta_v_cross_right_max)
850  float theta_v_cross_right_min = 0.f, theta_v_cross_right_max = 0.f;
851  if (v_vcross_right < v_vcross_right_2) {
852  theta_v_cross_right_min = theta_v_cross_right;
853  theta_v_cross_right_max = theta_v_cross_right_2;
854  }
855  else {
856  theta_v_cross_right_min = theta_v_cross_right_2;
857  theta_v_cross_right_max = theta_v_cross_right;
858  }
859 
860  // Computing the the length of the angular interval of the circle when it intersects
861  // only with the top and bottom borders of the Region of Interest (RoI)
862  delta_theta = (theta_v_cross_left_min - theta_v_cross_right_min) + (theta_v_cross_right_max - theta_v_cross_left_max);
863 }
864 
865 
879 void computeIntersectionsAllAxes(const float &u_c, const float &v_c, const float &umin_roi, const float &umax_roi,
880  const float &vmin_roi, const float &vmax_roi, const float &radius, float &delta_theta)
881 {
882  // Computing the intersections with the top and left axes
883  std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
884  std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
885  float crossing_u_top = vmin_roi; // We cross the u-axis of the top axis of the RoI at the minimum v-coordinate of the RoI
886  float crossing_v_left = umin_roi; // We cross the v-axis of the left of the RoI at the minimum u-coordinate of the RoI
887  computePerpendicularAxesIntersections(u_c, v_c, radius, crossing_u_top, crossing_v_left,
888  crossing_theta_u_min, crossing_theta_u_max,
889  crossing_theta_v_min, crossing_theta_v_max);
890  float theta_u_min_top = crossing_theta_u_min.first;
891  float theta_u_max_top = crossing_theta_u_max.first;
892  float theta_v_min_left = crossing_theta_v_min.first;
893  float theta_v_max_left = crossing_theta_v_max.first;
894 
895  // Computing the intersections with the bottom and right axes
896  float crossing_u_bottom = vmax_roi; // We cross the u-axis of the RoI at the maximum v-coordinate of the RoI
897  float crossing_v_right = umax_roi; // We cross the v-axis of the right of the RoI at the maximum u-coordinate of the RoI
898  computePerpendicularAxesIntersections(u_c, v_c, radius, crossing_u_bottom, crossing_v_right,
899  crossing_theta_u_min, crossing_theta_u_max,
900  crossing_theta_v_min, crossing_theta_v_max);
901  float theta_u_min_bottom = crossing_theta_u_min.first;
902  float theta_u_max_bottom = crossing_theta_u_max.first;
903  float theta_v_min_right = crossing_theta_v_min.first;
904  float theta_v_max_right = crossing_theta_v_max.first;
905  delta_theta = (theta_v_min_left - theta_u_min_top) + (theta_u_max_top -theta_v_min_right);
906  delta_theta += (theta_v_max_right - theta_u_max_bottom) + (theta_u_min_bottom - theta_v_max_left);
907 }
908 
909 float vpImageCircle::computeAngularCoverageInRoI(const vpRect &roi, const float &roundingTolerance) const
910 {
911  float delta_theta = 0.f;
912  vpImagePoint center = m_center;
913  float u_c = center.get_u();
914  float v_c = center.get_v();
915  float radius = m_radius;
916  float roi_w = roi.getWidth();
917  float roi_h = roi.getHeight();
918  vpImagePoint topLeft = roi.getTopLeft();
919  float umin_roi = topLeft.get_u();
920  float vmin_roi = topLeft.get_v();
921  float umax_roi = topLeft.get_u() + roi_w;
922  float vmax_roi = topLeft.get_v() + roi_h;
923  bool touchLeftBorder = (u_c - radius) <= umin_roi;
924  bool touchRightBorder = (u_c + radius) >= umax_roi;
925  bool touchTopBorder = (v_c - radius) <= vmin_roi;
926  bool touchBottomBorder = (v_c + radius) >= vmax_roi;
927  bool isHorizontallyOK = (!touchLeftBorder && !touchRightBorder);
928  bool isVerticallyOK = (!touchTopBorder && !touchBottomBorder);
929  if (isHorizontallyOK && isVerticallyOK && roi.isInside(m_center)) {
930  // Easy case
931  // The circle has its center in the image and its radius is not too great
932  // to make it fully contained in the RoI
933  delta_theta = 2.f * M_PIf;
934  }
935  else if (touchBottomBorder && !touchLeftBorder && !touchRightBorder && !touchTopBorder) {
936  // Touches/intersects only the bottom border of the RoI
937  computeIntersectionsBottomBorderOnly(v_c, vmax_roi, radius, delta_theta);
938  }
939  else if (!touchBottomBorder && touchLeftBorder && !touchRightBorder && !touchTopBorder) {
940  // Touches/intersects only the left border of the RoI
941  computeIntersectionsLeftBorderOnly(u_c, umin_roi, radius, delta_theta);
942  }
943  else if (!touchBottomBorder && !touchLeftBorder && touchRightBorder && !touchTopBorder) {
944  // Touches/intersects only the right border of the RoI
945  computeIntersectionsRightBorderOnly(u_c, umax_roi, radius, delta_theta);
946  }
947  else if (!touchBottomBorder && !touchLeftBorder && !touchRightBorder && touchTopBorder) {
948  // Touches/intersects only the top border of the RoI
949  computeIntersectionsTopBorderOnly(v_c, vmin_roi, radius, delta_theta);
950  }
951  else if (touchBottomBorder && touchLeftBorder && !touchRightBorder && !touchTopBorder) {
952  // Touches/intersects the bottom and left borders of the RoI
953  computeIntersectionsBottomLeft(u_c, v_c, umin_roi, vmax_roi, radius, delta_theta);
954  }
955  else if (touchBottomBorder && !touchLeftBorder && touchRightBorder && !touchTopBorder) {
956  // Touches/intersects the bottom and right borders of the RoI
957  computeIntersectionsBottomRight(u_c, v_c, vmax_roi, umax_roi, radius, delta_theta);
958  }
959  else if (!touchBottomBorder && touchLeftBorder && !touchRightBorder && touchTopBorder) {
960  // Touches/intersects the top and left borders of the RoI
961  computeIntersectionsTopLeft(u_c, v_c, umin_roi, vmin_roi, radius, delta_theta);
962  }
963  else if (!touchBottomBorder && !touchLeftBorder && touchRightBorder && touchTopBorder) {
964  // Touches/intersects the top and right borders of the RoI
965  computeIntersectionsTopRight(u_c, v_c, vmin_roi, umax_roi, radius, delta_theta);
966  }
967  else if (touchBottomBorder && touchTopBorder && touchLeftBorder && !touchRightBorder) {
968  std::cout << "DEBUG ici" << std::endl;
969  // Touches/intersects the top, left and bottom borders of the RoI
970  computeIntersectionsTopLeftBottom(u_c, v_c, umin_roi, vmin_roi, vmax_roi, radius, delta_theta);
971  }
972  else if (touchBottomBorder && touchTopBorder && !touchLeftBorder && touchRightBorder) {
973  // Touches/intersects the top, right and bottom borders of the RoI
974  computeIntersectionsTopRightBottom(u_c, v_c, umax_roi, vmin_roi, vmax_roi, radius, delta_theta);
975  }
976  else if (touchBottomBorder && touchTopBorder && !touchLeftBorder && !touchRightBorder) {
977  // Touches/intersects the top and bottom borders of the RoI
978  computeIntersectionsTopBottomOnly(u_c, v_c, vmin_roi, vmax_roi, radius, delta_theta);
979  }
980  else if (!touchBottomBorder && touchTopBorder && touchLeftBorder && touchRightBorder) {
981  // Touches/intersects the top, left and right borders of the RoI
982  computeIntersectionsLeftRightTop(u_c, v_c, umin_roi, umax_roi, vmin_roi, radius, delta_theta);
983  }
984  else if (touchBottomBorder && !touchTopBorder && touchLeftBorder && touchRightBorder) {
985  // Touches/intersects the bottom, left and right borders of the RoI
986  computeIntersectionsLeftRightBottom(u_c, v_c, umin_roi, umax_roi, vmax_roi, radius, delta_theta);
987  }
988  else if (touchLeftBorder && touchRightBorder && !touchTopBorder && !touchBottomBorder) {
989  // Touches/intersects the bottom, left and right borders of the RoI
990  computeIntersectionsLeftRightOnly(u_c, v_c, umin_roi, umax_roi, radius, delta_theta);
991  }
992  else if (touchLeftBorder && touchRightBorder && touchTopBorder && touchBottomBorder) {
993  // Touches/intersects each axis
994  computeIntersectionsAllAxes(u_c, v_c, umin_roi, umax_roi, vmin_roi, vmax_roi, radius, delta_theta);
995  }
996  else {
997  std::cerr << "touchLeft = " << (touchLeftBorder ? "true" : "false") << "\ttouchRight = " << (touchRightBorder ? "true" : "false") << std::endl;
998  std::cerr << "touchTop = " << (touchTopBorder ? "true" : "false") << "\ttouchBottom = " << (touchBottomBorder ? "true" : "false") << std::endl;
999  std::cerr << "u_c = " << u_c << "\tv_c = " << v_c << "\tradius = " << radius << std::endl;
1000  std::cerr << "umin_roi = " << umin_roi << "\tumax_roi = " << umax_roi << std::endl;
1001  std::cerr << "vmin_roi = " << vmin_roi << "\tvmax_roi = " << vmax_roi << std::endl << std::flush;
1002  throw(vpException(vpException::fatalError, "This case should never happen. Please contact Inria to make fix the problem"));
1003  }
1004 
1005  if (delta_theta < 0 || delta_theta > 2.f * M_PIf) { // Needed since M_PIf is used
1006  float rest = vpMath::modulo(delta_theta, 2.f * M_PIf);
1007  if (rest < roundingTolerance && (delta_theta < -M_PIf || delta_theta > M_PIf)) {
1008  // If the angle is a negative multiple of 2.f * M_PIf we consider it to be 2.f * M_PIf
1009  delta_theta = 2.f * M_PIf;
1010  }
1011  else {
1012  //Otherwise, it corresponds to delta_theta modulo 2.f * M_PIf
1013  delta_theta = rest;
1014  }
1015  }
1016 
1017  return delta_theta;
1018 }
1019 
1020 float vpImageCircle::computeArcLengthInRoI(const vpRect &roi, const float &roundingTolerance) const
1021 {
1022  float delta_theta = computeAngularCoverageInRoI(roi, roundingTolerance);
1023  return delta_theta * m_radius;
1024 }
1025 
1027 {
1028  return m_center;
1029 }
1030 
1032 {
1033  return m_radius;
1034 }
1035 
1037 {
1038  vpRect bbox(m_center - vpImagePoint(m_radius, m_radius), 2 * m_radius, 2 * m_radius);
1039  return bbox;
1040 }
1041 
1043 {
1044  return m_radius * m_radius / 4;
1045 }
1046 
1048 {
1049  return m_radius * m_radius / 4;
1050 }
1051 
1053 {
1054  return 0.;
1055 };
error that can be emitted by ViSP classes.
Definition: vpException.h:59
@ fatalError
Fatal error.
Definition: vpException.h:84
float computeAngularCoverageInRoI(const vpRect &roi, const float &roundingTolerance=0.001f) const
float getRadius() const
float get_n11() const
vpRect getBBox() const
vpImagePoint getCenter() const
float get_n02() const
float computeArcLengthInRoI(const vpRect &roi, const float &roundingTolerance=0.001f) const
float get_n20() const
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:82
double get_u() const
Definition: vpImagePoint.h:136
double get_v() const
Definition: vpImagePoint.h:147
static float getAngleBetweenMinPiAndPi(const float &theta)
Definition: vpMath.h:137
static float modulo(const float &value, const float &modulo)
Gives the rest of value divided by modulo when the quotient can only be an integer.
Definition: vpMath.h:175
Defines a rectangle in the plane.
Definition: vpRect.h:76
double getWidth() const
Definition: vpRect.h:224
bool isInside(const vpImagePoint &ip) const
Definition: vpRect.cpp:123
vpImagePoint getTopLeft() const
Definition: vpRect.h:196
double getHeight() const
Definition: vpRect.h:163