diff --git a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h index f0b5b7fa5ff..759213e2687 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h @@ -3295,9 +3295,28 @@ namespace CartesianKernelFunctors { Point_2 operator()( const Segment_2& s, const Point_2& p ) const { - assert(false); - return p; - // CommonKernelFunctors::Construct_projected_point_3()(s,p,K()); + const Point_2& a = s.source(); + const Point_2& b = s.target(); + typename K::FT dx = b.x() - a.x(); + typename K::FT dy = b.y() - a.y(); + + // Degenerate segment + if (dx == 0 && dy == 0) + return a; + + typename K::FT px = p.x() - a.x(); + typename K::FT py = p.y() - a.y(); + + typename K::FT proj = (dx * px + dy * py) / (dx * dx + dy * dy); + + if (proj <= 0.0) + return a; + + if (proj >= 1.0) + return b; + + typename K::Construct_point_2 construct_point_2; + return construct_point_2(a.x() + proj * dx, a.y() + proj * dy); } Point_2 diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_constructions_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_constructions_2.h index 288d6a55dfd..c4411533b41 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_constructions_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_constructions_2.h @@ -20,7 +20,7 @@ template bool -_test_fct_constructions_2(const R&) +_test_fct_constructions_2(const R& r) { typedef typename R::RT RT; typedef CGAL::Point_2 Point; @@ -89,6 +89,15 @@ _test_fct_constructions_2(const R&) assert( CGAL::weighted_circumcenter( wpnw_b, wpse_b, wpsw_b ) == psw); + Point a(0.0, 1.0); + Point b(3.0, 4.0); + Segment seg(a, b); + + assert(r.construct_projected_point_2_object()(seg, Point(0, 0)) == a); + assert(r.construct_projected_point_2_object()(seg, Point(5.0, 0)) == Point(2.0, 3.0)); + assert(r.construct_projected_point_2_object()(seg, Point(5.0, 4.0)) == b); + assert(r.construct_projected_point_2_object()(seg, Point(2.0, 4.0)) == Point(2.5, 3.5)); + return true; }