34 #include <visp3/core/vpImageCircle.h>
35 #include <visp3/core/vpMath.h>
52 #ifdef HAVE_OPENCV_CORE
55 const unsigned int index_0 = 0;
56 const unsigned int index_1 = 1;
57 const unsigned int index_2 = 2;
59 m_radius = vec[index_2];
72 void computeIntersectionsLeftBorder(
const float &u_c,
const float &umin_roi,
const float &radius,
78 float theta1 = std::acos((umin_roi - u_c) / radius);
80 float theta2 = -1.f * theta1;
81 float theta_min = std::min<float>(theta1, theta2);
82 float theta_max = std::max<float>(theta1, theta2);
83 delta_theta = theta_max - theta_min;
84 if ((u_c < umin_roi) && (std::abs(delta_theta - (val_2 * M_PI_FLOAT)) < (2.f * std::numeric_limits<float>::epsilon()))) {
98 void computeIntersectionsRightBorder(
const float &u_c,
const float &umax_roi,
const float &radius,
104 float theta1 = std::acos((umax_roi - u_c) / radius);
106 float theta2 = -1.f * theta1;
107 float theta_min = std::min<float>(theta1, theta2);
108 float theta_max = std::max<float>(theta1, theta2);
109 delta_theta = (2.f * M_PI_FLOAT) - (theta_max - theta_min);
110 if ((u_c > umax_roi) && (std::abs(delta_theta - (val_2 * M_PI_FLOAT)) < (2.f * std::numeric_limits<float>::epsilon()))) {
124 void computeIntersectionsTopBorder(
const float &v_c,
const float &vmin_roi,
const float &radius,
130 float theta1 = std::asin((v_c - vmin_roi) / radius);
135 theta2 = M_PI_FLOAT - theta1;
138 theta2 = -theta1 - M_PI_FLOAT;
140 float theta_min = std::min<float>(theta1, theta2);
141 float theta_max = std::max<float>(theta1, theta2);
142 if ((std::abs(theta_max - theta_min) * radius) < 1.f) {
145 delta_theta = 2.f * M_PI_FLOAT;
147 else if (theta1 > 0.f) {
148 delta_theta = (2.f * M_PI_FLOAT) - (theta_max - theta_min);
151 delta_theta = theta_max - theta_min;
153 if ((v_c < vmin_roi) && (std::abs(delta_theta - (val_2 * M_PI_FLOAT)) < (2.f * std::numeric_limits<float>::epsilon()))) {
167 void computeIntersBottomBorder(
const float &v_c,
const float &vmax_roi,
const float &radius,
173 float theta1 = std::asin((v_c - vmax_roi) / radius);
178 theta2 = M_PI_FLOAT - theta1;
181 theta2 = -theta1 - M_PI_FLOAT;
183 float theta_min = std::min<float>(theta1, theta2);
184 float theta_max = std::max<float>(theta1, theta2);
185 if ((std::abs(theta_max - theta_min) * radius) < 1.f) {
188 delta_theta = 2.f * M_PI_FLOAT;
190 else if (theta1 > 0.f) {
191 delta_theta = theta_max - theta_min;
194 delta_theta = (2.f * M_PI_FLOAT) - (theta_max - theta_min);
196 if ((v_c > vmax_roi) && (std::abs(delta_theta - (val_2 * M_PI_FLOAT)) < (2.f * std::numeric_limits<float>::epsilon()))) {
215 void computePerpendicularAxesInters(
const float &u_c,
const float &v_c,
const float &radius,
216 const float &crossing_u,
const float &crossing_v,
217 std::pair<float, float> &theta_u_cross_min, std::pair<float, float> &theta_u_cross_max,
218 std::pair<float, float> &theta_v_cross_min, std::pair<float, float> &theta_v_cross_max)
223 float theta_u_cross = std::asin((v_c - crossing_u) / radius);
225 float theta_u_cross_2 = 0.f;
226 if (theta_u_cross > 0) {
227 theta_u_cross_2 = M_PI_FLOAT - theta_u_cross;
230 theta_u_cross_2 = -M_PI_FLOAT - theta_u_cross;
233 float u_ucross = u_c + (radius * std::cos(theta_u_cross));
234 float u_ucross2 = u_c + (radius * std::cos(theta_u_cross_2));
236 if (u_ucross < u_ucross2) {
237 theta_u_cross_min.first = theta_u_cross;
238 theta_u_cross_min.second = u_ucross;
239 theta_u_cross_max.first = theta_u_cross_2;
240 theta_u_cross_max.second = u_ucross2;
243 theta_u_cross_min.first = theta_u_cross_2;
244 theta_u_cross_min.second = u_ucross2;
245 theta_u_cross_max.first = theta_u_cross;
246 theta_u_cross_max.second = u_ucross;
252 float theta_v_cross = std::acos((crossing_v - u_c) / radius);
254 float theta_v_cross_2 = -theta_v_cross;
257 float v_vcross = v_c - (radius * std::sin(theta_v_cross));
258 float v_vcross2 = v_c - (radius * std::sin(theta_v_cross_2));
260 if (v_vcross < v_vcross2) {
261 theta_v_cross_min.first = theta_v_cross;
262 theta_v_cross_min.second = v_vcross;
263 theta_v_cross_max.first = theta_v_cross_2;
264 theta_v_cross_max.second = v_vcross2;
267 theta_v_cross_min.first = theta_v_cross_2;
268 theta_v_cross_min.second = v_vcross2;
269 theta_v_cross_max.first = theta_v_cross;
270 theta_v_cross_max.second = v_vcross;
285 void computeIntersectionsTopLeft(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &vmin_roi,
const float &radius,
288 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
289 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
290 float crossing_u = vmin_roi;
291 float crossing_v = umin_roi;
292 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v,
293 crossing_theta_u_min, crossing_theta_u_max,
294 crossing_theta_v_min, crossing_theta_v_max);
295 float theta_u_min = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
296 float theta_u_max = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
297 float u_umin = crossing_theta_u_min.second;
298 float u_umax = crossing_theta_u_max.second;
299 float v_vmin = crossing_theta_v_min.second;
300 float v_vmax = crossing_theta_v_max.second;
301 if ((u_umin < umin_roi) && (u_umax >= umin_roi) && (v_vmin < vmin_roi) && (v_vmax >= vmin_roi)) {
304 delta_theta = theta_u_max - theta_v_max;
306 else if ((u_umin >= umin_roi) && (u_umax >= umin_roi) && (v_vmin >= vmin_roi) && (v_vmax >= vmin_roi)) {
309 delta_theta = (theta_v_min - theta_u_min) + (theta_u_max - theta_v_max);
311 else if ((u_umin < umin_roi) && (u_umax < umin_roi) && (v_vmin >= vmin_roi) && (v_vmax >= vmin_roi)) {
315 computeIntersectionsLeftBorder(u_c, umin_roi, radius, delta_theta);
317 else if ((u_umin >= umin_roi) && (u_umax >= umin_roi) && (v_vmin <= vmin_roi) && (v_vmax <= vmin_roi)) {
321 computeIntersectionsTopBorder(v_c, vmin_roi, radius, delta_theta);
336 void computeIntersectionsTopRight(
const float &u_c,
const float &v_c,
const float &vmin_roi,
const float &umax_roi,
const float &radius,
340 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
341 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
342 computePerpendicularAxesInters(u_c, v_c, radius, vmin_roi, umax_roi,
343 crossing_theta_u_min, crossing_theta_u_max,
344 crossing_theta_v_min, crossing_theta_v_max);
345 float theta_u_min = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
346 float theta_u_max = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
347 float u_umin = crossing_theta_u_min.second;
348 float u_umax = crossing_theta_u_max.second;
349 float v_vmin = crossing_theta_v_min.second;
350 float v_vmax = crossing_theta_v_max.second;
351 if ((u_umin <= umax_roi) && (v_vmin < vmin_roi) && (u_umax >= umax_roi) && (v_vmax >= vmin_roi)) {
354 delta_theta = theta_v_max - theta_u_min;
355 if (delta_theta < 0) {
357 delta_theta += 2.f * M_PI_FLOAT;
360 else if ((u_umin <= umax_roi) && (v_vmin >= vmin_roi) && (u_umax <= umax_roi) && (v_vmax >= vmin_roi)) {
363 delta_theta = (val_2 * M_PI_FLOAT) - ((theta_u_min - theta_u_max) + (theta_v_min - theta_v_max));
365 else if ((u_umin >= umax_roi) && (v_vmin >= vmin_roi) && (u_umax >= umax_roi) && (v_vmax >= vmin_roi)) {
369 computeIntersectionsRightBorder(u_c, umax_roi, radius, delta_theta);
371 else if ((u_umin <= umax_roi) && (v_vmin <= vmin_roi) && (u_umax <= umax_roi) && (v_vmax <= vmin_roi)) {
375 computeIntersectionsTopBorder(v_c, vmin_roi, radius, delta_theta);
390 void computeIntersectionsBottomLeft(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &vmax_roi,
const float &radius,
393 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
394 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
395 float crossing_u = vmax_roi;
396 float crossing_v = umin_roi;
397 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v,
398 crossing_theta_u_min, crossing_theta_u_max,
399 crossing_theta_v_min, crossing_theta_v_max);
400 float theta_u_min = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
401 float theta_u_max = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
402 float u_umin = crossing_theta_u_min.second;
403 float u_umax = crossing_theta_u_max.second;
404 float v_vmin = crossing_theta_v_min.second;
405 float v_vmax = crossing_theta_v_max.second;
406 if ((u_umin < umin_roi) && (u_umax >= umin_roi) && (v_vmin <= vmax_roi) && (v_vmax > vmax_roi)) {
409 delta_theta = theta_v_min - theta_u_max;
411 else if ((u_umin >= umin_roi) && (u_umax >= umin_roi) && (v_vmin <= vmax_roi) && (v_vmax <= vmax_roi)) {
414 delta_theta = (theta_v_min - theta_u_max) + (theta_u_min - theta_v_max);
416 else if ((u_umin < umin_roi) && (u_umax < umin_roi) && (v_vmin <= vmax_roi) && (v_vmax <= vmax_roi)) {
420 computeIntersectionsLeftBorder(u_c, umin_roi, radius, delta_theta);
422 else if ((u_umin >= umin_roi) && (u_umax >= umin_roi) && (v_vmin >= vmax_roi) && (v_vmax >= vmax_roi)) {
426 computeIntersBottomBorder(v_c, vmax_roi, radius, delta_theta);
441 void computeIntersectionsBottomRight(
const float &u_c,
const float &v_c,
const float &vmax_roi,
const float &umax_roi,
const float &radius,
444 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
445 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
446 float crossing_u = vmax_roi;
447 float crossing_v = umax_roi;
448 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v,
449 crossing_theta_u_min, crossing_theta_u_max,
450 crossing_theta_v_min, crossing_theta_v_max);
451 float theta_u_min = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
452 float theta_u_max = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
453 float u_umin = crossing_theta_u_min.second;
454 float u_umax = crossing_theta_u_max.second;
455 float v_vmin = crossing_theta_v_min.second;
456 float v_vmax = crossing_theta_v_max.second;
457 if ((u_umin <= umax_roi) && (u_umax > umax_roi) && (v_vmin <= vmax_roi) && (v_vmax > vmax_roi)) {
460 delta_theta = theta_u_min - theta_v_min;
461 if (delta_theta < 0) {
463 delta_theta += 2.f * M_PI_FLOAT;
466 else if ((u_umin <= umax_roi) && (u_umax <= umax_roi) && (v_vmin <= vmax_roi) && (v_vmax <= vmax_roi)) {
469 delta_theta = (2.f * M_PI_FLOAT) - ((theta_v_min - theta_v_max) + (theta_u_max - theta_u_min));
471 else if ((u_umin > umax_roi) && (u_umax > umax_roi) && (v_vmin <= vmax_roi) && (v_vmax <= vmax_roi)) {
475 computeIntersectionsRightBorder(u_c, umax_roi, radius, delta_theta);
477 else if ((u_umin <= umax_roi) && (u_umax <= umax_roi) && (v_vmin > vmax_roi) && (v_vmax > vmax_roi)) {
481 computeIntersBottomBorder(v_c, vmax_roi, radius, delta_theta);
497 void computeIntersTopLeftBottom(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &vmin_roi,
498 const float &vmax_roi,
const float &radius,
float &delta_theta)
501 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
502 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
503 float crossing_u_top = vmin_roi;
504 float crossing_v = umin_roi;
505 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_top, crossing_v,
506 crossing_theta_u_min, crossing_theta_u_max,
507 crossing_theta_v_min, crossing_theta_v_max);
508 float theta_u_min_top = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
509 float theta_u_max_top = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
510 float u_umin_top = crossing_theta_u_min.second;
511 float u_umax_top = crossing_theta_u_max.second;
512 float v_vmin = crossing_theta_v_min.second;
513 float v_vmax = crossing_theta_v_max.second;
516 float crossing_u_bottom = vmax_roi;
517 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_bottom, crossing_v,
518 crossing_theta_u_min, crossing_theta_u_max,
519 crossing_theta_v_min, crossing_theta_v_max);
520 float theta_u_min_bottom = crossing_theta_u_min.first;
521 float theta_u_max_bottom = crossing_theta_u_max.first;
522 float u_umin_bottom = crossing_theta_u_min.second;
523 float u_umax_bottom = crossing_theta_u_max.second;
524 if ((u_umin_top >= umin_roi) && (u_umin_bottom >= umin_roi) && (v_vmin >= vmin_roi) && (v_vmax <= vmax_roi)) {
526 delta_theta = (theta_v_min - theta_u_min_top) + (theta_u_max_top - theta_u_max_bottom) + (theta_u_min_bottom - theta_v_max);
528 else if ((u_umin_top <= umin_roi) && (v_vmin <= vmin_roi) && (u_umin_bottom <= umin_roi) && (v_vmax >= vmax_roi)) {
530 delta_theta = (theta_u_max_top - theta_u_max_bottom);
532 else if ((u_umax_top <= umin_roi) && (u_umax_bottom <= umin_roi) && (v_vmin >= vmin_roi) && (v_vmax <= vmax_roi)) {
534 computeIntersectionsLeftBorder(u_c, umin_roi, radius, delta_theta);
536 else if ((u_umax_bottom > umin_roi) && (v_vmin >= vmin_roi)) {
538 computeIntersectionsBottomLeft(u_c, v_c, umin_roi, vmax_roi, radius, delta_theta);
540 else if ((u_umax_top > umin_roi) && (v_vmax <= vmax_roi)) {
542 computeIntersectionsTopLeft(u_c, v_c, umin_roi, vmin_roi, radius, delta_theta);
558 void computeIntersTopRightBottom(
const float &u_c,
const float &v_c,
const float &umax_roi,
const float &vmin_roi,
const float &vmax_roi,
559 const float &radius,
float &delta_theta)
562 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
563 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
564 float crossing_u_top = vmin_roi;
565 float crossing_v = umax_roi;
566 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_top, crossing_v,
567 crossing_theta_u_min, crossing_theta_u_max,
568 crossing_theta_v_min, crossing_theta_v_max);
569 float theta_u_min_top = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
570 float theta_u_max_top = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
571 float u_umin_top = crossing_theta_u_min.second;
572 float u_umax_top = crossing_theta_u_max.second;
573 float v_vmin = crossing_theta_v_min.second;
574 float v_vmax = crossing_theta_v_max.second;
577 float crossing_u_bottom = vmax_roi;
578 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_bottom, crossing_v,
579 crossing_theta_u_min, crossing_theta_u_max,
580 crossing_theta_v_min, crossing_theta_v_max);
581 float theta_u_min_bottom = crossing_theta_u_min.first;
582 float theta_u_max_bottom = crossing_theta_u_max.first;
583 float u_umin_bottom = crossing_theta_u_min.second;
584 float u_umax_bottom = crossing_theta_u_max.second;
585 bool crossOnceTopHor = (u_umin_top <= umax_roi) && (u_umax_top > umax_roi);
586 bool dontCrossVert = (v_vmin <= vmin_roi) && (v_vmax >= vmax_roi);
587 bool crossOnceBotHor = (u_umin_bottom <= umax_roi) && (u_umax_bottom > umax_roi);
588 if ((u_umax_top <= umax_roi) && (u_umax_bottom <= umax_roi) && (v_vmin >= vmin_roi) && (v_vmax <= vmax_roi)) {
590 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));
592 else if (crossOnceTopHor && crossOnceBotHor && dontCrossVert) {
594 delta_theta = (theta_u_max_top - theta_u_max_bottom);
596 else if ((u_umin_top >= umax_roi) && (u_umin_bottom >= umax_roi) && (v_vmin >= vmin_roi) && (v_vmax <= vmax_roi)) {
598 computeIntersectionsRightBorder(u_c, umax_roi, radius, delta_theta);
600 else if ((u_umin_bottom <= umax_roi) && (v_vmin >= vmin_roi)) {
602 computeIntersectionsBottomRight(u_c, v_c, vmax_roi, umax_roi, radius, delta_theta);
604 else if ((u_umin_top <= umax_roi) && (v_vmax <= vmax_roi)) {
606 computeIntersectionsTopRight(u_c, v_c, vmin_roi, umax_roi, radius, delta_theta);
621 void computeIntersTopBottomOnly(
const float &u_c,
const float &v_c,
const float &vmin_roi,
const float &vmax_roi,
const float &radius,
627 float theta_u_cross_top = std::asin((v_c - vmin_roi) / radius);
629 float theta_u_cross_top_2 = 0.f;
630 if (theta_u_cross_top > 0) {
631 theta_u_cross_top_2 = M_PI_FLOAT - theta_u_cross_top;
634 theta_u_cross_top_2 = -M_PI_FLOAT - theta_u_cross_top;
638 float u_ucross_top = u_c + (radius * std::cos(theta_u_cross_top));
639 float u_ucross_top_2 = u_c + (radius * std::cos(theta_u_cross_top_2));
641 float theta_u_cross_top_min = 0.f, theta_u_cross_top_max = 0.f;
642 if (u_ucross_top < u_ucross_top_2) {
643 theta_u_cross_top_min = theta_u_cross_top;
644 theta_u_cross_top_max = theta_u_cross_top_2;
647 theta_u_cross_top_min = theta_u_cross_top_2;
648 theta_u_cross_top_max = theta_u_cross_top;
654 float theta_u_cross_bottom = std::asin((v_c - vmax_roi) / radius);
656 float theta_u_cross_bottom_2 = 0.f;
657 if (theta_u_cross_bottom > 0) {
658 theta_u_cross_bottom_2 = M_PI_FLOAT - theta_u_cross_bottom;
661 theta_u_cross_bottom_2 = -M_PI_FLOAT - theta_u_cross_bottom;
665 float u_ucross_bottom = u_c + (radius * std::cos(theta_u_cross_bottom));
666 float u_ucross_bottom_2 = u_c + (radius * std::cos(theta_u_cross_bottom_2));
669 float theta_u_cross_bottom_min = 0.f, theta_u_cross_bottom_max = 0.f;
670 if (u_ucross_bottom < u_ucross_bottom_2) {
671 theta_u_cross_bottom_min = theta_u_cross_bottom;
672 theta_u_cross_bottom_max = theta_u_cross_bottom_2;
675 theta_u_cross_bottom_min = theta_u_cross_bottom_2;
676 theta_u_cross_bottom_max = theta_u_cross_bottom;
681 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));
696 void computeIntersLeftRightTop(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &umax_roi,
697 const float &vmin_roi,
const float &radius,
float &delta_theta)
700 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
701 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
702 float crossing_u = vmin_roi;
703 float crossing_v_left = umin_roi;
704 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v_left,
705 crossing_theta_u_min, crossing_theta_u_max,
706 crossing_theta_v_min, crossing_theta_v_max);
707 float theta_u_min = crossing_theta_u_min.first;
708 float theta_u_max = crossing_theta_u_max.first;
709 float u_umin = crossing_theta_u_min.second;
710 float u_umax = crossing_theta_u_max.second;
711 float theta_v_min_left = crossing_theta_v_min.first;
712 float theta_v_max_left = crossing_theta_v_max.first;
713 float v_vmin_left = crossing_theta_v_min.second;
714 float v_vmax_left = crossing_theta_v_max.second;
717 float crossing_v_right = umax_roi;
718 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v_right,
719 crossing_theta_u_min, crossing_theta_u_max,
720 crossing_theta_v_min, crossing_theta_v_max);
721 float theta_v_min_right = crossing_theta_v_min.first;
722 float theta_v_max_right = crossing_theta_v_max.first;
723 float v_vmin_right = crossing_theta_v_min.second;
724 float v_vmax_right = crossing_theta_v_max.second;
726 if ((u_umin >= umin_roi) && (u_umax <= umax_roi) && (v_vmin_left >= vmin_roi) && (v_vmin_right >= vmin_roi)) {
728 delta_theta = (theta_v_min_left - theta_u_min) + (theta_u_max - theta_v_min_right) + (theta_v_max_right - theta_v_max_left);
730 else if ((u_umin <= umin_roi) && (u_umax >= umax_roi) && (v_vmax_left >= vmin_roi) && (v_vmax_right >= vmin_roi)) {
732 delta_theta = (theta_v_max_right - theta_v_max_left);
734 else if ((v_vmax_left <= vmin_roi) && (v_vmax_right <= vmin_roi) && (u_umin >= umin_roi) && (u_umax <= umax_roi)) {
736 computeIntersectionsTopBorder(v_c, vmin_roi, radius, delta_theta);
738 else if ((u_umax >= umin_roi) && (v_vmax_left >= vmin_roi)) {
740 computeIntersectionsTopLeft(u_c, v_c, umin_roi, vmin_roi, radius, delta_theta);
742 else if ((u_umin <= umax_roi) && (v_vmax_right >= vmin_roi)) {
744 computeIntersectionsTopRight(u_c, v_c, vmin_roi, umax_roi, radius, delta_theta);
760 void computeIntersLeftRightBottom(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &umax_roi,
761 const float &vmax_roi,
const float &radius,
float &delta_theta)
764 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
765 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
766 float crossing_u = vmax_roi;
767 float crossing_v_left = umin_roi;
768 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v_left,
769 crossing_theta_u_min, crossing_theta_u_max,
770 crossing_theta_v_min, crossing_theta_v_max);
771 float theta_u_min = crossing_theta_u_min.first;
772 float theta_u_max = crossing_theta_u_max.first;
773 float u_umin = crossing_theta_u_min.second;
774 float u_umax = crossing_theta_u_max.second;
775 float theta_v_min_left = crossing_theta_v_min.first;
776 float theta_v_max_left = crossing_theta_v_max.first;
777 float v_vmin_left = crossing_theta_v_min.second;
781 float crossing_v_right = umax_roi;
782 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v_right,
783 crossing_theta_u_min, crossing_theta_u_max,
784 crossing_theta_v_min, crossing_theta_v_max);
785 float theta_v_min_right = crossing_theta_v_min.first;
786 float theta_v_max_right = crossing_theta_v_max.first;
787 float v_vmin_right = crossing_theta_v_min.second;
790 if ((u_umin >= umin_roi) && (u_umax <= umax_roi) && (v_vmin_left <= vmax_roi) && (v_vmin_right <= vmax_roi)) {
792 delta_theta = (theta_v_min_left - theta_v_min_right) + (theta_v_max_right - theta_u_max) + (theta_u_min - theta_v_max_left);
794 else if ((u_umin <= umin_roi) && (u_umax >= umax_roi) && (v_vmin_left <= vmax_roi) && (v_vmin_right <= vmax_roi)) {
796 delta_theta = (theta_v_min_left - theta_v_min_right);
798 else if ((v_vmin_left >= vmax_roi) && (v_vmin_right >= vmax_roi) && (u_umin >= umin_roi) && (u_umax <= umax_roi)) {
800 computeIntersBottomBorder(v_c, vmax_roi, radius, delta_theta);
802 else if ((u_umax >= umin_roi) && (v_vmin_right >= vmax_roi)) {
804 computeIntersectionsBottomLeft(u_c, v_c, umin_roi, vmax_roi, radius, delta_theta);
806 else if ((u_umin <= umax_roi) && (v_vmin_right <= vmax_roi)) {
808 computeIntersectionsBottomRight(u_c, v_c, vmax_roi, umax_roi, radius, delta_theta);
823 void computeIntersectionsLeftRight(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &umax_roi,
const float &radius,
830 float theta_v_cross_left = std::acos((umin_roi - u_c) / radius);
832 float theta_v_cross_left_2 = -theta_v_cross_left;
835 float v_vcross_left = v_c - (radius * std::sin(theta_v_cross_left));
836 float v_vcross_left_2 = v_c - (radius * std::sin(theta_v_cross_left_2));
838 float theta_v_cross_left_min = 0.f, theta_v_cross_left_max = 0.f;
839 if (v_vcross_left < v_vcross_left_2) {
840 theta_v_cross_left_min = theta_v_cross_left;
841 theta_v_cross_left_max = theta_v_cross_left_2;
844 theta_v_cross_left_min = theta_v_cross_left_2;
845 theta_v_cross_left_max = theta_v_cross_left;
852 float theta_v_cross_right = std::acos((umax_roi - u_c) / radius);
854 float theta_v_cross_right_2 = -theta_v_cross_right;
857 float v_vcross_right = v_c - (radius * std::sin(theta_v_cross_right));
858 float v_vcross_right_2 = v_c - (radius * std::sin(theta_v_cross_right_2));
861 float theta_v_cross_right_min = 0.f, theta_v_cross_right_max = 0.f;
862 if (v_vcross_right < v_vcross_right_2) {
863 theta_v_cross_right_min = theta_v_cross_right;
864 theta_v_cross_right_max = theta_v_cross_right_2;
867 theta_v_cross_right_min = theta_v_cross_right_2;
868 theta_v_cross_right_max = theta_v_cross_right;
873 delta_theta = (theta_v_cross_left_min - theta_v_cross_right_min) + (theta_v_cross_right_max - theta_v_cross_left_max);
890 void computeIntersectionsAllAxes(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &umax_roi,
891 const float &vmin_roi,
const float &vmax_roi,
const float &radius,
float &delta_theta)
894 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
895 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
896 float crossing_u_top = vmin_roi;
897 float crossing_v_left = umin_roi;
898 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_top, crossing_v_left,
899 crossing_theta_u_min, crossing_theta_u_max,
900 crossing_theta_v_min, crossing_theta_v_max);
901 float theta_u_min_top = crossing_theta_u_min.first;
902 float theta_u_max_top = crossing_theta_u_max.first;
903 float theta_v_min_left = crossing_theta_v_min.first;
904 float theta_v_max_left = crossing_theta_v_max.first;
907 float crossing_u_bottom = vmax_roi;
908 float crossing_v_right = umax_roi;
909 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_bottom, crossing_v_right,
910 crossing_theta_u_min, crossing_theta_u_max,
911 crossing_theta_v_min, crossing_theta_v_max);
912 float theta_u_min_bottom = crossing_theta_u_min.first;
913 float theta_u_max_bottom = crossing_theta_u_max.first;
914 float theta_v_min_right = crossing_theta_v_min.first;
915 float theta_v_max_right = crossing_theta_v_max.first;
916 delta_theta = (theta_v_min_left - theta_u_min_top) + (theta_u_max_top - theta_v_min_right);
917 delta_theta += (theta_v_max_right - theta_u_max_bottom) + (theta_u_min_bottom - theta_v_max_left);
922 float delta_theta = 0.f;
924 float u_c =
static_cast<float>(center.
get_u());
925 float v_c =
static_cast<float>(center.
get_v());
926 float radius = m_radius;
927 float roi_w =
static_cast<float>(roi.
getWidth());
928 float roi_h =
static_cast<float>(roi.
getHeight());
930 float umin_roi =
static_cast<float>(topLeft.
get_u());
931 float vmin_roi =
static_cast<float>(topLeft.
get_v());
932 float umax_roi = umin_roi + roi_w;
933 float vmax_roi = vmin_roi + roi_h;
934 bool touchLeftBorder = (u_c - radius) <= umin_roi;
935 bool touchRightBorder = (u_c + radius) >= umax_roi;
936 bool touchTopBorder = (v_c - radius) <= vmin_roi;
937 bool touchBottomBorder = (v_c + radius) >= vmax_roi;
938 bool isHorizontallyOK = ((!touchLeftBorder) && (!touchRightBorder));
939 bool isVerticallyOK = ((!touchTopBorder) && (!touchBottomBorder));
940 if (isHorizontallyOK && isVerticallyOK && roi.
isInside(m_center)) {
944 delta_theta = 2.f * M_PI_FLOAT;
946 else if (touchBottomBorder && (!touchLeftBorder) && (!touchRightBorder) && (!touchTopBorder)) {
948 computeIntersBottomBorder(v_c, vmax_roi, radius, delta_theta);
950 else if ((!touchBottomBorder) && touchLeftBorder && (!touchRightBorder) && (!touchTopBorder)) {
952 computeIntersectionsLeftBorder(u_c, umin_roi, radius, delta_theta);
954 else if ((!touchBottomBorder) && (!touchLeftBorder) && touchRightBorder && (!touchTopBorder)) {
956 computeIntersectionsRightBorder(u_c, umax_roi, radius, delta_theta);
958 else if ((!touchBottomBorder) && (!touchLeftBorder) && (!touchRightBorder) && touchTopBorder) {
960 computeIntersectionsTopBorder(v_c, vmin_roi, radius, delta_theta);
962 else if (touchBottomBorder && touchLeftBorder && (!touchRightBorder) && (!touchTopBorder)) {
964 computeIntersectionsBottomLeft(u_c, v_c, umin_roi, vmax_roi, radius, delta_theta);
966 else if (touchBottomBorder && (!touchLeftBorder) && touchRightBorder && (!touchTopBorder)) {
968 computeIntersectionsBottomRight(u_c, v_c, vmax_roi, umax_roi, radius, delta_theta);
970 else if ((!touchBottomBorder) && touchLeftBorder && (!touchRightBorder) && touchTopBorder) {
972 computeIntersectionsTopLeft(u_c, v_c, umin_roi, vmin_roi, radius, delta_theta);
974 else if ((!touchBottomBorder) && (!touchLeftBorder) && touchRightBorder && touchTopBorder) {
976 computeIntersectionsTopRight(u_c, v_c, vmin_roi, umax_roi, radius, delta_theta);
978 else if (touchBottomBorder && touchTopBorder && touchLeftBorder && (!touchRightBorder)) {
980 computeIntersTopLeftBottom(u_c, v_c, umin_roi, vmin_roi, vmax_roi, radius, delta_theta);
982 else if (touchBottomBorder && touchTopBorder && (!touchLeftBorder) && touchRightBorder) {
984 computeIntersTopRightBottom(u_c, v_c, umax_roi, vmin_roi, vmax_roi, radius, delta_theta);
986 else if (touchBottomBorder && touchTopBorder && (!touchLeftBorder) && (!touchRightBorder)) {
988 computeIntersTopBottomOnly(u_c, v_c, vmin_roi, vmax_roi, radius, delta_theta);
990 else if ((!touchBottomBorder) && touchTopBorder && touchLeftBorder && touchRightBorder) {
992 computeIntersLeftRightTop(u_c, v_c, umin_roi, umax_roi, vmin_roi, radius, delta_theta);
994 else if (touchBottomBorder && (!touchTopBorder) && touchLeftBorder && touchRightBorder) {
996 computeIntersLeftRightBottom(u_c, v_c, umin_roi, umax_roi, vmax_roi, radius, delta_theta);
998 else if (touchLeftBorder && touchRightBorder && (!touchTopBorder) && (!touchBottomBorder)) {
1000 computeIntersectionsLeftRight(u_c, v_c, umin_roi, umax_roi, radius, delta_theta);
1002 else if (touchLeftBorder && touchRightBorder && touchTopBorder && touchBottomBorder) {
1004 computeIntersectionsAllAxes(u_c, v_c, umin_roi, umax_roi, vmin_roi, vmax_roi, radius, delta_theta);
1007 std::cerr <<
"touchLeft = " << (touchLeftBorder ?
"true" :
"false") <<
"\ttouchRight = " << (touchRightBorder ?
"true" :
"false") << std::endl;
1008 std::cerr <<
"touchTop = " << (touchTopBorder ?
"true" :
"false") <<
"\ttouchBottom = " << (touchBottomBorder ?
"true" :
"false") << std::endl;
1009 std::cerr <<
"u_c = " << u_c <<
"\tv_c = " << v_c <<
"\tradius = " << radius << std::endl;
1010 std::cerr <<
"umin_roi = " << umin_roi <<
"\tumax_roi = " << umax_roi << std::endl;
1011 std::cerr <<
"vmin_roi = " << vmin_roi <<
"\tvmax_roi = " << vmax_roi << std::endl << std::flush;
1015 if ((delta_theta < 0) || (delta_theta >(2.f * M_PI_FLOAT))) {
1017 if ((rest < roundingTolerance) && ((delta_theta < -M_PI_FLOAT) || (delta_theta > M_PI_FLOAT))) {
1019 delta_theta = 2.f * M_PI_FLOAT;
1033 return delta_theta * m_radius;
1036 #if (VISP_CXX_STANDARD == VISP_CXX_STANDARD_98)
1040 void incrementIfIsInMask(
const vpImage<bool> &mask,
const int &width,
const int &height,
const int &x,
const int &y,
1041 unsigned int &count)
1043 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
1057 const float xm =
static_cast<float>(m_center.
get_u()), ym =
static_cast<float>(m_center.
get_v());
1058 const float r_float =
static_cast<float>(m_radius);
1062 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
1064 auto incrementIfIsInMask = [](
const vpImage<bool> &mask,
const int &width,
const int &height,
const int &x,
const int &y,
1065 unsigned int &count) {
1066 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
1076 unsigned int count = 0;
1078 const float thetaStop = M_PI_2_FLOAT;
1080 int x1 = 0, x2 = 0, x3 = 0, x4 = 0;
1081 int y1 = 0, y2 = 0, y3 = 0, y4 = 0;
1082 while (theta < thetaStop) {
1083 float cos_theta = std::cos(theta);
1084 float sin_theta = std::sin(theta);
1085 float rcos_pos = r_float * cos_theta;
1086 float rsin_pos = r_float * sin_theta;
1087 x1 =
static_cast<int>(xm + rcos_pos);
1088 y1 =
static_cast<int>(ym + rsin_pos);
1089 x2 =
static_cast<int>(xm - rsin_pos);
1090 y2 =
static_cast<int>(ym + rcos_pos);
1091 x3 =
static_cast<int>(xm - rcos_pos);
1092 y3 =
static_cast<int>(ym - rsin_pos);
1093 x4 =
static_cast<int>(xm + rsin_pos);
1094 y4 =
static_cast<int>(ym - rcos_pos);
1095 incrementIfIsInMask(mask, width, height, x1, y1, count);
1096 incrementIfIsInMask(mask, width, height, x2, y2, count);
1097 incrementIfIsInMask(mask, width, height, x3, y3, count);
1098 incrementIfIsInMask(mask, width, height, x4, y4, count);
1104 float dthetaCosPos = 1.f / (r_float * cos_theta);
1105 float dthetaCosNeg = -1.f / (r_float * cos_theta);
1106 float dthetaSinPos = 1.f / (r_float * sin_theta);
1107 float dthetaSinNeg = -1.f / (r_float * sin_theta);
1108 float dthetaPos = 0.f;
1109 if ((sin_theta < 0.f) && (cos_theta > 0.f)) {
1111 dthetaPos = std::min<float>(dthetaCosPos, dthetaSinNeg);
1113 else if ((sin_theta > 0.f) && (cos_theta < 0.f)) {
1115 dthetaPos = std::min<float>(dthetaCosNeg, dthetaSinPos);
1117 else if ((sin_theta < 0.f) && (cos_theta < 0.f)) {
1119 dthetaPos = std::min<float>(dthetaCosNeg, dthetaSinNeg);
1121 else if ((sin_theta > 0.f) && (cos_theta > 0.f)) {
1123 dthetaPos = std::min<float>(dthetaCosPos, dthetaSinPos);
1127 if (cos_theta > 0.f) {
1128 dthetaPos = dthetaCosNeg;
1131 dthetaPos = dthetaCosPos;
1136 if (sin_theta > 0.f) {
1137 dthetaPos = dthetaSinNeg;
1140 dthetaPos = dthetaSinPos;
1160 vpRect bbox(m_center -
vpImagePoint(m_radius, m_radius), 2 * m_radius, 2 * m_radius);
1166 const int val_4 = 4;
1167 return (m_radius * m_radius) / val_4;
1172 const int val_4 = 4;
1173 return (m_radius * m_radius) / val_4;
error that can be emitted by ViSP classes.
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 ...
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