Circle_2 - Segment_2 intersection does now consider inclusion as non intersecting

This commit is contained in:
Sven Oesau 2025-10-07 19:44:49 +02:00
parent 6a62e8c214
commit 324d531dfe
2 changed files with 84 additions and 5 deletions

View File

@ -13,8 +13,9 @@
#ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_SEGMENT_2_H
#define CGAL_INTERSECTIONS_2_CIRCLE_2_SEGMENT_2_H
#include <CGAL/Distance_2/Point_2_Segment_2.h>
#include <CGAL/Distance_2/internal/squared_distance_utils_2.h>
#include <CGAL/Intersection_traits_2.h>
#include <CGAL/tags.h>
#include <CGAL/Circle_2.h>
#include <CGAL/Segment_2.h>
@ -22,23 +23,100 @@
namespace CGAL {
namespace Intersections {
namespace internal {
//
template <class K>
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 <class K>
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 <class K>
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 <class K>
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

View File

@ -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)));