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,
77 float theta1 = std::acos((umin_roi - u_c) / radius);
79 float theta2 = -1.f * theta1;
80 float theta_min = std::min<float>(theta1, theta2);
81 float theta_max = std::max<float>(theta1, theta2);
82 delta_theta = theta_max - theta_min;
83 if ((u_c < umin_roi) && (std::abs(delta_theta - (2 * M_PI_FLOAT)) < (2.f * std::numeric_limits<float>::epsilon()))) {
97 void computeIntersectionsRightBorder(
const float &u_c,
const float &umax_roi,
const float &radius,
102 float theta1 = std::acos((umax_roi - u_c) / radius);
104 float theta2 = -1.f * theta1;
105 float theta_min = std::min<float>(theta1, theta2);
106 float theta_max = std::max<float>(theta1, theta2);
107 delta_theta = (2.f * M_PI_FLOAT) - (theta_max - theta_min);
108 if ((u_c > umax_roi) && (std::abs(delta_theta - (2 * M_PI_FLOAT)) < (2.f * std::numeric_limits<float>::epsilon()))) {
122 void computeIntersectionsTopBorder(
const float &v_c,
const float &vmin_roi,
const float &radius,
127 float theta1 = std::asin((v_c - vmin_roi) / radius);
132 theta2 = M_PI_FLOAT - theta1;
135 theta2 = -theta1 - M_PI_FLOAT;
137 float theta_min = std::min<float>(theta1, theta2);
138 float theta_max = std::max<float>(theta1, theta2);
139 if ((std::abs(theta_max - theta_min) * radius) < 1.f) {
142 delta_theta = 2.f * M_PI_FLOAT;
144 else if (theta1 > 0.f) {
145 delta_theta = (2.f * M_PI_FLOAT) - (theta_max - theta_min);
148 delta_theta = theta_max - theta_min;
150 if ((v_c < vmin_roi) && (std::abs(delta_theta - (2 * M_PI_FLOAT)) < (2.f * std::numeric_limits<float>::epsilon()))) {
164 void computeIntersBottomBorder(
const float &v_c,
const float &vmax_roi,
const float &radius,
169 float theta1 = std::asin((v_c - vmax_roi) / radius);
174 theta2 = M_PI_FLOAT - theta1;
177 theta2 = -theta1 - M_PI_FLOAT;
179 float theta_min = std::min<float>(theta1, theta2);
180 float theta_max = std::max<float>(theta1, theta2);
181 if ((std::abs(theta_max - theta_min) * radius) < 1.f) {
184 delta_theta = 2.f * M_PI_FLOAT;
186 else if (theta1 > 0.f) {
187 delta_theta = theta_max - theta_min;
190 delta_theta = (2.f * M_PI_FLOAT) - (theta_max - theta_min);
192 if ((v_c > vmax_roi) && (std::abs(delta_theta - (2 * M_PI_FLOAT)) < (2.f * std::numeric_limits<float>::epsilon()))) {
211 void computePerpendicularAxesInters(
const float &u_c,
const float &v_c,
const float &radius,
212 const float &crossing_u,
const float &crossing_v,
213 std::pair<float, float> &theta_u_cross_min, std::pair<float, float> &theta_u_cross_max,
214 std::pair<float, float> &theta_v_cross_min, std::pair<float, float> &theta_v_cross_max)
219 float theta_u_cross = std::asin((v_c - crossing_u) / radius);
221 float theta_u_cross_2 = 0.f;
222 if (theta_u_cross > 0) {
223 theta_u_cross_2 = M_PI_FLOAT - theta_u_cross;
226 theta_u_cross_2 = -M_PI_FLOAT - theta_u_cross;
229 float u_ucross = u_c + (radius * std::cos(theta_u_cross));
230 float u_ucross2 = u_c + (radius * std::cos(theta_u_cross_2));
232 if (u_ucross < u_ucross2) {
233 theta_u_cross_min.first = theta_u_cross;
234 theta_u_cross_min.second = u_ucross;
235 theta_u_cross_max.first = theta_u_cross_2;
236 theta_u_cross_max.second = u_ucross2;
239 theta_u_cross_min.first = theta_u_cross_2;
240 theta_u_cross_min.second = u_ucross2;
241 theta_u_cross_max.first = theta_u_cross;
242 theta_u_cross_max.second = u_ucross;
248 float theta_v_cross = std::acos((crossing_v - u_c) / radius);
250 float theta_v_cross_2 = -theta_v_cross;
253 float v_vcross = v_c - (radius * std::sin(theta_v_cross));
254 float v_vcross2 = v_c - (radius * std::sin(theta_v_cross_2));
256 if (v_vcross < v_vcross2) {
257 theta_v_cross_min.first = theta_v_cross;
258 theta_v_cross_min.second = v_vcross;
259 theta_v_cross_max.first = theta_v_cross_2;
260 theta_v_cross_max.second = v_vcross2;
263 theta_v_cross_min.first = theta_v_cross_2;
264 theta_v_cross_min.second = v_vcross2;
265 theta_v_cross_max.first = theta_v_cross;
266 theta_v_cross_max.second = v_vcross;
281 void computeIntersectionsTopLeft(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &vmin_roi,
const float &radius,
284 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
285 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
286 float crossing_u = vmin_roi;
287 float crossing_v = umin_roi;
288 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v,
289 crossing_theta_u_min, crossing_theta_u_max,
290 crossing_theta_v_min, crossing_theta_v_max);
291 float theta_u_min = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
292 float theta_u_max = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
293 float u_umin = crossing_theta_u_min.second;
294 float u_umax = crossing_theta_u_max.second;
295 float v_vmin = crossing_theta_v_min.second;
296 float v_vmax = crossing_theta_v_max.second;
297 if ((u_umin < umin_roi) && (u_umax >= umin_roi) && (v_vmin < vmin_roi) && (v_vmax >= vmin_roi)) {
300 delta_theta = theta_u_max - theta_v_max;
302 else if ((u_umin >= umin_roi) && (u_umax >= umin_roi) && (v_vmin >= vmin_roi) && (v_vmax >= vmin_roi)) {
305 delta_theta = (theta_v_min - theta_u_min) + (theta_u_max - theta_v_max);
307 else if ((u_umin < umin_roi) && (u_umax < umin_roi) && (v_vmin >= vmin_roi) && (v_vmax >= vmin_roi)) {
311 computeIntersectionsLeftBorder(u_c, umin_roi, radius, delta_theta);
313 else if ((u_umin >= umin_roi) && (u_umax >= umin_roi) && (v_vmin <= vmin_roi) && (v_vmax <= vmin_roi)) {
317 computeIntersectionsTopBorder(v_c, vmin_roi, radius, delta_theta);
332 void computeIntersectionsTopRight(
const float &u_c,
const float &v_c,
const float &vmin_roi,
const float &umax_roi,
const float &radius,
335 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
336 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
337 computePerpendicularAxesInters(u_c, v_c, radius, vmin_roi, umax_roi,
338 crossing_theta_u_min, crossing_theta_u_max,
339 crossing_theta_v_min, crossing_theta_v_max);
340 float theta_u_min = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
341 float theta_u_max = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
342 float u_umin = crossing_theta_u_min.second;
343 float u_umax = crossing_theta_u_max.second;
344 float v_vmin = crossing_theta_v_min.second;
345 float v_vmax = crossing_theta_v_max.second;
346 if ((u_umin <= umax_roi) && (v_vmin < vmin_roi) && (u_umax >= umax_roi) && (v_vmax >= vmin_roi)) {
349 delta_theta = theta_v_max - theta_u_min;
350 if (delta_theta < 0) {
352 delta_theta += 2.f * M_PI_FLOAT;
355 else if ((u_umin <= umax_roi) && (v_vmin >= vmin_roi) && (u_umax <= umax_roi) && (v_vmax >= vmin_roi)) {
358 delta_theta = (2 * M_PI_FLOAT) - ((theta_u_min - theta_u_max) + (theta_v_min - theta_v_max));
360 else if ((u_umin >= umax_roi) && (v_vmin >= vmin_roi) && (u_umax >= umax_roi) && (v_vmax >= vmin_roi)) {
364 computeIntersectionsRightBorder(u_c, umax_roi, radius, delta_theta);
366 else if ((u_umin <= umax_roi) && (v_vmin <= vmin_roi) && (u_umax <= umax_roi) && (v_vmax <= vmin_roi)) {
370 computeIntersectionsTopBorder(v_c, vmin_roi, radius, delta_theta);
385 void computeIntersectionsBottomLeft(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &vmax_roi,
const float &radius,
388 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
389 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
390 float crossing_u = vmax_roi;
391 float crossing_v = umin_roi;
392 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v,
393 crossing_theta_u_min, crossing_theta_u_max,
394 crossing_theta_v_min, crossing_theta_v_max);
395 float theta_u_min = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
396 float theta_u_max = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
397 float u_umin = crossing_theta_u_min.second;
398 float u_umax = crossing_theta_u_max.second;
399 float v_vmin = crossing_theta_v_min.second;
400 float v_vmax = crossing_theta_v_max.second;
401 if ((u_umin < umin_roi) && (u_umax >= umin_roi) && (v_vmin <= vmax_roi) && (v_vmax > vmax_roi)) {
404 delta_theta = theta_v_min - theta_u_max;
406 else 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) + (theta_u_min - theta_v_max);
411 else if ((u_umin < umin_roi) && (u_umax < umin_roi) && (v_vmin <= vmax_roi) && (v_vmax <= vmax_roi)) {
415 computeIntersectionsLeftBorder(u_c, umin_roi, radius, delta_theta);
417 else if ((u_umin >= umin_roi) && (u_umax >= umin_roi) && (v_vmin >= vmax_roi) && (v_vmax >= vmax_roi)) {
421 computeIntersBottomBorder(v_c, vmax_roi, radius, delta_theta);
436 void computeIntersectionsBottomRight(
const float &u_c,
const float &v_c,
const float &vmax_roi,
const float &umax_roi,
const float &radius,
439 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
440 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
441 float crossing_u = vmax_roi;
442 float crossing_v = umax_roi;
443 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v,
444 crossing_theta_u_min, crossing_theta_u_max,
445 crossing_theta_v_min, crossing_theta_v_max);
446 float theta_u_min = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
447 float theta_u_max = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
448 float u_umin = crossing_theta_u_min.second;
449 float u_umax = crossing_theta_u_max.second;
450 float v_vmin = crossing_theta_v_min.second;
451 float v_vmax = crossing_theta_v_max.second;
452 if ((u_umin <= umax_roi) && (u_umax > umax_roi) && (v_vmin <= vmax_roi) && (v_vmax > vmax_roi)) {
455 delta_theta = theta_u_min - theta_v_min;
456 if (delta_theta < 0) {
458 delta_theta += 2.f * M_PI_FLOAT;
461 else if ((u_umin <= umax_roi) && (u_umax <= umax_roi) && (v_vmin <= vmax_roi) && (v_vmax <= vmax_roi)) {
464 delta_theta = (2.f * M_PI_FLOAT) - ((theta_v_min - theta_v_max) + (theta_u_max - theta_u_min));
466 else if ((u_umin > umax_roi) && (u_umax > umax_roi) && (v_vmin <= vmax_roi) && (v_vmax <= vmax_roi)) {
470 computeIntersectionsRightBorder(u_c, umax_roi, radius, delta_theta);
472 else if ((u_umin <= umax_roi) && (u_umax <= umax_roi) && (v_vmin > vmax_roi) && (v_vmax > vmax_roi)) {
476 computeIntersBottomBorder(v_c, vmax_roi, radius, delta_theta);
492 void computeIntersTopLeftBottom(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &vmin_roi,
493 const float &vmax_roi,
const float &radius,
float &delta_theta)
496 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
497 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
498 float crossing_u_top = vmin_roi;
499 float crossing_v = umin_roi;
500 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_top, crossing_v,
501 crossing_theta_u_min, crossing_theta_u_max,
502 crossing_theta_v_min, crossing_theta_v_max);
503 float theta_u_min_top = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
504 float theta_u_max_top = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
505 float u_umin_top = crossing_theta_u_min.second;
506 float u_umax_top = crossing_theta_u_max.second;
507 float v_vmin = crossing_theta_v_min.second;
508 float v_vmax = crossing_theta_v_max.second;
511 float crossing_u_bottom = vmax_roi;
512 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_bottom, crossing_v,
513 crossing_theta_u_min, crossing_theta_u_max,
514 crossing_theta_v_min, crossing_theta_v_max);
515 float theta_u_min_bottom = crossing_theta_u_min.first;
516 float theta_u_max_bottom = crossing_theta_u_max.first;
517 float u_umin_bottom = crossing_theta_u_min.second;
518 float u_umax_bottom = crossing_theta_u_max.second;
519 if ((u_umin_top >= umin_roi) && (u_umin_bottom >= umin_roi) && (v_vmin >= vmin_roi) && (v_vmax <= vmax_roi)) {
521 delta_theta = (theta_v_min - theta_u_min_top) + (theta_u_max_top - theta_u_max_bottom) + (theta_u_min_bottom - theta_v_max);
523 else if ((u_umin_top <= umin_roi) && (v_vmin <= vmin_roi) && (u_umin_bottom <= umin_roi) && (v_vmax >= vmax_roi)) {
525 delta_theta = (theta_u_max_top - theta_u_max_bottom);
527 else if ((u_umax_top <= umin_roi) && (u_umax_bottom <= umin_roi) && (v_vmin >= vmin_roi) && (v_vmax <= vmax_roi)) {
529 computeIntersectionsLeftBorder(u_c, umin_roi, radius, delta_theta);
531 else if ((u_umax_bottom > umin_roi) && (v_vmin >= vmin_roi)) {
533 computeIntersectionsBottomLeft(u_c, v_c, umin_roi, vmax_roi, radius, delta_theta);
535 else if ((u_umax_top > umin_roi) && (v_vmax <= vmax_roi)) {
537 computeIntersectionsTopLeft(u_c, v_c, umin_roi, vmin_roi, radius, delta_theta);
553 void computeIntersTopRightBottom(
const float &u_c,
const float &v_c,
const float &umax_roi,
const float &vmin_roi,
const float &vmax_roi,
554 const float &radius,
float &delta_theta)
557 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
558 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
559 float crossing_u_top = vmin_roi;
560 float crossing_v = umax_roi;
561 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_top, crossing_v,
562 crossing_theta_u_min, crossing_theta_u_max,
563 crossing_theta_v_min, crossing_theta_v_max);
564 float theta_u_min_top = crossing_theta_u_min.first, theta_v_min = crossing_theta_v_min.first;
565 float theta_u_max_top = crossing_theta_u_max.first, theta_v_max = crossing_theta_v_max.first;
566 float u_umin_top = crossing_theta_u_min.second;
567 float u_umax_top = crossing_theta_u_max.second;
568 float v_vmin = crossing_theta_v_min.second;
569 float v_vmax = crossing_theta_v_max.second;
572 float crossing_u_bottom = vmax_roi;
573 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_bottom, crossing_v,
574 crossing_theta_u_min, crossing_theta_u_max,
575 crossing_theta_v_min, crossing_theta_v_max);
576 float theta_u_min_bottom = crossing_theta_u_min.first;
577 float theta_u_max_bottom = crossing_theta_u_max.first;
578 float u_umin_bottom = crossing_theta_u_min.second;
579 float u_umax_bottom = crossing_theta_u_max.second;
580 bool crossOnceTopHor = (u_umin_top <= umax_roi) && (u_umax_top > umax_roi);
581 bool dontCrossVert = (v_vmin <= vmin_roi) && (v_vmax >= vmax_roi);
582 bool crossOnceBotHor = (u_umin_bottom <= umax_roi) && (u_umax_bottom > umax_roi);
583 if ((u_umax_top <= umax_roi) && (u_umax_bottom <= umax_roi) && (v_vmin >= vmin_roi) && (v_vmax <= vmax_roi)) {
585 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));
587 else if (crossOnceTopHor && crossOnceBotHor && dontCrossVert) {
589 delta_theta = (theta_u_max_top - theta_u_max_bottom);
591 else if ((u_umin_top >= umax_roi) && (u_umin_bottom >= umax_roi) && (v_vmin >= vmin_roi) && (v_vmax <= vmax_roi)) {
593 computeIntersectionsRightBorder(u_c, umax_roi, radius, delta_theta);
595 else if ((u_umin_bottom <= umax_roi) && (v_vmin >= vmin_roi)) {
597 computeIntersectionsBottomRight(u_c, v_c, vmax_roi, umax_roi, radius, delta_theta);
599 else if ((u_umin_top <= umax_roi) && (v_vmax <= vmax_roi)) {
601 computeIntersectionsTopRight(u_c, v_c, vmin_roi, umax_roi, radius, delta_theta);
616 void computeIntersTopBottomOnly(
const float &u_c,
const float &v_c,
const float &vmin_roi,
const float &vmax_roi,
const float &radius,
622 float theta_u_cross_top = std::asin((v_c - vmin_roi) / radius);
624 float theta_u_cross_top_2 = 0.f;
625 if (theta_u_cross_top > 0) {
626 theta_u_cross_top_2 = M_PI_FLOAT - theta_u_cross_top;
629 theta_u_cross_top_2 = -M_PI_FLOAT - theta_u_cross_top;
633 float u_ucross_top = u_c + (radius * std::cos(theta_u_cross_top));
634 float u_ucross_top_2 = u_c + (radius * std::cos(theta_u_cross_top_2));
636 float theta_u_cross_top_min = 0.f, theta_u_cross_top_max = 0.f;
637 if (u_ucross_top < u_ucross_top_2) {
638 theta_u_cross_top_min = theta_u_cross_top;
639 theta_u_cross_top_max = theta_u_cross_top_2;
642 theta_u_cross_top_min = theta_u_cross_top_2;
643 theta_u_cross_top_max = theta_u_cross_top;
649 float theta_u_cross_bottom = std::asin((v_c - vmax_roi) / radius);
651 float theta_u_cross_bottom_2 = 0.f;
652 if (theta_u_cross_bottom > 0) {
653 theta_u_cross_bottom_2 = M_PI_FLOAT - theta_u_cross_bottom;
656 theta_u_cross_bottom_2 = -M_PI_FLOAT - theta_u_cross_bottom;
660 float u_ucross_bottom = u_c + (radius * std::cos(theta_u_cross_bottom));
661 float u_ucross_bottom_2 = u_c + (radius * std::cos(theta_u_cross_bottom_2));
664 float theta_u_cross_bottom_min = 0.f, theta_u_cross_bottom_max = 0.f;
665 if (u_ucross_bottom < u_ucross_bottom_2) {
666 theta_u_cross_bottom_min = theta_u_cross_bottom;
667 theta_u_cross_bottom_max = theta_u_cross_bottom_2;
670 theta_u_cross_bottom_min = theta_u_cross_bottom_2;
671 theta_u_cross_bottom_max = theta_u_cross_bottom;
676 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));
691 void computeIntersLeftRightTop(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &umax_roi,
692 const float &vmin_roi,
const float &radius,
float &delta_theta)
695 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
696 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
697 float crossing_u = vmin_roi;
698 float crossing_v_left = umin_roi;
699 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v_left,
700 crossing_theta_u_min, crossing_theta_u_max,
701 crossing_theta_v_min, crossing_theta_v_max);
702 float theta_u_min = crossing_theta_u_min.first;
703 float theta_u_max = crossing_theta_u_max.first;
704 float u_umin = crossing_theta_u_min.second;
705 float u_umax = crossing_theta_u_max.second;
706 float theta_v_min_left = crossing_theta_v_min.first;
707 float theta_v_max_left = crossing_theta_v_max.first;
708 float v_vmin_left = crossing_theta_v_min.second;
709 float v_vmax_left = crossing_theta_v_max.second;
712 float crossing_v_right = umax_roi;
713 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v_right,
714 crossing_theta_u_min, crossing_theta_u_max,
715 crossing_theta_v_min, crossing_theta_v_max);
716 float theta_v_min_right = crossing_theta_v_min.first;
717 float theta_v_max_right = crossing_theta_v_max.first;
718 float v_vmin_right = crossing_theta_v_min.second;
719 float v_vmax_right = crossing_theta_v_max.second;
721 if ((u_umin >= umin_roi) && (u_umax <= umax_roi) && (v_vmin_left >= vmin_roi) && (v_vmin_right >= vmin_roi)) {
723 delta_theta = (theta_v_min_left - theta_u_min) + (theta_u_max - theta_v_min_right) + (theta_v_max_right - theta_v_max_left);
725 else if ((u_umin <= umin_roi) && (u_umax >= umax_roi) && (v_vmax_left >= vmin_roi) && (v_vmax_right >= vmin_roi)) {
727 delta_theta = (theta_v_max_right - theta_v_max_left);
729 else if ((v_vmax_left <= vmin_roi) && (v_vmax_right <= vmin_roi) && (u_umin >= umin_roi) && (u_umax <= umax_roi)) {
731 computeIntersectionsTopBorder(v_c, vmin_roi, radius, delta_theta);
733 else if ((u_umax >= umin_roi) && (v_vmax_left >= vmin_roi)) {
735 computeIntersectionsTopLeft(u_c, v_c, umin_roi, vmin_roi, radius, delta_theta);
737 else if ((u_umin <= umax_roi) && (v_vmax_right >= vmin_roi)) {
739 computeIntersectionsTopRight(u_c, v_c, vmin_roi, umax_roi, radius, delta_theta);
755 void computeIntersLeftRightBottom(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &umax_roi,
756 const float &vmax_roi,
const float &radius,
float &delta_theta)
759 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
760 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
761 float crossing_u = vmax_roi;
762 float crossing_v_left = umin_roi;
763 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v_left,
764 crossing_theta_u_min, crossing_theta_u_max,
765 crossing_theta_v_min, crossing_theta_v_max);
766 float theta_u_min = crossing_theta_u_min.first;
767 float theta_u_max = crossing_theta_u_max.first;
768 float u_umin = crossing_theta_u_min.second;
769 float u_umax = crossing_theta_u_max.second;
770 float theta_v_min_left = crossing_theta_v_min.first;
771 float theta_v_max_left = crossing_theta_v_max.first;
772 float v_vmin_left = crossing_theta_v_min.second;
776 float crossing_v_right = umax_roi;
777 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u, crossing_v_right,
778 crossing_theta_u_min, crossing_theta_u_max,
779 crossing_theta_v_min, crossing_theta_v_max);
780 float theta_v_min_right = crossing_theta_v_min.first;
781 float theta_v_max_right = crossing_theta_v_max.first;
782 float v_vmin_right = crossing_theta_v_min.second;
785 if ((u_umin >= umin_roi) && (u_umax <= umax_roi) && (v_vmin_left <= vmax_roi) && (v_vmin_right <= vmax_roi)) {
787 delta_theta = (theta_v_min_left - theta_v_min_right) + (theta_v_max_right - theta_u_max) + (theta_u_min - theta_v_max_left);
789 else if ((u_umin <= umin_roi) && (u_umax >= umax_roi) && (v_vmin_left <= vmax_roi) && (v_vmin_right <= vmax_roi)) {
791 delta_theta = (theta_v_min_left - theta_v_min_right);
793 else if ((v_vmin_left >= vmax_roi) && (v_vmin_right >= vmax_roi) && (u_umin >= umin_roi) && (u_umax <= umax_roi)) {
795 computeIntersBottomBorder(v_c, vmax_roi, radius, delta_theta);
797 else if ((u_umax >= umin_roi) && (v_vmin_right >= vmax_roi)) {
799 computeIntersectionsBottomLeft(u_c, v_c, umin_roi, vmax_roi, radius, delta_theta);
801 else if ((u_umin <= umax_roi) && (v_vmin_right <= vmax_roi)) {
803 computeIntersectionsBottomRight(u_c, v_c, vmax_roi, umax_roi, radius, delta_theta);
818 void computeIntersectionsLeftRight(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &umax_roi,
const float &radius,
825 float theta_v_cross_left = std::acos((umin_roi - u_c) / radius);
827 float theta_v_cross_left_2 = -theta_v_cross_left;
830 float v_vcross_left = v_c - (radius * std::sin(theta_v_cross_left));
831 float v_vcross_left_2 = v_c - (radius * std::sin(theta_v_cross_left_2));
833 float theta_v_cross_left_min = 0.f, theta_v_cross_left_max = 0.f;
834 if (v_vcross_left < v_vcross_left_2) {
835 theta_v_cross_left_min = theta_v_cross_left;
836 theta_v_cross_left_max = theta_v_cross_left_2;
839 theta_v_cross_left_min = theta_v_cross_left_2;
840 theta_v_cross_left_max = theta_v_cross_left;
847 float theta_v_cross_right = std::acos((umax_roi - u_c) / radius);
849 float theta_v_cross_right_2 = -theta_v_cross_right;
852 float v_vcross_right = v_c - (radius * std::sin(theta_v_cross_right));
853 float v_vcross_right_2 = v_c - (radius * std::sin(theta_v_cross_right_2));
856 float theta_v_cross_right_min = 0.f, theta_v_cross_right_max = 0.f;
857 if (v_vcross_right < v_vcross_right_2) {
858 theta_v_cross_right_min = theta_v_cross_right;
859 theta_v_cross_right_max = theta_v_cross_right_2;
862 theta_v_cross_right_min = theta_v_cross_right_2;
863 theta_v_cross_right_max = theta_v_cross_right;
868 delta_theta = (theta_v_cross_left_min - theta_v_cross_right_min) + (theta_v_cross_right_max - theta_v_cross_left_max);
885 void computeIntersectionsAllAxes(
const float &u_c,
const float &v_c,
const float &umin_roi,
const float &umax_roi,
886 const float &vmin_roi,
const float &vmax_roi,
const float &radius,
float &delta_theta)
889 std::pair<float, float> crossing_theta_u_min, crossing_theta_u_max;
890 std::pair<float, float> crossing_theta_v_min, crossing_theta_v_max;
891 float crossing_u_top = vmin_roi;
892 float crossing_v_left = umin_roi;
893 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_top, crossing_v_left,
894 crossing_theta_u_min, crossing_theta_u_max,
895 crossing_theta_v_min, crossing_theta_v_max);
896 float theta_u_min_top = crossing_theta_u_min.first;
897 float theta_u_max_top = crossing_theta_u_max.first;
898 float theta_v_min_left = crossing_theta_v_min.first;
899 float theta_v_max_left = crossing_theta_v_max.first;
902 float crossing_u_bottom = vmax_roi;
903 float crossing_v_right = umax_roi;
904 computePerpendicularAxesInters(u_c, v_c, radius, crossing_u_bottom, crossing_v_right,
905 crossing_theta_u_min, crossing_theta_u_max,
906 crossing_theta_v_min, crossing_theta_v_max);
907 float theta_u_min_bottom = crossing_theta_u_min.first;
908 float theta_u_max_bottom = crossing_theta_u_max.first;
909 float theta_v_min_right = crossing_theta_v_min.first;
910 float theta_v_max_right = crossing_theta_v_max.first;
911 delta_theta = (theta_v_min_left - theta_u_min_top) + (theta_u_max_top - theta_v_min_right);
912 delta_theta += (theta_v_max_right - theta_u_max_bottom) + (theta_u_min_bottom - theta_v_max_left);
917 float delta_theta = 0.f;
919 float u_c =
static_cast<float>(center.
get_u());
920 float v_c =
static_cast<float>(center.
get_v());
921 float radius = m_radius;
922 float roi_w =
static_cast<float>(roi.
getWidth());
923 float roi_h =
static_cast<float>(roi.
getHeight());
925 float umin_roi =
static_cast<float>(topLeft.
get_u());
926 float vmin_roi =
static_cast<float>(topLeft.
get_v());
927 float umax_roi = umin_roi + roi_w;
928 float vmax_roi = vmin_roi + roi_h;
929 bool touchLeftBorder = (u_c - radius) <= umin_roi;
930 bool touchRightBorder = (u_c + radius) >= umax_roi;
931 bool touchTopBorder = (v_c - radius) <= vmin_roi;
932 bool touchBottomBorder = (v_c + radius) >= vmax_roi;
933 bool isHorizontallyOK = ((!touchLeftBorder) && (!touchRightBorder));
934 bool isVerticallyOK = ((!touchTopBorder) && (!touchBottomBorder));
935 if (isHorizontallyOK && isVerticallyOK && roi.
isInside(m_center)) {
939 delta_theta = 2.f * M_PI_FLOAT;
941 else if (touchBottomBorder && (!touchLeftBorder) && (!touchRightBorder) && (!touchTopBorder)) {
943 computeIntersBottomBorder(v_c, vmax_roi, radius, delta_theta);
945 else if ((!touchBottomBorder) && touchLeftBorder && (!touchRightBorder) && (!touchTopBorder)) {
947 computeIntersectionsLeftBorder(u_c, umin_roi, radius, delta_theta);
949 else if ((!touchBottomBorder) && (!touchLeftBorder) && touchRightBorder && (!touchTopBorder)) {
951 computeIntersectionsRightBorder(u_c, umax_roi, radius, delta_theta);
953 else if ((!touchBottomBorder) && (!touchLeftBorder) && (!touchRightBorder) && touchTopBorder) {
955 computeIntersectionsTopBorder(v_c, vmin_roi, radius, delta_theta);
957 else if (touchBottomBorder && touchLeftBorder && (!touchRightBorder) && (!touchTopBorder)) {
959 computeIntersectionsBottomLeft(u_c, v_c, umin_roi, vmax_roi, radius, delta_theta);
961 else if (touchBottomBorder && (!touchLeftBorder) && touchRightBorder && (!touchTopBorder)) {
963 computeIntersectionsBottomRight(u_c, v_c, vmax_roi, umax_roi, radius, delta_theta);
965 else if ((!touchBottomBorder) && touchLeftBorder && (!touchRightBorder) && touchTopBorder) {
967 computeIntersectionsTopLeft(u_c, v_c, umin_roi, vmin_roi, radius, delta_theta);
969 else if ((!touchBottomBorder) && (!touchLeftBorder) && touchRightBorder && touchTopBorder) {
971 computeIntersectionsTopRight(u_c, v_c, vmin_roi, umax_roi, radius, delta_theta);
973 else if (touchBottomBorder && touchTopBorder && touchLeftBorder && (!touchRightBorder)) {
975 computeIntersTopLeftBottom(u_c, v_c, umin_roi, vmin_roi, vmax_roi, radius, delta_theta);
977 else if (touchBottomBorder && touchTopBorder && (!touchLeftBorder) && touchRightBorder) {
979 computeIntersTopRightBottom(u_c, v_c, umax_roi, vmin_roi, vmax_roi, radius, delta_theta);
981 else if (touchBottomBorder && touchTopBorder && (!touchLeftBorder) && (!touchRightBorder)) {
983 computeIntersTopBottomOnly(u_c, v_c, vmin_roi, vmax_roi, radius, delta_theta);
985 else if ((!touchBottomBorder) && touchTopBorder && touchLeftBorder && touchRightBorder) {
987 computeIntersLeftRightTop(u_c, v_c, umin_roi, umax_roi, vmin_roi, radius, delta_theta);
989 else if (touchBottomBorder && (!touchTopBorder) && touchLeftBorder && touchRightBorder) {
991 computeIntersLeftRightBottom(u_c, v_c, umin_roi, umax_roi, vmax_roi, radius, delta_theta);
993 else if (touchLeftBorder && touchRightBorder && (!touchTopBorder) && (!touchBottomBorder)) {
995 computeIntersectionsLeftRight(u_c, v_c, umin_roi, umax_roi, radius, delta_theta);
997 else if (touchLeftBorder && touchRightBorder && touchTopBorder && touchBottomBorder) {
999 computeIntersectionsAllAxes(u_c, v_c, umin_roi, umax_roi, vmin_roi, vmax_roi, radius, delta_theta);
1002 std::cerr <<
"touchLeft = " << (touchLeftBorder ?
"true" :
"false") <<
"\ttouchRight = " << (touchRightBorder ?
"true" :
"false") << std::endl;
1003 std::cerr <<
"touchTop = " << (touchTopBorder ?
"true" :
"false") <<
"\ttouchBottom = " << (touchBottomBorder ?
"true" :
"false") << std::endl;
1004 std::cerr <<
"u_c = " << u_c <<
"\tv_c = " << v_c <<
"\tradius = " << radius << std::endl;
1005 std::cerr <<
"umin_roi = " << umin_roi <<
"\tumax_roi = " << umax_roi << std::endl;
1006 std::cerr <<
"vmin_roi = " << vmin_roi <<
"\tvmax_roi = " << vmax_roi << std::endl << std::flush;
1010 if ((delta_theta < 0) || (delta_theta >(2.f * M_PI_FLOAT))) {
1012 if ((rest < roundingTolerance) && ((delta_theta < -M_PI_FLOAT) || (delta_theta > M_PI_FLOAT))) {
1014 delta_theta = 2.f * M_PI_FLOAT;
1028 return delta_theta * m_radius;
1031 #if (VISP_CXX_STANDARD == VISP_CXX_STANDARD_98)
1035 void incrementIfIsInMask(
const vpImage<bool> &mask,
const int &width,
const int &height,
const int &x,
const int &y,
1036 unsigned int &count)
1038 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
1052 const float xm =
static_cast<float>(m_center.
get_u()), ym =
static_cast<float>(m_center.
get_v());
1053 const float r_float =
static_cast<float>(m_radius);
1057 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
1059 auto incrementIfIsInMask = [](
const vpImage<bool> &mask,
const int &width,
const int &height,
const int &x,
const int &y,
1060 unsigned int &count) {
1061 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
1071 unsigned int count = 0;
1073 const float thetaStop = M_PI_2_FLOAT;
1075 int x1 = 0, x2 = 0, x3 = 0, x4 = 0;
1076 int y1 = 0, y2 = 0, y3 = 0, y4 = 0;
1077 while (theta < thetaStop) {
1078 float cos_theta = std::cos(theta);
1079 float sin_theta = std::sin(theta);
1080 float rcos_pos = r_float * cos_theta;
1081 float rsin_pos = r_float * sin_theta;
1082 x1 =
static_cast<int>(xm + rcos_pos);
1083 y1 =
static_cast<int>(ym + rsin_pos);
1084 x2 =
static_cast<int>(xm - rsin_pos);
1085 y2 =
static_cast<int>(ym + rcos_pos);
1086 x3 =
static_cast<int>(xm - rcos_pos);
1087 y3 =
static_cast<int>(ym - rsin_pos);
1088 x4 =
static_cast<int>(xm + rsin_pos);
1089 y4 =
static_cast<int>(ym - rcos_pos);
1090 incrementIfIsInMask(mask, width, height, x1, y1, count);
1091 incrementIfIsInMask(mask, width, height, x2, y2, count);
1092 incrementIfIsInMask(mask, width, height, x3, y3, count);
1093 incrementIfIsInMask(mask, width, height, x4, y4, count);
1099 float dthetaCosPos = 1.f / (r_float * cos_theta);
1100 float dthetaCosNeg = -1.f / (r_float * cos_theta);
1101 float dthetaSinPos = 1.f / (r_float * sin_theta);
1102 float dthetaSinNeg = -1.f / (r_float * sin_theta);
1103 float dthetaPos = 0.f;
1104 if ((sin_theta < 0.f) && (cos_theta > 0.f)) {
1106 dthetaPos = std::min<float>(dthetaCosPos, dthetaSinNeg);
1108 else if ((sin_theta > 0.f) && (cos_theta < 0.f)) {
1110 dthetaPos = std::min<float>(dthetaCosNeg, dthetaSinPos);
1112 else if ((sin_theta < 0.f) && (cos_theta < 0.f)) {
1114 dthetaPos = std::min<float>(dthetaCosNeg, dthetaSinNeg);
1116 else if ((sin_theta > 0.f) && (cos_theta > 0.f)) {
1118 dthetaPos = std::min<float>(dthetaCosPos, dthetaSinPos);
1122 if (cos_theta > 0.f) {
1123 dthetaPos = dthetaCosNeg;
1126 dthetaPos = dthetaCosPos;
1131 if (sin_theta > 0.f) {
1132 dthetaPos = dthetaSinNeg;
1135 dthetaPos = dthetaSinPos;
1155 vpRect bbox(m_center -
vpImagePoint(m_radius, m_radius), 2 * m_radius, 2 * m_radius);
1161 return (m_radius * m_radius) / 4;
1166 return (m_radius * m_radius) / 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