From 324d531dfe2edd6ef06736cfd8e20c10da43e710 Mon Sep 17 00:00:00 2001 From: Sven Oesau Date: Tue, 7 Oct 2025 19:44:49 +0200 Subject: [PATCH] Circle_2 - Segment_2 intersection does now consider inclusion as non intersecting --- .../CGAL/Intersections_2/Circle_2_Segment_2.h | 88 +++++++++++++++++-- .../Intersections_2/test_intersections_2.cpp | 1 + 2 files changed, 84 insertions(+), 5 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h index d884d520332..fa5558f32b1 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h @@ -13,8 +13,9 @@ #ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_SEGMENT_2_H #define CGAL_INTERSECTIONS_2_CIRCLE_2_SEGMENT_2_H -#include +#include #include +#include #include #include @@ -22,23 +23,100 @@ namespace CGAL { namespace Intersections { namespace internal { +// + +template +typename K::Boolean +do_intersect(const typename K::Circle_2& circ, + const typename K::Segment_2& s, + const K& k, + const Homogeneous_tag&) +{ + typedef typename K::Vector_2 Vector_2; + typedef typename K::Point_2 Point_2; + typedef typename K::FT FT; + + typename K::Construct_vector_2 vector = k.construct_vector_2_object(); + typename K::Compute_squared_length_2 sq_length = k.compute_squared_length_2_object(); + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + const Point_2 c = circ.center(); + const FT sqrad = circ.squared_radius(); + const Vector_2 diffsrc = vector(s.source(), c); + const Vector_2 difftgt = vector(s.target(), c); + + FT lsrc = CGAL::internal::wdot(diffsrc, diffsrc, k); + FT lsrcw = square(diffsrc.hw()); + FT ltgt = CGAL::internal::wdot(difftgt, difftgt, k); + FT ltgtw = square(difftgt.hw()); + + if (lsrc < sqrad * lsrcw) { + if (ltgt < sqrad * ltgtw) + return false; + else + return true; + } + else if (ltgt <= sqrad * ltgtw) + return true; + + return sq_dist(c, s.supporting_line()) <= sqrad; +} + +template +typename K::Boolean +do_intersect(const typename K::Circle_2& circ, + const typename K::Segment_2& s, + const K& k, + const Cartesian_tag&) +{ + typedef typename K::Vector_2 Vector_2; + typedef typename K::Point_2 Point_2; + typedef typename K::FT FT; + + typename K::Construct_vector_2 vector = k.construct_vector_2_object(); + typename K::Compute_squared_length_2 sq_length = k.compute_squared_length_2_object(); + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + const Point_2 c = circ.center(); + const FT sqrad = circ.squared_radius(); + const Vector_2 diffsrc = vector(s.source(), c); + const Vector_2 difftgt = vector(s.target(), c); + + FT lsrc = CGAL::internal::wdot(diffsrc, diffsrc, k); + FT ltgt = CGAL::internal::wdot(difftgt, difftgt, k); + + if (lsrc < sqrad) { + if (ltgt < sqrad) + return false; + else + return true; + } + else if (ltgt <= sqrad) + return true; + + return sq_dist(c, s.supporting_line()) <= sqrad; +} template typename K::Boolean do_intersect(const typename K::Circle_2& c, const typename K::Segment_2& s, - const K&) + const K& k) { - return squared_distance(c.center(), s) <= c.squared_radius(); + typedef typename K::Kernel_tag Tag; + Tag tag; + return do_intersect(c, s, k, tag); } template typename K::Boolean do_intersect(const typename K::Segment_2& s, const typename K::Circle_2& c, - const K&) + const K& k) { - return squared_distance(c.center(), s) <= c.squared_radius(); + typedef typename K::Kernel_tag Tag; + Tag tag; + return do_intersect(c, s, k, tag); } } // namespace internal diff --git a/Intersections_2/test/Intersections_2/test_intersections_2.cpp b/Intersections_2/test/Intersections_2/test_intersections_2.cpp index 8219881120d..368fbd7d37c 100644 --- a/Intersections_2/test/Intersections_2/test_intersections_2.cpp +++ b/Intersections_2/test/Intersections_2/test_intersections_2.cpp @@ -341,6 +341,7 @@ struct Test check_no_do_intersect (C(p( 2, 8), 6), S(p(-3, -2), p( 2, -4))); check_no_do_intersect (C(p( 2, 8), 6), S(p(-3, 22), p( 2, 34))); check_no_do_intersect (C(p( 4, 16), 18), S(p(5, 7), p(6, 8))); + check_no_do_intersect (C(p( 0, 0), 25), S(p(-2, -2), p(2, 2))); check_do_intersect (C(p( 3, 4), 0), S(p(-3, 8), p( 6, 2))); check_do_intersect (C(p( 4, 3), 4), S(p( 6, -7), p( 5, 2)));