From 2613be3c1b25385c2cdca1c1c2fd144a6496889d Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 13 Apr 2016 12:35:00 +0200 Subject: [PATCH 1/5] Add specializations for Compare_distance_3 for points/segments --- .../include/CGAL/Cartesian/function_objects.h | 20 +++ .../include/CGAL/squared_distance_3_1.h | 150 +++++++++++++++++- .../include/CGAL/Kernel/interface_macros.h | 4 +- 3 files changed, 168 insertions(+), 6 deletions(-) diff --git a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h index 71b30a58010..4053c406b33 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h @@ -462,6 +462,7 @@ namespace CartesianKernelFunctors { class Compare_distance_3 { typedef typename K::Point_3 Point_3; + typedef typename K::Segment_3 Segment_3; public: typedef typename K::Comparison_result result_type; @@ -473,6 +474,25 @@ namespace CartesianKernelFunctors { r.x(), r.y(), r.z()); } + + result_type + operator()(const Point_3& p1, const Segment_3& s1, const Segment_3& s2) const + { + return CGAL::compare_distance(p1,s1,s2); + } + + result_type + operator()(const Point_3& p1, const Point_3& p2, const Segment_3& s2) const + { + return CGAL::compare_distance(p1,p2,s2); + } + + result_type + operator()(const Point_3& p1, const Segment_3& s2, const Point_3& p2) const + { + return CGAL::compare_distance(p1,p2,s2); + } + template result_type operator()(const T1& p, const T2& q, const T3& r) const diff --git a/Distance_3/include/CGAL/squared_distance_3_1.h b/Distance_3/include/CGAL/squared_distance_3_1.h index 0f1e0bbe86d..c88102034fa 100644 --- a/Distance_3/include/CGAL/squared_distance_3_1.h +++ b/Distance_3/include/CGAL/squared_distance_3_1.h @@ -174,6 +174,125 @@ squared_distance( return squared_distance(pt, seg, k); } +template +typename K::Comparison_result +compare_distance( + const typename K::Point_3 &pt, + const typename K::Segment_3 &seg1, + const typename K::Segment_3 &seg2, + const K& k, + const Cartesian_tag&) +{ + typename K::Construct_vector_3 construct_vector; + typedef typename K::Vector_3 Vector_3; + typedef typename K::RT RT; + typedef typename K::FT FT; + FT d1=FT(0), d2=FT(0); + RT e1 = RT(1), e2 = RT(1); + // assert that the segment is valid (non zero length). + { + Vector_3 diff = construct_vector(seg1.source(), pt); + Vector_3 segvec = construct_vector(seg1.source(), seg1.target()); + RT d = wdot(diff,segvec, k); + if (d <= (RT)0){ + d1 = (FT(diff*diff)); + }else{ + RT e = wdot(segvec,segvec, k); + if (d > e){ + d1 = squared_distance(pt, seg1.target(), k); + } else{ + Vector_3 wcr = wcross(segvec, diff, k); + d1 = FT(wcr*wcr); + e1 = e; + } + } + } + { + Vector_3 diff = construct_vector(seg2.source(), pt); + Vector_3 segvec = construct_vector(seg2.source(), seg2.target()); + RT d = wdot(diff,segvec, k); + if (d <= (RT)0){ + d2 = (FT(diff*diff)); + }else{ + RT e = wdot(segvec,segvec, k); + if (d > e){ + d2 = squared_distance(pt, seg2.target(), k); + } else{ + Vector_3 wcr = wcross(segvec, diff, k); + d2 = FT(wcr*wcr); + e2 = e; + } + } + } + return compare(d1*e2, d2*e1); +} + +template +typename K::Comparison_result +compare_distance( + const typename K::Point_3 &pt, + const typename K::Point_3 &pt2, + const typename K::Segment_3 &seg, + const K& k, + const Cartesian_tag&) +{ + typename K::Construct_vector_3 construct_vector; + typedef typename K::Vector_3 Vector_3; + typedef typename K::RT RT; + typedef typename K::FT FT; + RT e2 = RT(1); + // assert that the segment is valid (non zero length). + FT d1 = squared_distance(pt, pt2, k); + FT d2 = FT(0); + { + Vector_3 diff = construct_vector(seg.source(), pt); + Vector_3 segvec = construct_vector(seg.source(), seg.target()); + RT d = wdot(diff,segvec, k); + if (d <= (RT)0){ + d2 = (FT(diff*diff)); + }else{ + RT e = wdot(segvec,segvec, k); + if (d > e){ + d2 = squared_distance(pt, seg.target(), k); + } else{ + Vector_3 wcr = wcross(segvec, diff, k); + d2 = FT(wcr*wcr); + e2 = e; + } + } + } + return compare(d1*e2, d2); +} + +template +inline +typename K::Comparison_result +compare_distance( + const typename K::Point_3 & pt, + const typename K::Point_3 & pt2, + const typename K::Segment_3 & seg2, + const K& k) +{ + typedef typename K::Kernel_tag Tag; + Tag tag; + return compare_distance(pt, pt2, seg2, k, tag); +} + + +template +inline +typename K::Comparison_result +compare_distance( + const typename K::Point_3 & pt, + const typename K::Segment_3 & seg1, + const typename K::Segment_3 & seg2, + const K& k) +{ + typedef typename K::Kernel_tag Tag; + Tag tag; + return compare_distance(pt, seg1, seg2, k, tag); +} + @@ -529,7 +648,7 @@ squared_distance( template -inline +inline typename K::FT squared_distance( const typename K::Line_3 & line, @@ -741,7 +860,7 @@ squared_distance( template -inline +inline typename K::FT squared_distance( const Ray_3 & ray, @@ -763,7 +882,7 @@ squared_distance( template -inline +inline typename K::FT squared_distance( const Segment_3 & seg, @@ -848,7 +967,7 @@ squared_distance( template -inline +inline typename K::FT squared_distance( const Line_3 & line, @@ -921,6 +1040,29 @@ squared_distance( } +template +inline +typename K::Comparison_result +compare_distance( + const Point_3 &p, + const Point_3 &p2, + const Segment_3 &s2) +{ + return internal::compare_distance(p, p2, s2, K()); +} + + +template +inline +typename K::Comparison_result +compare_distance( + const Point_3 &p, + const Segment_3 &s1, + const Segment_3 &s2) +{ + return internal::compare_distance(p, s1, s2, K()); +} + } //namespace CGAL diff --git a/Kernel_23/include/CGAL/Kernel/interface_macros.h b/Kernel_23/include/CGAL/Kernel/interface_macros.h index 2a4587e24bb..e4769ba252c 100644 --- a/Kernel_23/include/CGAL/Kernel/interface_macros.h +++ b/Kernel_23/include/CGAL/Kernel/interface_macros.h @@ -116,8 +116,8 @@ CGAL_Kernel_pred(Compare_dihedral_angle_3, compare_dihedral_angle_3_object) CGAL_Kernel_pred(Compare_distance_2, compare_distance_2_object) -CGAL_Kernel_pred(Compare_distance_3, - compare_distance_3_object) +CGAL_Kernel_pred_RT(Compare_distance_3, + compare_distance_3_object) CGAL_Kernel_pred(Compare_slope_2, compare_slope_2_object) CGAL_Kernel_pred(Compare_squared_distance_2, From 594442428c65526bbdf1057cd6da32559d7acd34 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 13 Apr 2016 13:29:23 +0200 Subject: [PATCH 2/5] make it work with Homogenous --- .../include/CGAL/squared_distance_3_1.h | 29 +++++++++++++++++++ .../test/Distance_3/compare_distance_3.cpp | 23 +++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 Distance_3/test/Distance_3/compare_distance_3.cpp diff --git a/Distance_3/include/CGAL/squared_distance_3_1.h b/Distance_3/include/CGAL/squared_distance_3_1.h index c88102034fa..73ae578f59b 100644 --- a/Distance_3/include/CGAL/squared_distance_3_1.h +++ b/Distance_3/include/CGAL/squared_distance_3_1.h @@ -174,6 +174,35 @@ squared_distance( return squared_distance(pt, seg, k); } +template +typename K::Comparison_result +compare_distance( + const typename K::Point_3 &pt, + const typename K::Segment_3 &seg1, + const typename K::Segment_3 &seg2, + const K& k, + const Homogeneous_tag& t) +{ + typename K::FT d1 = squared_distance(pt,seg1,k,t); + typename K::FT d2 = squared_distance(pt,seg2,k,t); + return compare(d1,d2); +} + +template +typename K::Comparison_result +compare_distance( + const typename K::Point_3 &pt, + const typename K::Point_3 &pt2, + const typename K::Segment_3 &seg2, + const K& k, + const Homogeneous_tag& t) +{ + typename K::FT d1 = squared_distance(pt,pt2,k,t); + typename K::FT d2 = squared_distance(pt,seg2,k,t); + return compare(d1,d2); +} + + template typename K::Comparison_result compare_distance( diff --git a/Distance_3/test/Distance_3/compare_distance_3.cpp b/Distance_3/test/Distance_3/compare_distance_3.cpp new file mode 100644 index 00000000000..63f75f411ac --- /dev/null +++ b/Distance_3/test/Distance_3/compare_distance_3.cpp @@ -0,0 +1,23 @@ + +#include +#include + + +template +void cmp(const K& k) +{ + typename K::Point_3 p, q; + typename K::Segment_3 s1, s2; + + k.compare_distance_3_object()(p,s1, s2); + k.compare_distance_3_object()(p,q, s2); +} + +int main() +{ + CGAL::Exact_predicates_inexact_constructions_kernel epic; + CGAL::Homogeneous hk; + cmp(epic); + cmp(hk); + return 0; +} From d00c04777ec85c2dd90caf6e61bc1c917585ef30 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 15 Apr 2016 10:31:33 +0200 Subject: [PATCH 3/5] Remove ambiguity reported by GCC --- .../include/CGAL/Cartesian/function_objects.h | 7 +- .../include/CGAL/squared_distance_3_1.h | 96 ++----------------- 2 files changed, 9 insertions(+), 94 deletions(-) diff --git a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h index 4053c406b33..3e4b23cf7db 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h @@ -474,23 +474,22 @@ namespace CartesianKernelFunctors { r.x(), r.y(), r.z()); } - result_type operator()(const Point_3& p1, const Segment_3& s1, const Segment_3& s2) const { - return CGAL::compare_distance(p1,s1,s2); + return CGAL::internal::compare_distance_pssC3(p1,s1,s2, K()); } result_type operator()(const Point_3& p1, const Point_3& p2, const Segment_3& s2) const { - return CGAL::compare_distance(p1,p2,s2); + return CGAL::internal::compare_distance_ppsC3(p1,p2,s2, K()); } result_type operator()(const Point_3& p1, const Segment_3& s2, const Point_3& p2) const { - return CGAL::compare_distance(p1,p2,s2); + return CGAL::internal::compare_distance_ppsC3(p1,p2,s2, K()); } template diff --git a/Distance_3/include/CGAL/squared_distance_3_1.h b/Distance_3/include/CGAL/squared_distance_3_1.h index 73ae578f59b..31af229ad71 100644 --- a/Distance_3/include/CGAL/squared_distance_3_1.h +++ b/Distance_3/include/CGAL/squared_distance_3_1.h @@ -174,43 +174,15 @@ squared_distance( return squared_distance(pt, seg, k); } + + template typename K::Comparison_result -compare_distance( +compare_distance_pssC3( const typename K::Point_3 &pt, const typename K::Segment_3 &seg1, const typename K::Segment_3 &seg2, - const K& k, - const Homogeneous_tag& t) -{ - typename K::FT d1 = squared_distance(pt,seg1,k,t); - typename K::FT d2 = squared_distance(pt,seg2,k,t); - return compare(d1,d2); -} - -template -typename K::Comparison_result -compare_distance( - const typename K::Point_3 &pt, - const typename K::Point_3 &pt2, - const typename K::Segment_3 &seg2, - const K& k, - const Homogeneous_tag& t) -{ - typename K::FT d1 = squared_distance(pt,pt2,k,t); - typename K::FT d2 = squared_distance(pt,seg2,k,t); - return compare(d1,d2); -} - - -template -typename K::Comparison_result -compare_distance( - const typename K::Point_3 &pt, - const typename K::Segment_3 &seg1, - const typename K::Segment_3 &seg2, - const K& k, - const Cartesian_tag&) + const K& k) { typename K::Construct_vector_3 construct_vector; typedef typename K::Vector_3 Vector_3; @@ -258,12 +230,11 @@ compare_distance( template typename K::Comparison_result -compare_distance( +compare_distance_ppsC3( const typename K::Point_3 &pt, const typename K::Point_3 &pt2, const typename K::Segment_3 &seg, - const K& k, - const Cartesian_tag&) + const K& k) { typename K::Construct_vector_3 construct_vector; typedef typename K::Vector_3 Vector_3; @@ -293,37 +264,6 @@ compare_distance( return compare(d1*e2, d2); } -template -inline -typename K::Comparison_result -compare_distance( - const typename K::Point_3 & pt, - const typename K::Point_3 & pt2, - const typename K::Segment_3 & seg2, - const K& k) -{ - typedef typename K::Kernel_tag Tag; - Tag tag; - return compare_distance(pt, pt2, seg2, k, tag); -} - - -template -inline -typename K::Comparison_result -compare_distance( - const typename K::Point_3 & pt, - const typename K::Segment_3 & seg1, - const typename K::Segment_3 & seg2, - const K& k) -{ - typedef typename K::Kernel_tag Tag; - Tag tag; - return compare_distance(pt, seg1, seg2, k, tag); -} - - - template typename K::FT @@ -1069,30 +1009,6 @@ squared_distance( } -template -inline -typename K::Comparison_result -compare_distance( - const Point_3 &p, - const Point_3 &p2, - const Segment_3 &s2) -{ - return internal::compare_distance(p, p2, s2, K()); -} - - -template -inline -typename K::Comparison_result -compare_distance( - const Point_3 &p, - const Segment_3 &s1, - const Segment_3 &s2) -{ - return internal::compare_distance(p, s1, s2, K()); -} - - } //namespace CGAL From 4b74d71525bcde201e085804bf4f4f3484d05a0d Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Sat, 16 Apr 2016 20:26:38 +0200 Subject: [PATCH 4/5] segments were degenerate --- Distance_3/test/Distance_3/compare_distance_3.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Distance_3/test/Distance_3/compare_distance_3.cpp b/Distance_3/test/Distance_3/compare_distance_3.cpp index 63f75f411ac..46c567fb9c5 100644 --- a/Distance_3/test/Distance_3/compare_distance_3.cpp +++ b/Distance_3/test/Distance_3/compare_distance_3.cpp @@ -6,8 +6,11 @@ template void cmp(const K& k) { - typename K::Point_3 p, q; - typename K::Segment_3 s1, s2; + typedef typename K::Point_3 Point_3; + + Point_3 p(0,0,0), q(1,1,1); + typename K::Segment_3 s1(Point_3(1,0,0),Point_3(1,1,0)), + s2(Point_3(1,1,1),Point_3(2,2,2)); k.compare_distance_3_object()(p,s1, s2); k.compare_distance_3_object()(p,q, s2); From dd249bb1f079d73efc14eb1e609da49605b50926 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Sat, 16 Apr 2016 21:02:38 +0200 Subject: [PATCH 5/5] Call opposite() when changing the order of arguments --- Cartesian_kernel/include/CGAL/Cartesian/function_objects.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h index 3e4b23cf7db..79f68441a2b 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h @@ -489,7 +489,7 @@ namespace CartesianKernelFunctors { result_type operator()(const Point_3& p1, const Segment_3& s2, const Point_3& p2) const { - return CGAL::internal::compare_distance_ppsC3(p1,p2,s2, K()); + return opposite(CGAL::internal::compare_distance_ppsC3(p1,p2,s2, K())); } template