Merge pull request #1005 from afabri/Kernel-compare_distance-GF

Add specializations for Compare_distance_3::operator() for points/segments
This commit is contained in:
Laurent Rineau 2016-04-22 15:25:52 +02:00
commit 2a9ab3e7d8
4 changed files with 139 additions and 7 deletions

View File

@ -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,24 @@ 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::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::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 opposite(CGAL::internal::compare_distance_ppsC3(p1,p2,s2, K()));
}
template <class T1, class T2, class T3>
result_type
operator()(const T1& p, const T2& q, const T3& r) const

View File

@ -176,6 +176,94 @@ squared_distance(
template <class K>
typename K::Comparison_result
compare_distance_pssC3(
const typename K::Point_3 &pt,
const typename K::Segment_3 &seg1,
const typename K::Segment_3 &seg2,
const K& k)
{
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 <class K>
typename K::Comparison_result
compare_distance_ppsC3(
const typename K::Point_3 &pt,
const typename K::Point_3 &pt2,
const typename K::Segment_3 &seg,
const K& k)
{
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 <class K>
typename K::FT
@ -529,7 +617,7 @@ squared_distance(
template <class K>
inline
inline
typename K::FT
squared_distance(
const typename K::Line_3 & line,
@ -741,7 +829,7 @@ squared_distance(
template <class K>
inline
inline
typename K::FT
squared_distance(
const Ray_3<K> & ray,
@ -763,7 +851,7 @@ squared_distance(
template <class K>
inline
inline
typename K::FT
squared_distance(
const Segment_3<K> & seg,
@ -848,7 +936,7 @@ squared_distance(
template <class K>
inline
inline
typename K::FT
squared_distance(
const Line_3<K> & line,
@ -921,7 +1009,6 @@ squared_distance(
}
} //namespace CGAL

View File

@ -0,0 +1,26 @@
#include <CGAL/Homogeneous.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
template <typename K>
void cmp(const K& k)
{
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);
}
int main()
{
CGAL::Exact_predicates_inexact_constructions_kernel epic;
CGAL::Homogeneous<int> hk;
cmp(epic);
cmp(hk);
return 0;
}

View File

@ -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,