diff --git a/AABB_tree/doc/AABB_tree/Concepts/AABBGeomTraits.h b/AABB_tree/doc/AABB_tree/Concepts/AABBGeomTraits.h index a579453e9f2..ec017f1efe3 100644 --- a/AABB_tree/doc/AABB_tree/Concepts/AABBGeomTraits.h +++ b/AABB_tree/doc/AABB_tree/Concepts/AABBGeomTraits.h @@ -66,7 +66,8 @@ typedef unspecified_type Construct_sphere_3; /*! A functor object to compute the point on a geometric primitive which is closest from a query. Provides the operator: -`Point_3 operator()(const Type_2& type_2, const Point_3& p);` where `Type_2` is any type among `Segment_3` and `Triangle_3`. The operator returns the point on `type_2` which is closest to `p`. +`Point_3 operator()(const Type_2& type_2, const Point_3& p);` where `Type_2` can be any of the following types : `Segment_3`, `Ray_3`, or `Triangle_3`. +The operator returns the point on `type_2` which is closest to `p`. */ typedef unspecified_type Construct_projected_point_3; diff --git a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h index 600fe1af0d5..a53b3fe55a8 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h @@ -3181,6 +3181,7 @@ namespace CartesianKernelFunctors { typedef typename K::Line_3 Line_3; typedef typename K::Triangle_3 Triangle_3; typedef typename K::Segment_3 Segment_3; + typedef typename K::Ray_3 Ray_3; typedef typename K::FT FT; public: typedef Point_3 result_type; @@ -3215,6 +3216,10 @@ namespace CartesianKernelFunctors { Point_3 operator()( const Segment_3& s, const Point_3& p ) const { return CommonKernelFunctors::Construct_projected_point_3()(p,s,K()); } + + Point_3 + operator()( const Ray_3& r, const Point_3& p ) const + { return CommonKernelFunctors::Construct_projected_point_3()(p,r,K()); } }; template diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/function_objects.h b/Homogeneous_kernel/include/CGAL/Homogeneous/function_objects.h index 080bd4929ea..40c2e3b2f65 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/function_objects.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/function_objects.h @@ -3315,6 +3315,7 @@ namespace HomogeneousKernelFunctors { typedef typename K::Vector_3 Vector_3; typedef typename K::Triangle_3 Triangle_3; typedef typename K::Segment_3 Segment_3; + typedef typename K::Ray_3 Ray_3; public: typedef Point_3 result_type; @@ -3351,6 +3352,10 @@ namespace HomogeneousKernelFunctors { Point_3 operator()( const Segment_3& s, const Point_3& p ) const { return CommonKernelFunctors::Construct_projected_point_3()(p,s,K()); } + + Point_3 + operator()( const Ray_3& r, const Point_3& p ) const + { return CommonKernelFunctors::Construct_projected_point_3()(p,r,K()); } }; template diff --git a/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h b/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h index 2cb3db219c7..ef058713356 100644 --- a/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h +++ b/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h @@ -5976,6 +5976,12 @@ public: */ Kernel::Point_3 operator()(const Kernel::Segment_3& s, const Kernel::Point_3& p); + + /*! + returns the point of `r` that is the closest to `p`. + */ + Kernel::Point_3 operator()(const Kernel::Ray_3& r, + const Kernel::Point_3& p); /*! returns the point of `t` that is the closest to `p`. diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index 0ff0de5764b..ec0681875e5 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -2855,10 +2855,7 @@ namespace CommonKernelFunctors { const typename K::Segment_3& segment, const K& k) { - typedef typename K::Point_3 Point_3; - typename K::Construct_projected_point_3 projection = - k.construct_projected_point_3_object(); typename K::Is_degenerate_3 is_degenerate = k.is_degenerate_3_object(); typename K::Construct_vertex_3 vertex = @@ -2867,20 +2864,27 @@ namespace CommonKernelFunctors { if(is_degenerate(segment)) return vertex(segment, 0); - // Project query on segment supporting line - const Point_3 proj = projection(segment.supporting_line(), query); - - Point_3 closest_point_on_segment; - bool inside = is_inside_segment_3(proj,segment,closest_point_on_segment,k); - + if(segment.to_vector() * (query-segment.source()) <= 0) + return segment.source(); + if(segment.to_vector() * (query-segment.target()) >= 0) + return segment.target(); // If proj is inside segment, returns it - if ( inside ) - return proj; - - // Else returns the constructed point - return closest_point_on_segment; + return k.construct_projected_point_3_object()(segment.supporting_line(), query); } + typename K::Point_3 + operator()(const typename K::Point_3& query, + const typename K::Ray_3& ray, + const K& k) + { + if ( ray.to_vector() * (query-ray.source()) <= 0) + return ray.source(); + else + { + return k.construct_projected_point_3_object()(ray.supporting_line(), query); + } + } + // code for operator for plane and point is defined in // CGAL/Cartesian/function_objects.h and CGAL/Homogeneous/function_objects.h }; diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_constructions_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_constructions_3.h index 2c3ff790b01..72326c520a7 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_constructions_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_constructions_3.h @@ -26,12 +26,13 @@ template bool -_test_fct_constructions_3(const R&) +_test_fct_constructions_3(const R& r) { typedef typename R::RT RT; typedef typename R::Point_3 Point; typedef typename R::Weighted_point_3 Weighted_point; typedef typename R::Segment_3 Segment; + typedef typename R::Ray_3 Ray; typedef typename R::Plane_3 Plane; typedef typename R::Vector_3 Vector; typedef typename R::Triangle_3 Triangle; @@ -129,6 +130,12 @@ _test_fct_constructions_3(const R&) assert( CGAL::weighted_circumcenter( wp000_b, wp100_b, wp010_b) == wp000_b); assert( CGAL::weighted_circumcenter( wp000_b, wp100_b, wp010_b, wp001_b) == wp000_b); + // projected point + Ray ray(Point(0,0,0), Point (1,1,0)); + Segment s(Point(0,0,0), Point (1,1,0)); + assert( r.construct_projected_point_3_object()(ray, Point(-1,0,0)) == Point(0,0,0)); + assert( r.construct_projected_point_3_object()(s, Point(-1,0,0)) == Point(0,0,0)); + assert( r.construct_projected_point_3_object()(s, Point(2,0,0)) == Point(1,1,0)); return true; }