34#include <visp3/core/vpImageCircle.h>
35#include <visp3/core/vpMath.h>
39void computeIntersectionsLeftBorder(
const float &u_c,
const float &umin_roi,
const float &radius,
float &delta_theta);
40void computeIntersectionsRightBorder(
const float &u_c,
const float &umax_roi,
const float &radius,
float &delta_theta);
41void computeIntersectionsTopBorder(
const float &v_c,
const float &vmin_roi,
const float &radius,
float &delta_theta);
42void computeIntersBottomBorder(
const float &v_c,
const float &vmax_roi,
const float &radius,
float &delta_theta);
43void computePerpendicularAxesInters(
const float &u_c,
const float &v_c,
const float &radius,
44 const float &crossing_u,
const float &crossing_v,
45 std::pair<float, float> &theta_u_cross_min, std::pair<float, float> &theta_u_cross_max,
46 std::pair<float, float> &theta_v_cross_min, std::pair<float, float> &theta_v_cross_max);
47void computeIntersectionsTopLeft(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &vmin_roi,
48 const float &radius,
float &delta_theta);
49void computeIntersectionsTopRight(
const float &u_c,
const float &v_c,
const float &vmin_roi,
const float &umax_roi,
50 const float &radius,
float &delta_theta);
51void computeIntersectionsBottomLeft(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &vmax_roi,
52 const float &radius,
float &delta_theta);
53void computeIntersectionsBottomRight(
const float &u_c,
const float &v_c,
const float &vmax_roi,
const float &umax_roi,
54 const float &radius,
float &delta_theta);
55void computeIntersTopLeftBottom(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &vmin_roi,
56 const float &vmax_roi,
const float &radius,
float &delta_theta);
57void computeIntersTopRightBottom(
const float &u_c,
const float &v_c,
const float &umax_roi,
const float &vmin_roi,
58 const float &vmax_roi,
const float &radius,
float &delta_theta);
59void computeIntersTopBottomOnly(
const float &u_c,
const float &v_c,
const float &vmin_roi,
const float &vmax_roi,
60 const float &radius,
float &delta_theta);
61void computeIntersLeftRightTop(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &umax_roi,
62 const float &vmin_roi,
const float &radius,
float &delta_theta);
63void computeIntersLeftRightBottom(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &umax_roi,
64 const float &vmax_roi,
const float &radius,
float &delta_theta);
65void computeIntersectionsLeftRight(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &umax_roi,
66 const float &radius,
float &delta_theta);
67void computeIntersectionsAllAxes(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &umax_roi,
68 const float &vmin_roi,
const float &vmax_roi,
const float &radius,
float &delta_theta);
84#ifdef HAVE_OPENCV_CORE
87 const unsigned int index_0 = 0;
88 const unsigned int index_1 = 1;
89 const unsigned int index_2 = 2;
90 m_center =
vpImagePoint(
static_cast<double>(vec[index_1]),
static_cast<double>(vec[index_0]));
91 m_radius = vec[index_2];
104void computeIntersectionsLeftBorder(
const float &u_c,
const float &umin_roi,
const float &radius,
float &delta_theta)
109 float theta1 = std::acos((umin_roi - u_c) / radius);
111 float theta2 = -1.f * theta1;
112 float theta_min = std::min<float>(theta1, theta2);
113 float theta_max = std::max<float>(theta1, theta2);
114 delta_theta = theta_max - theta_min;
115 if ((u_c < umin_roi) && (std::abs(delta_theta - (val_2 * M_PI_FLOAT)) < (2.f * std::numeric_limits<float>::epsilon()))) {
129void computeIntersectionsRightBorder(
const float &u_c,
const float &umax_roi,
const float &radius,
float &delta_theta)
134 float theta1 = std::acos((umax_roi - u_c) / radius);
136 float theta2 = -1.f * theta1;
137 float theta_min = std::min<float>(theta1, theta2);
138 float theta_max = std::max<float>(theta1, theta2);
139 delta_theta = (2.f * M_PI_FLOAT) - (theta_max - theta_min);
140 if ((u_c > umax_roi) && (std::abs(delta_theta - (val_2 * M_PI_FLOAT)) < (2.f * std::numeric_limits<float>::epsilon()))) {
154void computeIntersectionsTopBorder(
const float &v_c,
const float &vmin_roi,
const float &radius,
float &delta_theta)
159 float theta1 = std::asin((v_c - vmin_roi) / radius);
164 theta2 = M_PI_FLOAT - theta1;
167 theta2 = -theta1 - M_PI_FLOAT;
169 float theta_min = std::min<float>(theta1, theta2);
170 float theta_max = std::max<float>(theta1, theta2);
171 if ((std::abs(theta_max - theta_min) * radius) < 1.f) {
174 delta_theta = 2.f * M_PI_FLOAT;
176 else if (theta1 > 0.f) {
177 delta_theta = (2.f * M_PI_FLOAT) - (theta_max - theta_min);
180 delta_theta = theta_max - theta_min;
182 if ((v_c < vmin_roi) && (std::abs(delta_theta - (val_2 * M_PI_FLOAT)) < (2.f * std::numeric_limits<float>::epsilon()))) {
196void computeIntersBottomBorder(
const float &v_c,
const float &vmax_roi,
const float &radius,
float &delta_theta)
201 float theta1 = std::asin((v_c - vmax_roi) / radius);
206 theta2 = M_PI_FLOAT - theta1;
209 theta2 = -theta1 - M_PI_FLOAT;
211 float theta_min = std::min<float>(theta1, theta2);
212 float theta_max = std::max<float>(theta1, theta2);
213 if ((std::abs(theta_max - theta_min) * radius) < 1.f) {
216 delta_theta = 2.f * M_PI_FLOAT;
218 else if (theta1 > 0.f) {
219 delta_theta = theta_max - theta_min;
222 delta_theta = (2.f * M_PI_FLOAT) - (theta_max - theta_min);
224 if ((v_c > vmax_roi) && (std::abs(delta_theta - (val_2 * M_PI_FLOAT)) < (2.f * std::numeric_limits<float>::epsilon()))) {
243void computePerpendicularAxesInters(
const float &u_c,
const float &v_c,
const float &radius,
244 const float &crossing_u,
const float &crossing_v,
245 std::pair<float, float> &theta_u_cross_min, std::pair<float, float> &theta_u_cross_max,
246 std::pair<float, float> &theta_v_cross_min, std::pair<float, float> &theta_v_cross_max)
251 float theta_u_cross = std::asin((v_c - crossing_u) / radius);
253 float theta_u_cross_2 = 0.f;
254 if (theta_u_cross > 0) {
255 theta_u_cross_2 = M_PI_FLOAT - theta_u_cross;
258 theta_u_cross_2 = -M_PI_FLOAT - theta_u_cross;
261 float u_ucross = u_c + (radius * std::cos(theta_u_cross));
262 float u_ucross2 = u_c + (radius * std::cos(theta_u_cross_2));
264 if (u_ucross < u_ucross2) {
265 theta_u_cross_min.first = theta_u_cross;
266 theta_u_cross_min.second = u_ucross;
267 theta_u_cross_max.first = theta_u_cross_2;
268 theta_u_cross_max.second = u_ucross2;
271 theta_u_cross_min.first = theta_u_cross_2;
272 theta_u_cross_min.second = u_ucross2;
273 theta_u_cross_max.first = theta_u_cross;
274 theta_u_cross_max.second = u_ucross;
280 float theta_v_cross = std::acos((crossing_v - u_c) / radius);
282 float theta_v_cross_2 = -theta_v_cross;
285 float v_vcross = v_c - (radius * std::sin(theta_v_cross));
286 float v_vcross2 = v_c - (radius * std::sin(theta_v_cross_2));
288 if (v_vcross < v_vcross2) {
289 theta_v_cross_min.first = theta_v_cross;
290 theta_v_cross_min.second = v_vcross;
291 theta_v_cross_max.first = theta_v_cross_2;
292 theta_v_cross_max.second = v_vcross2;
295 theta_v_cross_min.first = theta_v_cross_2;
296 theta_v_cross_min.second = v_vcross2;
297 theta_v_cross_max.first = theta_v_cross;
298 theta_v_cross_max.second = v_vcross;
313void computeIntersectionsTopLeft(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &vmin_roi,
314 const float &radius,
float &delta_theta)
316 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
317 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
318 float crossing_u = vmin_roi;
319 float crossing_v = umin_roi;
320 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v,
321 crossing_theta_u_min, crossing_theta_u_max,
322 crossing_theta_v_min, crossing_theta_v_max);
323 float theta_u_min = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
324 float theta_u_max = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
325 float u_umin = crossing_theta_u_min.second;
326 float u_umax = crossing_theta_u_max.second;
327 float v_vmin = crossing_theta_v_min.second;
328 float v_vmax = crossing_theta_v_max.second;
329 if ((u_umin < umin_roi) && (u_umax >= umin_roi) && (v_vmin < vmin_roi) && (v_vmax >= vmin_roi)) {
332 delta_theta = theta_u_max - theta_v_max;
334 else if ((u_umin >= umin_roi) && (u_umax >= umin_roi) && (v_vmin >= vmin_roi) && (v_vmax >= vmin_roi)) {
337 delta_theta = (theta_v_min - theta_u_min) + (theta_u_max - theta_v_max);
339 else if ((u_umin < umin_roi) && (u_umax < umin_roi) && (v_vmin >= vmin_roi) && (v_vmax >= vmin_roi)) {
343 computeIntersectionsLeftBorder(u_c, umin_roi, radius, delta_theta);
345 else if ((u_umin >= umin_roi) && (u_umax >= umin_roi) && (v_vmin <= vmin_roi) && (v_vmax <= vmin_roi)) {
349 computeIntersectionsTopBorder(v_c, vmin_roi, radius, delta_theta);
364void computeIntersectionsTopRight(
const float &u_c,
const float &v_c,
const float &vmin_roi,
const float &umax_roi,
365 const float &radius,
float &delta_theta)
368 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
369 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
370 computePerpendicularAxesInters(u_c, v_c, radius, vmin_roi, umax_roi,
371 crossing_theta_u_min, crossing_theta_u_max,
372 crossing_theta_v_min, crossing_theta_v_max);
373 float theta_u_min = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
374 float theta_u_max = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
375 float u_umin = crossing_theta_u_min.second;
376 float u_umax = crossing_theta_u_max.second;
377 float v_vmin = crossing_theta_v_min.second;
378 float v_vmax = crossing_theta_v_max.second;
379 if ((u_umin <= umax_roi) && (v_vmin < vmin_roi) && (u_umax >= umax_roi) && (v_vmax >= vmin_roi)) {
382 delta_theta = theta_v_max - theta_u_min;
383 if (delta_theta < 0) {
385 delta_theta += 2.f * M_PI_FLOAT;
388 else if ((u_umin <= umax_roi) && (v_vmin >= vmin_roi) && (u_umax <= umax_roi) && (v_vmax >= vmin_roi)) {
391 delta_theta = (val_2 * M_PI_FLOAT) - ((theta_u_min - theta_u_max) + (theta_v_min - theta_v_max));
393 else if ((u_umin >= umax_roi) && (v_vmin >= vmin_roi) && (u_umax >= umax_roi) && (v_vmax >= vmin_roi)) {
397 computeIntersectionsRightBorder(u_c, umax_roi, radius, delta_theta);
399 else if ((u_umin <= umax_roi) && (v_vmin <= vmin_roi) && (u_umax <= umax_roi) && (v_vmax <= vmin_roi)) {
403 computeIntersectionsTopBorder(v_c, vmin_roi, radius, delta_theta);
418void computeIntersectionsBottomLeft(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &vmax_roi,
419 const float &radius,
float &delta_theta)
421 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
422 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
423 float crossing_u = vmax_roi;
424 float crossing_v = umin_roi;
425 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v,
426 crossing_theta_u_min, crossing_theta_u_max,
427 crossing_theta_v_min, crossing_theta_v_max);
428 float theta_u_min = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
429 float theta_u_max = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
430 float u_umin = crossing_theta_u_min.second;
431 float u_umax = crossing_theta_u_max.second;
432 float v_vmin = crossing_theta_v_min.second;
433 float v_vmax = crossing_theta_v_max.second;
434 if ((u_umin < umin_roi) && (u_umax >= umin_roi) && (v_vmin <= vmax_roi) && (v_vmax > vmax_roi)) {
437 delta_theta = theta_v_min - theta_u_max;
439 else if ((u_umin >= umin_roi) && (u_umax >= umin_roi) && (v_vmin <= vmax_roi) && (v_vmax <= vmax_roi)) {
442 delta_theta = (theta_v_min - theta_u_max) + (theta_u_min - theta_v_max);
444 else if ((u_umin < umin_roi) && (u_umax < umin_roi) && (v_vmin <= vmax_roi) && (v_vmax <= vmax_roi)) {
448 computeIntersectionsLeftBorder(u_c, umin_roi, radius, delta_theta);
450 else if ((u_umin >= umin_roi) && (u_umax >= umin_roi) && (v_vmin >= vmax_roi) && (v_vmax >= vmax_roi)) {
454 computeIntersBottomBorder(v_c, vmax_roi, radius, delta_theta);
469void computeIntersectionsBottomRight(
const float &u_c,
const float &v_c,
const float &vmax_roi,
const float &umax_roi,
470 const float &radius,
float &delta_theta)
472 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
473 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
474 float crossing_u = vmax_roi;
475 float crossing_v = umax_roi;
476 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v,
477 crossing_theta_u_min, crossing_theta_u_max,
478 crossing_theta_v_min, crossing_theta_v_max);
479 float theta_u_min = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
480 float theta_u_max = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
481 float u_umin = crossing_theta_u_min.second;
482 float u_umax = crossing_theta_u_max.second;
483 float v_vmin = crossing_theta_v_min.second;
484 float v_vmax = crossing_theta_v_max.second;
485 if ((u_umin <= umax_roi) && (u_umax > umax_roi) && (v_vmin <= vmax_roi) && (v_vmax > vmax_roi)) {
488 delta_theta = theta_u_min - theta_v_min;
489 if (delta_theta < 0) {
491 delta_theta += 2.f * M_PI_FLOAT;
494 else if ((u_umin <= umax_roi) && (u_umax <= umax_roi) && (v_vmin <= vmax_roi) && (v_vmax <= vmax_roi)) {
497 delta_theta = (2.f * M_PI_FLOAT) - ((theta_v_min - theta_v_max) + (theta_u_max - theta_u_min));
499 else if ((u_umin > umax_roi) && (u_umax > umax_roi) && (v_vmin <= vmax_roi) && (v_vmax <= vmax_roi)) {
503 computeIntersectionsRightBorder(u_c, umax_roi, radius, delta_theta);
505 else if ((u_umin <= umax_roi) && (u_umax <= umax_roi) && (v_vmin > vmax_roi) && (v_vmax > vmax_roi)) {
509 computeIntersBottomBorder(v_c, vmax_roi, radius, delta_theta);
525void computeIntersTopLeftBottom(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &vmin_roi,
526 const float &vmax_roi,
const float &radius,
float &delta_theta)
529 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
530 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
531 float crossing_u_top = vmin_roi;
532 float crossing_v = umin_roi;
533 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_top, crossing_v,
534 crossing_theta_u_min, crossing_theta_u_max,
535 crossing_theta_v_min, crossing_theta_v_max);
536 float theta_u_min_top = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
537 float theta_u_max_top = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
538 float u_umin_top = crossing_theta_u_min.second;
539 float u_umax_top = crossing_theta_u_max.second;
540 float v_vmin = crossing_theta_v_min.second;
541 float v_vmax = crossing_theta_v_max.second;
544 float crossing_u_bottom = vmax_roi;
545 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_bottom, crossing_v,
546 crossing_theta_u_min, crossing_theta_u_max,
547 crossing_theta_v_min, crossing_theta_v_max);
548 float theta_u_min_bottom = crossing_theta_u_min.first;
549 float theta_u_max_bottom = crossing_theta_u_max.first;
550 float u_umin_bottom = crossing_theta_u_min.second;
551 float u_umax_bottom = crossing_theta_u_max.second;
552 if ((u_umin_top >= umin_roi) && (u_umin_bottom >= umin_roi) && (v_vmin >= vmin_roi) && (v_vmax <= vmax_roi)) {
554 delta_theta = (theta_v_min - theta_u_min_top) + (theta_u_max_top - theta_u_max_bottom) + (theta_u_min_bottom - theta_v_max);
556 else if ((u_umin_top <= umin_roi) && (v_vmin <= vmin_roi) && (u_umin_bottom <= umin_roi) && (v_vmax >= vmax_roi)) {
558 delta_theta = (theta_u_max_top - theta_u_max_bottom);
560 else if ((u_umax_top <= umin_roi) && (u_umax_bottom <= umin_roi) && (v_vmin >= vmin_roi) && (v_vmax <= vmax_roi)) {
562 computeIntersectionsLeftBorder(u_c, umin_roi, radius, delta_theta);
564 else if ((u_umax_bottom > umin_roi) && (v_vmin >= vmin_roi)) {
566 computeIntersectionsBottomLeft(u_c, v_c, umin_roi, vmax_roi, radius, delta_theta);
568 else if ((u_umax_top > umin_roi) && (v_vmax <= vmax_roi)) {
570 computeIntersectionsTopLeft(u_c, v_c, umin_roi, vmin_roi, radius, delta_theta);
586void computeIntersTopRightBottom(
const float &u_c,
const float &v_c,
const float &umax_roi,
const float &vmin_roi,
587 const float &vmax_roi,
const float &radius,
float &delta_theta)
590 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
591 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
592 float crossing_u_top = vmin_roi;
593 float crossing_v = umax_roi;
594 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_top, crossing_v,
595 crossing_theta_u_min, crossing_theta_u_max,
596 crossing_theta_v_min, crossing_theta_v_max);
597 float theta_u_min_top = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
598 float theta_u_max_top = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
599 float u_umin_top = crossing_theta_u_min.second;
600 float u_umax_top = crossing_theta_u_max.second;
601 float v_vmin = crossing_theta_v_min.second;
602 float v_vmax = crossing_theta_v_max.second;
605 float crossing_u_bottom = vmax_roi;
606 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_bottom, crossing_v,
607 crossing_theta_u_min, crossing_theta_u_max,
608 crossing_theta_v_min, crossing_theta_v_max);
609 float theta_u_min_bottom = crossing_theta_u_min.first;
610 float theta_u_max_bottom = crossing_theta_u_max.first;
611 float u_umin_bottom = crossing_theta_u_min.second;
612 float u_umax_bottom = crossing_theta_u_max.second;
613 bool crossOnceTopHor = (u_umin_top <= umax_roi) && (u_umax_top > umax_roi);
614 bool dontCrossVert = (v_vmin <= vmin_roi) && (v_vmax >= vmax_roi);
615 bool crossOnceBotHor = (u_umin_bottom <= umax_roi) && (u_umax_bottom > umax_roi);
616 if ((u_umax_top <= umax_roi) && (u_umax_bottom <= umax_roi) && (v_vmin >= vmin_roi) && (v_vmax <= vmax_roi)) {
618 delta_theta = (2.f * M_PI_FLOAT) - ((theta_u_min_top - theta_u_max_top) + (theta_v_min - theta_v_max) + (theta_u_max_bottom - theta_u_min_bottom));
620 else if (crossOnceTopHor && crossOnceBotHor && dontCrossVert) {
622 delta_theta = (theta_u_max_top - theta_u_max_bottom);
624 else if ((u_umin_top >= umax_roi) && (u_umin_bottom >= umax_roi) && (v_vmin >= vmin_roi) && (v_vmax <= vmax_roi)) {
626 computeIntersectionsRightBorder(u_c, umax_roi, radius, delta_theta);
628 else if ((u_umin_bottom <= umax_roi) && (v_vmin >= vmin_roi)) {
630 computeIntersectionsBottomRight(u_c, v_c, vmax_roi, umax_roi, radius, delta_theta);
632 else if ((u_umin_top <= umax_roi) && (v_vmax <= vmax_roi)) {
634 computeIntersectionsTopRight(u_c, v_c, vmin_roi, umax_roi, radius, delta_theta);
649void computeIntersTopBottomOnly(
const float &u_c,
const float &v_c,
const float &vmin_roi,
const float &vmax_roi,
650 const float &radius,
float &delta_theta)
655 float theta_u_cross_top = std::asin((v_c - vmin_roi) / radius);
657 float theta_u_cross_top_2 = 0.f;
658 if (theta_u_cross_top > 0) {
659 theta_u_cross_top_2 = M_PI_FLOAT - theta_u_cross_top;
662 theta_u_cross_top_2 = -M_PI_FLOAT - theta_u_cross_top;
666 float u_ucross_top = u_c + (radius * std::cos(theta_u_cross_top));
667 float u_ucross_top_2 = u_c + (radius * std::cos(theta_u_cross_top_2));
669 float theta_u_cross_top_min = 0.f, theta_u_cross_top_max = 0.f;
670 if (u_ucross_top < u_ucross_top_2) {
671 theta_u_cross_top_min = theta_u_cross_top;
672 theta_u_cross_top_max = theta_u_cross_top_2;
675 theta_u_cross_top_min = theta_u_cross_top_2;
676 theta_u_cross_top_max = theta_u_cross_top;
682 float theta_u_cross_bottom = std::asin((v_c - vmax_roi) / radius);
684 float theta_u_cross_bottom_2 = 0.f;
685 if (theta_u_cross_bottom > 0) {
686 theta_u_cross_bottom_2 = M_PI_FLOAT - theta_u_cross_bottom;
689 theta_u_cross_bottom_2 = -M_PI_FLOAT - theta_u_cross_bottom;
693 float u_ucross_bottom = u_c + (radius * std::cos(theta_u_cross_bottom));
694 float u_ucross_bottom_2 = u_c + (radius * std::cos(theta_u_cross_bottom_2));
697 float theta_u_cross_bottom_min = 0.f, theta_u_cross_bottom_max = 0.f;
698 if (u_ucross_bottom < u_ucross_bottom_2) {
699 theta_u_cross_bottom_min = theta_u_cross_bottom;
700 theta_u_cross_bottom_max = theta_u_cross_bottom_2;
703 theta_u_cross_bottom_min = theta_u_cross_bottom_2;
704 theta_u_cross_bottom_max = theta_u_cross_bottom;
709 delta_theta = (2.f * M_PI_FLOAT) - ((theta_u_cross_top_min - theta_u_cross_top_max) + (theta_u_cross_bottom_max - theta_u_cross_bottom_min));
724void computeIntersLeftRightTop(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &umax_roi,
725 const float &vmin_roi,
const float &radius,
float &delta_theta)
728 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
729 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
730 float crossing_u = vmin_roi;
731 float crossing_v_left = umin_roi;
732 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v_left,
733 crossing_theta_u_min, crossing_theta_u_max,
734 crossing_theta_v_min, crossing_theta_v_max);
735 float theta_u_min = crossing_theta_u_min.first;
736 float theta_u_max = crossing_theta_u_max.first;
737 float u_umin = crossing_theta_u_min.second;
738 float u_umax = crossing_theta_u_max.second;
739 float theta_v_min_left = crossing_theta_v_min.first;
740 float theta_v_max_left = crossing_theta_v_max.first;
741 float v_vmin_left = crossing_theta_v_min.second;
742 float v_vmax_left = crossing_theta_v_max.second;
745 float crossing_v_right = umax_roi;
746 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v_right,
747 crossing_theta_u_min, crossing_theta_u_max,
748 crossing_theta_v_min, crossing_theta_v_max);
749 float theta_v_min_right = crossing_theta_v_min.first;
750 float theta_v_max_right = crossing_theta_v_max.first;
751 float v_vmin_right = crossing_theta_v_min.second;
752 float v_vmax_right = crossing_theta_v_max.second;
754 if ((u_umin >= umin_roi) && (u_umax <= umax_roi) && (v_vmin_left >= vmin_roi) && (v_vmin_right >= vmin_roi)) {
756 delta_theta = (theta_v_min_left - theta_u_min) + (theta_u_max - theta_v_min_right) + (theta_v_max_right - theta_v_max_left);
758 else if ((u_umin <= umin_roi) && (u_umax >= umax_roi) && (v_vmax_left >= vmin_roi) && (v_vmax_right >= vmin_roi)) {
760 delta_theta = (theta_v_max_right - theta_v_max_left);
762 else if ((v_vmax_left <= vmin_roi) && (v_vmax_right <= vmin_roi) && (u_umin >= umin_roi) && (u_umax <= umax_roi)) {
764 computeIntersectionsTopBorder(v_c, vmin_roi, radius, delta_theta);
766 else if ((u_umax >= umin_roi) && (v_vmax_left >= vmin_roi)) {
768 computeIntersectionsTopLeft(u_c, v_c, umin_roi, vmin_roi, radius, delta_theta);
770 else if ((u_umin <= umax_roi) && (v_vmax_right >= vmin_roi)) {
772 computeIntersectionsTopRight(u_c, v_c, vmin_roi, umax_roi, radius, delta_theta);
788void computeIntersLeftRightBottom(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &umax_roi,
789 const float &vmax_roi,
const float &radius,
float &delta_theta)
792 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
793 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
794 float crossing_u = vmax_roi;
795 float crossing_v_left = umin_roi;
796 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v_left,
797 crossing_theta_u_min, crossing_theta_u_max,
798 crossing_theta_v_min, crossing_theta_v_max);
799 float theta_u_min = crossing_theta_u_min.first;
800 float theta_u_max = crossing_theta_u_max.first;
801 float u_umin = crossing_theta_u_min.second;
802 float u_umax = crossing_theta_u_max.second;
803 float theta_v_min_left = crossing_theta_v_min.first;
804 float theta_v_max_left = crossing_theta_v_max.first;
805 float v_vmin_left = crossing_theta_v_min.second;
809 float crossing_v_right = umax_roi;
810 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v_right,
811 crossing_theta_u_min, crossing_theta_u_max,
812 crossing_theta_v_min, crossing_theta_v_max);
813 float theta_v_min_right = crossing_theta_v_min.first;
814 float theta_v_max_right = crossing_theta_v_max.first;
815 float v_vmin_right = crossing_theta_v_min.second;
818 if ((u_umin >= umin_roi) && (u_umax <= umax_roi) && (v_vmin_left <= vmax_roi) && (v_vmin_right <= vmax_roi)) {
820 delta_theta = (theta_v_min_left - theta_v_min_right) + (theta_v_max_right - theta_u_max) + (theta_u_min - theta_v_max_left);
822 else if ((u_umin <= umin_roi) && (u_umax >= umax_roi) && (v_vmin_left <= vmax_roi) && (v_vmin_right <= vmax_roi)) {
824 delta_theta = (theta_v_min_left - theta_v_min_right);
826 else if ((v_vmin_left >= vmax_roi) && (v_vmin_right >= vmax_roi) && (u_umin >= umin_roi) && (u_umax <= umax_roi)) {
828 computeIntersBottomBorder(v_c, vmax_roi, radius, delta_theta);
830 else if ((u_umax >= umin_roi) && (v_vmin_right >= vmax_roi)) {
832 computeIntersectionsBottomLeft(u_c, v_c, umin_roi, vmax_roi, radius, delta_theta);
834 else if ((u_umin <= umax_roi) && (v_vmin_right <= vmax_roi)) {
836 computeIntersectionsBottomRight(u_c, v_c, vmax_roi, umax_roi, radius, delta_theta);
851void computeIntersectionsLeftRight(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &umax_roi,
852 const float &radius,
float &delta_theta)
858 float theta_v_cross_left = std::acos((umin_roi - u_c) / radius);
860 float theta_v_cross_left_2 = -theta_v_cross_left;
863 float v_vcross_left = v_c - (radius * std::sin(theta_v_cross_left));
864 float v_vcross_left_2 = v_c - (radius * std::sin(theta_v_cross_left_2));
866 float theta_v_cross_left_min = 0.f, theta_v_cross_left_max = 0.f;
867 if (v_vcross_left < v_vcross_left_2) {
868 theta_v_cross_left_min = theta_v_cross_left;
869 theta_v_cross_left_max = theta_v_cross_left_2;
872 theta_v_cross_left_min = theta_v_cross_left_2;
873 theta_v_cross_left_max = theta_v_cross_left;
880 float theta_v_cross_right = std::acos((umax_roi - u_c) / radius);
882 float theta_v_cross_right_2 = -theta_v_cross_right;
885 float v_vcross_right = v_c - (radius * std::sin(theta_v_cross_right));
886 float v_vcross_right_2 = v_c - (radius * std::sin(theta_v_cross_right_2));
889 float theta_v_cross_right_min = 0.f, theta_v_cross_right_max = 0.f;
890 if (v_vcross_right < v_vcross_right_2) {
891 theta_v_cross_right_min = theta_v_cross_right;
892 theta_v_cross_right_max = theta_v_cross_right_2;
895 theta_v_cross_right_min = theta_v_cross_right_2;
896 theta_v_cross_right_max = theta_v_cross_right;
901 delta_theta = (theta_v_cross_left_min - theta_v_cross_right_min) + (theta_v_cross_right_max - theta_v_cross_left_max);
917void computeIntersectionsAllAxes(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &umax_roi,
918 const float &vmin_roi,
const float &vmax_roi,
const float &radius,
float &delta_theta)
921 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
922 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
923 float crossing_u_top = vmin_roi;
924 float crossing_v_left = umin_roi;
925 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_top, crossing_v_left,
926 crossing_theta_u_min, crossing_theta_u_max,
927 crossing_theta_v_min, crossing_theta_v_max);
928 float theta_u_min_top = crossing_theta_u_min.first;
929 float theta_u_max_top = crossing_theta_u_max.first;
930 float theta_v_min_left = crossing_theta_v_min.first;
931 float theta_v_max_left = crossing_theta_v_max.first;
934 float crossing_u_bottom = vmax_roi;
935 float crossing_v_right = umax_roi;
936 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_bottom, crossing_v_right,
937 crossing_theta_u_min, crossing_theta_u_max,
938 crossing_theta_v_min, crossing_theta_v_max);
939 float theta_u_min_bottom = crossing_theta_u_min.first;
940 float theta_u_max_bottom = crossing_theta_u_max.first;
941 float theta_v_min_right = crossing_theta_v_min.first;
942 float theta_v_max_right = crossing_theta_v_max.first;
943 delta_theta = (theta_v_min_left - theta_u_min_top) + (theta_u_max_top - theta_v_min_right);
944 delta_theta += (theta_v_max_right - theta_u_max_bottom) + (theta_u_min_bottom - theta_v_max_left);
949 float delta_theta = 0.f;
951 float u_c =
static_cast<float>(center.
get_u());
952 float v_c =
static_cast<float>(center.
get_v());
953 float radius = m_radius;
954 float roi_w =
static_cast<float>(roi.
getWidth());
955 float roi_h =
static_cast<float>(roi.
getHeight());
957 float umin_roi =
static_cast<float>(topLeft.
get_u());
958 float vmin_roi =
static_cast<float>(topLeft.
get_v());
959 float umax_roi = umin_roi + roi_w;
960 float vmax_roi = vmin_roi + roi_h;
961 bool touchLeftBorder = (u_c - radius) <= umin_roi;
962 bool touchRightBorder = (u_c + radius) >= umax_roi;
963 bool touchTopBorder = (v_c - radius) <= vmin_roi;
964 bool touchBottomBorder = (v_c + radius) >= vmax_roi;
965 bool isHorizontallyOK = ((!touchLeftBorder) && (!touchRightBorder));
966 bool isVerticallyOK = ((!touchTopBorder) && (!touchBottomBorder));
967 if (isHorizontallyOK && isVerticallyOK && roi.
isInside(m_center)) {
971 delta_theta = 2.f * M_PI_FLOAT;
973 else if (touchBottomBorder && (!touchLeftBorder) && (!touchRightBorder) && (!touchTopBorder)) {
975 computeIntersBottomBorder(v_c, vmax_roi, radius, delta_theta);
977 else if ((!touchBottomBorder) && touchLeftBorder && (!touchRightBorder) && (!touchTopBorder)) {
979 computeIntersectionsLeftBorder(u_c, umin_roi, radius, delta_theta);
981 else if ((!touchBottomBorder) && (!touchLeftBorder) && touchRightBorder && (!touchTopBorder)) {
983 computeIntersectionsRightBorder(u_c, umax_roi, radius, delta_theta);
985 else if ((!touchBottomBorder) && (!touchLeftBorder) && (!touchRightBorder) && touchTopBorder) {
987 computeIntersectionsTopBorder(v_c, vmin_roi, radius, delta_theta);
989 else if (touchBottomBorder && touchLeftBorder && (!touchRightBorder) && (!touchTopBorder)) {
991 computeIntersectionsBottomLeft(u_c, v_c, umin_roi, vmax_roi, radius, delta_theta);
993 else if (touchBottomBorder && (!touchLeftBorder) && touchRightBorder && (!touchTopBorder)) {
995 computeIntersectionsBottomRight(u_c, v_c, vmax_roi, umax_roi, radius, delta_theta);
997 else if ((!touchBottomBorder) && touchLeftBorder && (!touchRightBorder) && touchTopBorder) {
999 computeIntersectionsTopLeft(u_c, v_c, umin_roi, vmin_roi, radius, delta_theta);
1001 else if ((!touchBottomBorder) && (!touchLeftBorder) && touchRightBorder && touchTopBorder) {
1003 computeIntersectionsTopRight(u_c, v_c, vmin_roi, umax_roi, radius, delta_theta);
1005 else if (touchBottomBorder && touchTopBorder && touchLeftBorder && (!touchRightBorder)) {
1007 computeIntersTopLeftBottom(u_c, v_c, umin_roi, vmin_roi, vmax_roi, radius, delta_theta);
1009 else if (touchBottomBorder && touchTopBorder && (!touchLeftBorder) && touchRightBorder) {
1011 computeIntersTopRightBottom(u_c, v_c, umax_roi, vmin_roi, vmax_roi, radius, delta_theta);
1013 else if (touchBottomBorder && touchTopBorder && (!touchLeftBorder) && (!touchRightBorder)) {
1015 computeIntersTopBottomOnly(u_c, v_c, vmin_roi, vmax_roi, radius, delta_theta);
1017 else if ((!touchBottomBorder) && touchTopBorder && touchLeftBorder && touchRightBorder) {
1019 computeIntersLeftRightTop(u_c, v_c, umin_roi, umax_roi, vmin_roi, radius, delta_theta);
1021 else if (touchBottomBorder && (!touchTopBorder) && touchLeftBorder && touchRightBorder) {
1023 computeIntersLeftRightBottom(u_c, v_c, umin_roi, umax_roi, vmax_roi, radius, delta_theta);
1025 else if (touchLeftBorder && touchRightBorder && (!touchTopBorder) && (!touchBottomBorder)) {
1027 computeIntersectionsLeftRight(u_c, v_c, umin_roi, umax_roi, radius, delta_theta);
1029 else if (touchLeftBorder && touchRightBorder && touchTopBorder && touchBottomBorder) {
1031 computeIntersectionsAllAxes(u_c, v_c, umin_roi, umax_roi, vmin_roi, vmax_roi, radius, delta_theta);
1034 std::cerr <<
"touchLeft = " << (touchLeftBorder ?
"true" :
"false") <<
"\ttouchRight = " << (touchRightBorder ?
"true" :
"false") << std::endl;
1035 std::cerr <<
"touchTop = " << (touchTopBorder ?
"true" :
"false") <<
"\ttouchBottom = " << (touchBottomBorder ?
"true" :
"false") << std::endl;
1036 std::cerr <<
"u_c = " << u_c <<
"\tv_c = " << v_c <<
"\tradius = " << radius << std::endl;
1037 std::cerr <<
"umin_roi = " << umin_roi <<
"\tumax_roi = " << umax_roi << std::endl;
1038 std::cerr <<
"vmin_roi = " << vmin_roi <<
"\tvmax_roi = " << vmax_roi << std::endl << std::flush;
1042 if ((delta_theta < 0) || (delta_theta >(2.f * M_PI_FLOAT))) {
1044 if ((rest < roundingTolerance) && ((delta_theta < -M_PI_FLOAT) || (delta_theta > M_PI_FLOAT))) {
1046 delta_theta = 2.f * M_PI_FLOAT;
1060 return delta_theta * m_radius;
1063#if (VISP_CXX_STANDARD == VISP_CXX_STANDARD_98)
1066void incrementIfIsInMask(
const vpImage<bool> &mask,
const int &width,
const int &height,
const int &x,
const int &y,
1067 unsigned int &count);
1070void incrementIfIsInMask(
const vpImage<bool> &mask,
const int &width,
const int &height,
const int &x,
const int &y,
1071 unsigned int &count)
1073 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
1087 const float xm =
static_cast<float>(m_center.get_u()), ym =
static_cast<float>(m_center.get_v());
1088 const float r_float =
static_cast<float>(m_radius);
1089 const int width =
static_cast<int>(mask.
getWidth());
1090 const int height =
static_cast<int>(mask.
getHeight());
1092#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
1094 auto incrementIfIsInMask = [](
const vpImage<bool> &mask_,
const int &width_,
const int &height_,
const int &x_,
const int &y_,
1095 unsigned int &count_) {
1096 if ((x_ < 0) || (y_ < 0) || (x_ >= width_) || (y_ >= height_)) {
1100 if (mask_[y_][x_]) {
1106 unsigned int count = 0;
1108 const float thetaStop = M_PI_2_FLOAT;
1110 int x1 = 0, x2 = 0, x3 = 0, x4 = 0;
1111 int y1 = 0, y2 = 0, y3 = 0, y4 = 0;
1112 while (theta < thetaStop) {
1113 float cos_theta = std::cos(theta);
1114 float sin_theta = std::sin(theta);
1115 float rcos_pos = r_float * cos_theta;
1116 float rsin_pos = r_float * sin_theta;
1117 x1 =
static_cast<int>(xm + rcos_pos);
1118 y1 =
static_cast<int>(ym + rsin_pos);
1119 x2 =
static_cast<int>(xm - rsin_pos);
1120 y2 =
static_cast<int>(ym + rcos_pos);
1121 x3 =
static_cast<int>(xm - rcos_pos);
1122 y3 =
static_cast<int>(ym - rsin_pos);
1123 x4 =
static_cast<int>(xm + rsin_pos);
1124 y4 =
static_cast<int>(ym - rcos_pos);
1125 incrementIfIsInMask(mask, width, height, x1, y1, count);
1126 incrementIfIsInMask(mask, width, height, x2, y2, count);
1127 incrementIfIsInMask(mask, width, height, x3, y3, count);
1128 incrementIfIsInMask(mask, width, height, x4, y4, count);
1134 float dthetaCosPos = 1.f / (r_float * cos_theta);
1135 float dthetaCosNeg = -1.f / (r_float * cos_theta);
1136 float dthetaSinPos = 1.f / (r_float * sin_theta);
1137 float dthetaSinNeg = -1.f / (r_float * sin_theta);
1138 float dthetaPos = 0.f;
1139 if ((sin_theta < 0.f) && (cos_theta > 0.f)) {
1141 dthetaPos = std::min<float>(dthetaCosPos, dthetaSinNeg);
1143 else if ((sin_theta > 0.f) && (cos_theta < 0.f)) {
1145 dthetaPos = std::min<float>(dthetaCosNeg, dthetaSinPos);
1147 else if ((sin_theta < 0.f) && (cos_theta < 0.f)) {
1149 dthetaPos = std::min<float>(dthetaCosNeg, dthetaSinNeg);
1151 else if ((sin_theta > 0.f) && (cos_theta > 0.f)) {
1153 dthetaPos = std::min<float>(dthetaCosPos, dthetaSinPos);
1157 if (cos_theta > 0.f) {
1158 dthetaPos = dthetaCosNeg;
1161 dthetaPos = dthetaCosPos;
1166 if (sin_theta > 0.f) {
1167 dthetaPos = dthetaSinNeg;
1170 dthetaPos = dthetaSinPos;
1190 double radius =
static_cast<double>(m_radius);
1197 const int val_4 = 4;
1198 return (m_radius * m_radius) / val_4;
1203 const int val_4 = 4;
1204 return (m_radius * m_radius) / val_4;
1217 return (sameCenter && sameRadius);
error that can be emitted by ViSP classes.
Class that defines a 2D circle in an image.
float computeAngularCoverageInRoI(const vpRect &roi, const float &roundingTolerance=0.001f) const
vpImagePoint getCenter() const
float computeArcLengthInRoI(const vpRect &roi, const float &roundingTolerance=0.001f) const
unsigned int computePixelsInMask(const vpImage< bool > &mask) const
Count the number of pixels of the circle whose value in the mask is true.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition of the vpImage class member functions.
unsigned int getWidth() const
unsigned int getHeight() const
static float getAngleBetweenMinPiAndPi(const float &theta)
static bool equal(double x, double y, double threshold=0.001)
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.
Defines a rectangle in the plane.
bool isInside(const vpImagePoint &ip) const
vpImagePoint getTopLeft() const