Compare squared distance with point

This commit is contained in:
Léo Valque 2025-02-18 18:57:48 +01:00
parent 73d79f8194
commit d7c9cce0b9
11 changed files with 396 additions and 12 deletions

View File

@ -45,6 +45,16 @@ squared_distance(const typename K::Line_3& line1,
return squared_distance_to_plane(normal, diff, k);
}
template <class K>
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 <class K>
@ -56,6 +66,17 @@ squared_distance(const Line_3<K>& line1,
return K().compute_squared_distance_3_object()(line1, line2);
}
template <class K>
inline
typename K::Comparison_result
compare_squared_distance(const Line_3<K>& line1,
const Line_3<K>& 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

View File

@ -66,6 +66,28 @@ squared_distance(const typename K::Line_3& line,
return squared_distance(pt, line, k);
}
template <class K>
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 <class K>
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 <class K>
@ -86,6 +108,26 @@ squared_distance(const Line_3<K>& line,
return K().compute_squared_distance_3_object()(line, pt);
}
template <class K>
inline
typename K::Comparison_result
compare_squared_distance(const Point_3<K>& pt,
const Line_3<K>& line,
const typename K::FT& d2)
{
return K().compare_squared_distance_3_object()(pt, line, d2);
}
template <class K>
inline
typename K::Comparison_result
compare_squared_distance(const Line_3<K>& line,
const Point_3<K>& 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

View File

@ -48,6 +48,26 @@ squared_distance(const typename K::Plane_3& plane,
return squared_distance(pt, plane, k);
}
template <class K>
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 <class K>
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 <class K>
@ -68,6 +88,27 @@ squared_distance(const Plane_3<K>& plane,
return K().compute_squared_distance_3_object()(plane, pt);
}
template <class K>
inline
typename K::Comparison_result
compare_squared_distance(const Point_3<K>& pt,
const Plane_3<K>& pl,
const typename K::FT& d2)
{
return K().compare_squared_distance_3_object()(pt, pl, d2);
}
template <class K>
inline
typename K::Comparison_result
compare_squared_distance(const Plane_3<K>& pl,
const Point_3<K>& 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

View File

@ -32,6 +32,17 @@ squared_distance(const typename K::Point_3& pt1,
return k.compute_squared_distance_3_object()(pt1, pt2);
}
template <class K>
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 <class K>

View File

@ -87,6 +87,40 @@ squared_distance(const typename K::Ray_3& ray,
return squared_distance(pt, ray, k);
}
template <class K>
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 <class K>
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 <class K>
@ -107,6 +141,27 @@ squared_distance(const Ray_3<K>& ray,
return K().compute_squared_distance_3_object()(ray, pt);
}
template <class K>
inline
typename K::Comparison_result
compare_squared_distance(const Point_3<K>& pt,
const Ray_3<K>& ray,
const typename K::FT& d2)
{
return K().compare_squared_distance_3_object()(pt, ray, d2);
}
template <class K>
inline
typename K::Comparison_result
compare_squared_distance(const Ray_3<K>& ray,
const Point_3<K>& 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

View File

@ -108,6 +108,56 @@ squared_distance(const typename K::Segment_3& seg,
return squared_distance(pt, seg, k);
}
template <class K>
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 <class K>
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 <class K>
@ -128,6 +178,26 @@ squared_distance(const Segment_3<K>& seg,
return K().compute_squared_distance_3_object()(seg, pt);
}
template <class K>
inline
typename K::Comparison_result
compare_squared_distance(const Point_3<K>& pt,
const Segment_3<K>& seg,
const typename K::FT &d2)
{
return K().compare_squared_distance_3_object()(pt, seg, d2);
}
template <class K>
inline
typename K::Comparison_result
compare_squared_distance(const Segment_3<K>& seg,
const Point_3<K>& 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

View File

@ -292,6 +292,118 @@ squared_distance(const typename K::Triangle_3& t,
return squared_distance(pt, t, k);
}
template <class K>
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 <class K>
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 <class K>
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 <class K>
@ -303,6 +415,7 @@ squared_distance(const Point_3<K>& pt,
return K().compute_squared_distance_3_object()(pt, t);
}
template <class K>
inline
typename K::FT
@ -312,6 +425,26 @@ squared_distance(const Triangle_3<K>& t,
return K().compute_squared_distance_3_object()(t, pt);
}
template <class K>
inline
typename K::Comparison_result
compare_squared_distance(const Point_3<K>& pt,
const Triangle_3<K>& t,
const typename K::FT& d2)
{
return K().compare_squared_distance_3_object()(pt, t, d2);
}
template <class K>
inline
typename K::Comparison_result
compare_squared_distance(const Triangle_3<K>& t,
const Point_3<K>& 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

View File

@ -145,8 +145,8 @@ template <typename K>
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<FT>(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<FT>((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
{

View File

@ -221,6 +221,16 @@ squared_distance_to_line(const typename K::Vector_3& dir,
return Rational_traits<FT>().make_rational(num, den);
}
template <class K>
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 <class K>
inline
bool

View File

@ -20,9 +20,9 @@
#include <CGAL/Distance_3/Point_3_Point_3.h>
#include <CGAL/Distance_3/Point_3_Weighted_point_3.h>
#include <CGAL/Distance_3/Point_3_Line_3.h>
#include <CGAL/Distance_3/Point_3_Segment_3.h>
#include <CGAL/Distance_3/Point_3_Ray_3.h>
#include <CGAL/Distance_3/Point_3_Line_3.h>
#include <CGAL/Distance_3/Point_3_Triangle_3.h>
#include <CGAL/Distance_3/Point_3_Plane_3.h>
#include <CGAL/Distance_3/Point_3_Tetrahedron_3.h>

View File

@ -937,7 +937,8 @@ namespace CommonKernelFunctors {
Needs_FT<result_type>
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 <class T1, class T2, class T3, class T4>