diff --git a/Distance_3/include/CGAL/Distance_3/Line_3_Line_3.h b/Distance_3/include/CGAL/Distance_3/Line_3_Line_3.h index 03495be04fa..85f181af18a 100644 --- a/Distance_3/include/CGAL/Distance_3/Line_3_Line_3.h +++ b/Distance_3/include/CGAL/Distance_3/Line_3_Line_3.h @@ -45,6 +45,16 @@ squared_distance(const typename K::Line_3& line1, return squared_distance_to_plane(normal, diff, k); } +template +typename K::Comparison_result +compare_squared_distance(const typename K::Line_3& line1, + const typename K::Line_3& line2, + const K& k, + const typename K::FT& d2) +{ + return compare(squared_distance(line1,line2,k),d2); +} + } // namespace internal template @@ -56,6 +66,17 @@ squared_distance(const Line_3& line1, return K().compute_squared_distance_3_object()(line1, line2); } +template +inline +typename K::Comparison_result +compare_squared_distance(const Line_3& line1, + const Line_3& line2, + const typename K::FT& d2) +{ + return K().compare_squared_distance_3_object()(line1,line2,d2); +} + + } // namespace CGAL #endif // CGAL_DISTANCE_3_LINE_3_LINE_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Point_3_Line_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Line_3.h index 0d1527c48a7..e202cb3bdd3 100644 --- a/Distance_3/include/CGAL/Distance_3/Point_3_Line_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Line_3.h @@ -66,6 +66,28 @@ squared_distance(const typename K::Line_3& line, return squared_distance(pt, line, k); } +template +inline +typename K::Comparison_result +compare_squared_distance(const typename K::Point_3& pt, + const typename K::Line_3& line, + const K& k, + const typename K::FT& d2) +{ + return compare(squared_distance(pt, line, k), d2); +} + +template +inline +typename K::Comparison_result +compare_squared_distance(const typename K::Line_3& line, + const typename K::Point_3& pt, + const K& k, + const typename K::FT& d2) +{ + return compare(squared_distance(pt, line, k), d2); +} + } // namespace internal template @@ -86,6 +108,26 @@ squared_distance(const Line_3& line, return K().compute_squared_distance_3_object()(line, pt); } +template +inline +typename K::Comparison_result +compare_squared_distance(const Point_3& pt, + const Line_3& line, + const typename K::FT& d2) +{ + return K().compare_squared_distance_3_object()(pt, line, d2); +} + +template +inline +typename K::Comparison_result +compare_squared_distance(const Line_3& line, + const Point_3& pt, + const typename K::FT& d2) +{ + return K().compare_squared_distance_3_object()(line, pt, d2); +} + } // namespace CGAL #endif // CGAL_DISTANCE_3_POINT_3_LINE_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Point_3_Plane_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Plane_3.h index 7544a72d963..41107dfac3e 100644 --- a/Distance_3/include/CGAL/Distance_3/Point_3_Plane_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Plane_3.h @@ -48,6 +48,26 @@ squared_distance(const typename K::Plane_3& plane, return squared_distance(pt, plane, k); } +template +inline typename K::Comparison_result +compare_squared_distance(const typename K::Point_3& pt, + const typename K::Plane_3& plane, + const K& k, + const typename K::FT& d2) +{ + return compare(squared_distance(pt, plane, k), d2); +} + +template +inline typename K::Comparison_result +compare_squared_distance(const typename K::Plane_3& plane, + const typename K::Point_3& pt, + const K& k, + const typename K::FT& d2) +{ + return compare_squared_distance(pt, plane, k, d2); +} + } // namespace internal template @@ -68,6 +88,27 @@ squared_distance(const Plane_3& plane, return K().compute_squared_distance_3_object()(plane, pt); } +template +inline +typename K::Comparison_result +compare_squared_distance(const Point_3& pt, + const Plane_3& pl, + const typename K::FT& d2) +{ + return K().compare_squared_distance_3_object()(pt, pl, d2); +} + +template +inline +typename K::Comparison_result +compare_squared_distance(const Plane_3& pl, + const Point_3& pt, + const typename K::FT& d2) +{ + return K().compare_squared_distance_3_object()(pl, pt, d2); +} + + } // namespace CGAL #endif // CGAL_DISTANCE_3_POINT_3_PLANE_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Point_3_Point_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Point_3.h index 6b307e571c7..ec5102e8bee 100644 --- a/Distance_3/include/CGAL/Distance_3/Point_3_Point_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Point_3.h @@ -32,6 +32,17 @@ squared_distance(const typename K::Point_3& pt1, return k.compute_squared_distance_3_object()(pt1, pt2); } +template +inline +typename K::Comparison_result +compare_squared_distance(const typename K::Point_3& pt1, + const typename K::Point_3& pt2, + const K& k, + const typename K::FT& d2) +{ + return compare(k.compute_squared_distance_3_object()(pt1, pt2), d2); +} + } // namespace internal template diff --git a/Distance_3/include/CGAL/Distance_3/Point_3_Ray_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Ray_3.h index 7eff899b0eb..71332a693b5 100644 --- a/Distance_3/include/CGAL/Distance_3/Point_3_Ray_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Ray_3.h @@ -87,6 +87,40 @@ squared_distance(const typename K::Ray_3& ray, return squared_distance(pt, ray, k); } +template +typename K::Comparison_result +compare_squared_distance(const typename K::Point_3& pt, + const typename K::Ray_3& ray, + const K& k, + const typename K::FT &d2) +{ + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + const Vector_3 dir = ray.direction().vector(); + const Vector_3 diff = vector(ray.source(), pt); + + const typename K::Comparison_result res_pl = compare_squared_distance_to_line(dir, diff, k, d2); + if(res_pl==LARGER) + return LARGER; + + if(!is_acute_angle(dir, diff, k)) + return compare(diff*diff, d2); + + return res_pl; +} + +template +typename K::Comparison_result +compare_squared_distance(const typename K::Ray_3& ray, + const typename K::Point_3& pt, + const K& k, + const typename K::FT &d2) +{ + return compare_squared_distance(pt, ray, k, d2); +} + } // namespace internal template @@ -107,6 +141,27 @@ squared_distance(const Ray_3& ray, return K().compute_squared_distance_3_object()(ray, pt); } +template +inline +typename K::Comparison_result +compare_squared_distance(const Point_3& pt, + const Ray_3& ray, + const typename K::FT& d2) +{ + return K().compare_squared_distance_3_object()(pt, ray, d2); +} + +template +inline +typename K::Comparison_result +compare_squared_distance(const Ray_3& ray, + const Point_3& pt, + const typename K::FT& d2) +{ + return K().compare_squared_distance_3_object()(ray, pt, d2); +} + + } // namespace CGAL #endif // CGAL_DISTANCE_3_POINT_3_RAY_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Point_3_Segment_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Segment_3.h index 554c0a58d2d..5188a13622a 100644 --- a/Distance_3/include/CGAL/Distance_3/Point_3_Segment_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Segment_3.h @@ -108,6 +108,56 @@ squared_distance(const typename K::Segment_3& seg, return squared_distance(pt, seg, k); } +template +typename K::Comparison_result +compare_squared_distance(const typename K::Point_3& pt, + const typename K::Segment_3& seg, + const K& k, + const typename K::FT &d2) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + // assert that the segment is valid (non zero length). + + const Vector_3 diff = vector(seg.source(), pt); + const Vector_3 segvec = vector(seg.source(), seg.target()); + + //We first compare the distance of the point and the line + const typename K::Comparison_result res_pl= compare_squared_distance_to_line(segvec, diff, k, d2); + + //If greater than d2, we early exit + if(res_pl==LARGER) + return LARGER; + + //If distance is realized by the source + const RT d = wdot(diff, segvec, k); + if(d <= RT(0)) + return compare(FT(diff*diff), d2); + + //If distance is realized by the target + const RT e = wdot(segvec, segvec, k); + if(wmult((K*)0, d, segvec.hw()) > wmult((K*)0, e, diff.hw())) + return compare_squared_distance(pt, seg.target(), k, d2); + + //If distance is realized by the interior, it is equal to the one of the line + return res_pl; +} + +template +inline +typename K::Comparison_result +compare_squared_distance(const typename K::Segment_3& seg, + const typename K::Point_3& pt, + const K& k, + const typename K::FT &d2) +{ + return compare_squared_distance(pt, seg, k, d2); +} + } // namespace internal template @@ -128,6 +178,26 @@ squared_distance(const Segment_3& seg, return K().compute_squared_distance_3_object()(seg, pt); } +template +inline +typename K::Comparison_result +compare_squared_distance(const Point_3& pt, + const Segment_3& seg, + const typename K::FT &d2) +{ + return K().compare_squared_distance_3_object()(pt, seg, d2); +} + +template +inline +typename K::Comparison_result +compare_squared_distance(const Segment_3& seg, + const Point_3& pt, + const typename K::FT &d2) +{ + return K().compare_squared_distance_3_object()(seg, pt, d2); +} + } // namespace CGAL #endif // CGAL_DISTANCE_3_POINT_3_SEGMENT_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Point_3_Triangle_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Triangle_3.h index 8b58e9a81a6..18de39c4024 100644 --- a/Distance_3/include/CGAL/Distance_3/Point_3_Triangle_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Triangle_3.h @@ -292,6 +292,118 @@ squared_distance(const typename K::Triangle_3& t, return squared_distance(pt, t, k); } +template +inline typename K::Comparison_result +compare_squared_distance_to_triangle(const typename K::Point_3& pt, + const typename K::Point_3& t0, + const typename K::Point_3& t1, + const typename K::Point_3& t2, + const K& k, + const typename K::Ft &d2, + bool& inside) +{ + // typedef typename K::Vector_3 Vector_3; + + // typename K::Construct_segment_3 segment = k.construct_segment_3_object(); + // typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + // typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object(); + + // const Vector_3 e1 = vector(t0, t1); + // const Vector_3 oe3 = vector(t0, t2); + // const Vector_3 normal = wcross(e1, oe3, k); + + // if(normal == NULL_VECTOR) + // { + // // The case normal == NULL_VECTOR covers the case when the triangle + // // is colinear, or even more degenerate. In that case, we can + // // simply take also the distance to the three segments. + // // + // // Note that in the degenerate case, at most 2 edges cover the full triangle, + // // and only two distances could be used, but leaving 3 for the case of + // // inexact constructions as it might improve the accuracy. + // typename K::FT d1 = sq_dist(pt, segment(t2, t0)); + // typename K::FT d2 = sq_dist(pt, segment(t1, t2)); + // typename K::FT d3 = sq_dist(pt, segment(t0, t1)); + + // return (std::min)((std::min)(d1, d2), d3); + // } + + // if(!on_left_of_triangle_edge(pt, normal, t0, t1, k)) + // { + // if(!on_left_of_triangle_edge(pt, normal, t1, t2, k)) + // { + // // can't be to the right of all three segments + // return (std::min)(sq_dist(pt, segment(t0, t1)), sq_dist(pt, segment(t1, t2))); + // } + // else // on_left_of_triangle_edge(pt, normal, t1, t2, k) + // { + // if(!on_left_of_triangle_edge(pt, normal, t2, t0, k)) + // { + // return (std::min)(sq_dist(pt, segment(t0, t1)), sq_dist(pt, segment(t2, t0))); + // } + // else // on_left_of_triangle_edge(pt, normal, t2, t0, k) + // { + // return sq_dist(pt, segment(t0, t1)); + // } + // } + // } + // else // on_left_of_triangle_edge(pt, normal, t0, t1, k) + // { + // if(!on_left_of_triangle_edge(pt, normal, t1, t2, k)) + // { + // if(!on_left_of_triangle_edge(pt, normal, t2, t0, k)) + // { + // return (std::min)(sq_dist(pt, segment(t1, t2)), sq_dist(pt, segment(t2, t0))); + // } + // else // on_left_of_triangle_edge(pt, normal, t2, t0, k) + // { + // return sq_dist(pt, segment(t1, t2)); + // } + // } + // else // on_left_of_triangle_edge(pt, normal, t1, t2, k) + // { + // if(!on_left_of_triangle_edge(pt, normal, t2, t0, k)) + // { + // return sq_dist(pt, segment(t2, t0)); + // } + // else // on_left_of_triangle_edge(pt, normal, t2, t0, k) + // { + // inside = true; + // return squared_distance_to_plane(normal, vector(t0, pt), k); + // } + // } + // } +} + +template +typename K::Comparison_result +compute_squared_distance(const typename K::Point_3& pt, + const typename K::Triangle_3& t, + const K& k, + const typename K::FT& d2) +{ + typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); + + bool unused_inside = false; + return compare_squared_distance_to_triangle(pt, + vertex(t, 0), + vertex(t, 1), + vertex(t, 2), + k, + d2, + unused_inside); +} + +template +typename K::Comparison_result +compute_squared_distance(const typename K::Triangle_3& t, + const typename K::Point_3& pt, + const K& k, + const typename K::FT& d2) +{ + return compute_squared_distance(pt, t, k, d2); +} + } // namespace internal template @@ -303,6 +415,7 @@ squared_distance(const Point_3& pt, return K().compute_squared_distance_3_object()(pt, t); } + template inline typename K::FT @@ -312,6 +425,26 @@ squared_distance(const Triangle_3& t, return K().compute_squared_distance_3_object()(t, pt); } +template +inline +typename K::Comparison_result +compare_squared_distance(const Point_3& pt, + const Triangle_3& t, + const typename K::FT& d2) +{ + return K().compare_squared_distance_3_object()(pt, t, d2); +} + +template +inline +typename K::Comparison_result +compare_squared_distance(const Triangle_3& t, + const Point_3& pt, + const typename K::FT &d2) +{ + return K().compare_squared_distance_3_object()(t, pt, d2); +} + } // namespace CGAL #endif // CGAL_DISTANCE_3_POINT_3_TRIANGLE_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Segment_3_Segment_3.h b/Distance_3/include/CGAL/Distance_3/Segment_3_Segment_3.h index 12bba07926e..e993eb94ba8 100644 --- a/Distance_3/include/CGAL/Distance_3/Segment_3_Segment_3.h +++ b/Distance_3/include/CGAL/Distance_3/Segment_3_Segment_3.h @@ -145,8 +145,8 @@ template typename K::Comparison_result compare_squared_distance(const typename K::Segment_3& s1, const typename K::Segment_3& s2, - const typename K::FT& dist, - const K& k) + const K& k, + const typename K::FT& d2) { typedef typename K::FT FT; typedef typename K::Point_3 Point_3; @@ -164,21 +164,21 @@ compare_squared_distance(const typename K::Segment_3& s1, const Vector_3 v1 = cv(p1, q1), v2 = cv(p2, q2); const Vector_3 p1p2 = cv(p1, p2); - //If degenerate segment, compare distance point segment + //If degenerate segment, compare distance between the point and the other segment if(p1 == q1) if(p2 == q2) - return compare_square_distance(p1,p2,dist,k); + return compare_square_distance(p1,p2,k,d2); else - return compare_square_distance(p1,s2,dist,k); + return compare_square_distance(p1,s2,k,d2); else if(p2 == q2) - return compare_square_distance(s1,p2,dist,k); + return compare_square_distance(s1,p2,k,d2); //Compare distance between the lines const Vector_3 normal = wcross(v1, v2, k); const Vector_3 diff = p1p2; //If the lines are at distance more than d, the segment do not be at distance less than d - typename K::Comparison_result res_ll=compare_squared_distance(v1.supporting_line(), v2.supporting_line(), dist, k); + typename K::Comparison_result res_ll=compare_squared_distance(v1.supporting_line(), v2.supporting_line(), k, d2); if(res_ll==LARGER) return LARGER; //Early exit @@ -207,7 +207,7 @@ compare_squared_distance(const typename K::Segment_3& s1, { // res_y = 0; res_x = boost::algorithm::clamp(e/a, 0, 1); // (e + y*c) / a - return compare(sq_dist(p1+res_x*v1,p2), dist); + return compare(sq_dist(p1+res_x*v1,p2), d2); } else // y >= 0 { @@ -216,12 +216,12 @@ compare_squared_distance(const typename K::Segment_3& s1, { // res_y = 1; res_x = boost::algorithm::clamp((e + c) / a, 0, 1); // (e + y*c) / a - return compare(sq_dist(p1+res_x*v1,p2), dist); + return compare(sq_dist(p1+res_x*v1,p2), d2); } else if(res_x==0 || res_x==1) // 0 <= y <= 1 { FT res_y = n / d; - return compare(sq_dist(p1 + res_x*v1, p2 + res_y*v2), dist); + return compare(sq_dist(p1 + res_x*v1, p2 + res_y*v2), d2); } else { diff --git a/Distance_3/include/CGAL/Distance_3/internal/squared_distance_utils_3.h b/Distance_3/include/CGAL/Distance_3/internal/squared_distance_utils_3.h index 7dbf82e246e..38844ecab54 100644 --- a/Distance_3/include/CGAL/Distance_3/internal/squared_distance_utils_3.h +++ b/Distance_3/include/CGAL/Distance_3/internal/squared_distance_utils_3.h @@ -221,6 +221,16 @@ squared_distance_to_line(const typename K::Vector_3& dir, return Rational_traits().make_rational(num, den); } +template +typename K::Comparison_result +compare_squared_distance_to_line(const typename K::Vector_3& dir, + const typename K::Vector_3& diff, + const K& k, + const typename K::FT &d2) +{ + return compare(squared_distance_to_line(dir,diff,k),d2); +} + template inline bool diff --git a/Distance_3/include/CGAL/squared_distance_3.h b/Distance_3/include/CGAL/squared_distance_3.h index 69436bbe6dc..1cf8feb0bfc 100644 --- a/Distance_3/include/CGAL/squared_distance_3.h +++ b/Distance_3/include/CGAL/squared_distance_3.h @@ -20,9 +20,9 @@ #include #include +#include #include #include -#include #include #include #include diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index c49094aefb2..f88a4ea4c2b 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -937,7 +937,8 @@ namespace CommonKernelFunctors { Needs_FT operator()(const T1& p, const T2& q, const FT& d2) const { - return CGAL::compare(internal::squared_distance(p, q, K()), d2); + // return CGAL::compare(internal::squared_distance(p, q, K()), d2); + return internal::compare_squared_distance(p, q, K(), d2); } template