From 6b0459c686b69bc3ed96fbf1c1546cf5ae86f3f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 12 Mar 2021 11:47:40 +0100 Subject: [PATCH 01/23] Re-organize squared_distance_3_x.h into squared_distance_O1_O2.h + minor improvements (missing overloads, obvious improvements, etc.) --- .../include/CGAL/Cartesian/function_objects.h | 103 +- .../squared_distance_utils_3.h} | 166 +-- Distance_3/include/CGAL/squared_distance_3.h | 30 +- .../include/CGAL/squared_distance_3_1.h | 1007 ----------------- .../include/CGAL/squared_distance_3_2.h | 414 ------- .../include/CGAL/squared_distance_3_3.h | 126 --- .../CGAL/squared_distance_Line_3_Line_3.h | 61 + .../CGAL/squared_distance_Line_3_Plane_3.h | 85 ++ .../CGAL/squared_distance_Plane_3_Plane_3.h | 44 + .../CGAL/squared_distance_Point_3_Line_3.h | 75 ++ .../CGAL/squared_distance_Point_3_Plane_3.h | 73 ++ .../CGAL/squared_distance_Point_3_Point_3.h | 48 + .../CGAL/squared_distance_Point_3_Ray_3.h | 78 ++ .../CGAL/squared_distance_Point_3_Segment_3.h | 130 +++ .../squared_distance_Point_3_Tetrahedron_3.h | 148 +++ .../squared_distance_Point_3_Triangle_3.h | 125 ++ ...quared_distance_Point_3_Weighted_point_3.h | 47 + .../CGAL/squared_distance_Ray_3_Line_3.h | 97 ++ .../CGAL/squared_distance_Ray_3_Plane_3.h | 97 ++ .../CGAL/squared_distance_Ray_3_Ray_3.h | 131 +++ .../CGAL/squared_distance_Segment_3_Line_3.h | 117 ++ .../CGAL/squared_distance_Segment_3_Plane_3.h | 105 ++ .../CGAL/squared_distance_Segment_3_Ray_3.h | 194 ++++ .../squared_distance_Segment_3_Segment_3.h | 193 ++++ ...stance_Weighted_point_3_Weighted_point_3.h | 37 + .../test/Distance_3/test_distance_3.cpp | 695 +++++++++--- 26 files changed, 2614 insertions(+), 1812 deletions(-) rename Distance_3/include/CGAL/{squared_distance_3_0.h => internal/squared_distance_utils_3.h} (65%) delete mode 100644 Distance_3/include/CGAL/squared_distance_3_1.h delete mode 100644 Distance_3/include/CGAL/squared_distance_3_2.h delete mode 100644 Distance_3/include/CGAL/squared_distance_3_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Line_3_Line_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Line_3_Plane_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Plane_3_Plane_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Point_3_Line_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Point_3_Plane_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Point_3_Point_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Point_3_Ray_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Point_3_Segment_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Point_3_Tetrahedron_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Point_3_Triangle_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Point_3_Weighted_point_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Ray_3_Line_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Ray_3_Plane_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Ray_3_Ray_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Segment_3_Line_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Segment_3_Plane_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Segment_3_Ray_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h create mode 100644 Distance_3/include/CGAL/squared_distance_Weighted_point_3_Weighted_point_3.h diff --git a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h index 943cc686804..ac34f9564b1 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h @@ -457,6 +457,103 @@ namespace CartesianKernelFunctors { } }; + namespace internal { + + template + 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) + { + typedef typename K::Vector_3 Vector_3; + typedef typename K::RT RT; + typedef typename K::FT FT; + + typename K::Construct_vector_3 construct_vector; + + 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 CGAL::compare(d1*e2, d2*e1); + } + + template + 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) + { + typedef typename K::Vector_3 Vector_3; + typedef typename K::RT RT; + typedef typename K::FT FT; + + typename K::Construct_vector_3 construct_vector; + + 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 CGAL::compare(d1*e2, d2); + } + + } // namespace internal + template class Compare_distance_3 { @@ -476,19 +573,19 @@ namespace CartesianKernelFunctors { 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()); + return 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()); + return 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())); + return opposite(internal::compare_distance_ppsC3(p1,p2,s2, K())); } template diff --git a/Distance_3/include/CGAL/squared_distance_3_0.h b/Distance_3/include/CGAL/internal/squared_distance_utils_3.h similarity index 65% rename from Distance_3/include/CGAL/squared_distance_3_0.h rename to Distance_3/include/CGAL/internal/squared_distance_utils_3.h index 7b496c5967a..0160d5b5fda 100644 --- a/Distance_3/include/CGAL/squared_distance_3_0.h +++ b/Distance_3/include/CGAL/internal/squared_distance_utils_3.h @@ -12,42 +12,33 @@ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // -// Author(s) : Geert-Jan Giezeman, Andreas Fabri +// Author(s) : Geert-Jan Giezeman +#ifndef CGAL_SQUARED_DISTANCE_UTILS_3_H +#define CGAL_SQUARED_DISTANCE_UTILS_3_H -#ifndef CGAL_DISTANCE_3_0_H -#define CGAL_DISTANCE_3_0_H - -#include +#include #include +#include #include -#include -#include -#include -#include - namespace CGAL { - - namespace internal { template bool is_null(const typename K::Vector_3 &v, const K&) { - typedef typename K::RT RT; - return v.hx()==RT(0) && v.hy()==RT(0) && v.hz()==RT(0); + typedef typename K::RT RT; + return v.hx() == RT(0) && v.hy() == RT(0) && v.hz() == RT(0); } - - template typename K::RT wdot(const typename K::Vector_3 &u, const typename K::Vector_3 &v, const K&) { - return (u.hx()*v.hx() + u.hy()*v.hy() + u.hz()*v.hz()); + return (u.hx()*v.hx() + u.hy()*v.hy() + u.hz()*v.hz()); } template @@ -71,12 +62,12 @@ wdot_tag(const typename K::Point_3 &p, const K&, const Homogeneous_tag&) { - return ( (p.hx() * q.hw() - q.hx() * p.hw()) - * (r.hx() * q.hw() - q.hx() * r.hw()) - + (p.hy() * q.hw() - q.hy() * p.hw()) - * (r.hy() * q.hw() - q.hy() * r.hw()) - + (p.hz() * q.hw() - q.hz() * p.hw()) - * (r.hz() * q.hw() - q.hz() * r.hw())); + return ( (p.hx() * q.hw() - q.hx() * p.hw()) + * (r.hx() * q.hw() - q.hx() * r.hw()) + + (p.hy() * q.hw() - q.hy() * p.hw()) + * (r.hy() * q.hw() - q.hy() * r.hw()) + + (p.hz() * q.hw() - q.hz() * p.hw()) + * (r.hz() * q.hw() - q.hz() * r.hw())); } template @@ -92,9 +83,6 @@ wdot(const typename K::Point_3 &p, return wdot_tag(p, q, r, k, tag); } - - - template typename K::Vector_3 wcross(const typename K::Vector_3 &u, @@ -102,13 +90,12 @@ wcross(const typename K::Vector_3 &u, const K&) { typedef typename K::Vector_3 Vector_3; - return Vector_3( + return Vector_3( u.hy()*v.hz() - u.hz()*v.hy(), u.hz()*v.hx() - u.hx()*v.hz(), u.hx()*v.hy() - u.hy()*v.hx()); } - template inline bool @@ -116,8 +103,8 @@ is_acute_angle(const typename K::Vector_3 &u, const typename K::Vector_3 &v, const K& k) { - typedef typename K::RT RT; - return RT(wdot(u, v, k)) > RT(0) ; + typedef typename K::RT RT; + return RT(wdot(u, v, k)) > RT(0) ; } template @@ -127,8 +114,8 @@ is_straight_angle(const typename K::Vector_3 &u, const typename K::Vector_3 &v, const K& k) { - typedef typename K::RT RT; - return RT(wdot(u, v, k)) == RT(0) ; + typedef typename K::RT RT; + return RT(wdot(u, v, k)) == RT(0) ; } template @@ -138,8 +125,8 @@ is_obtuse_angle(const typename K::Vector_3 &u, const typename K::Vector_3 &v, const K& k) { - typedef typename K::RT RT; - return RT(wdot(u, v, k)) < RT(0) ; + typedef typename K::RT RT; + return RT(wdot(u, v, k)) < RT(0) ; } template @@ -150,8 +137,8 @@ is_acute_angle(const typename K::Point_3 &p, const typename K::Point_3 &r, const K& k) { - typedef typename K::RT RT; - return RT(wdot(p, q, r, k)) > RT(0) ; + typedef typename K::RT RT; + return RT(wdot(p, q, r, k)) > RT(0) ; } template @@ -162,8 +149,8 @@ is_straight_angle(const typename K::Point_3 &p, const typename K::Point_3 &r, const K& k) { - typedef typename K::RT RT; - return RT(wdot(p, q, r, k)) == RT(0) ; + typedef typename K::RT RT; + return RT(wdot(p, q, r, k)) == RT(0) ; } template @@ -172,21 +159,11 @@ bool is_obtuse_angle(const typename K::Point_3 &p, const typename K::Point_3 &q, const typename K::Point_3 &r, - const K& k) + const K& k) { - typedef typename K::RT RT; - return RT(wdot(p, q, r, k)) < RT(0) ; + typedef typename K::RT RT; + return RT(wdot(p, q, r, k)) < RT(0) ; } -template -inline -typename K::FT -squared_distance(const typename K::Point_3 & pt1, - const typename K::Point_3 & pt2, - const K& k) -{ - return k.compute_squared_distance_3_object()(pt1, pt2); -} - template typename K::FT @@ -199,11 +176,9 @@ squared_distance_to_plane(const typename K::Vector_3 & normal, RT dot, squared_length; dot = wdot(normal, diff, k); squared_length = wdot(normal, normal, k); - return FT(dot*dot) / - FT(wmult((K*)0, squared_length, diff.hw(), diff.hw())); + return FT(dot*dot) / FT(wmult((K*)0, squared_length, diff.hw(), diff.hw())); } - template typename K::FT squared_distance_to_line(const typename K::Vector_3 & dir, @@ -214,11 +189,9 @@ squared_distance_to_line(const typename K::Vector_3 & dir, typedef typename K::RT RT; typedef typename K::FT FT; Vector_3 wcr = wcross(dir, diff, k); - return FT(wcr*wcr)/FT(wmult( - (K*)0, RT(wdot(dir, dir, k)), diff.hw(), diff.hw())); + return FT(wcr*wcr)/FT(wmult((K*)0, RT(wdot(dir, dir, k)), diff.hw(), diff.hw())); } - template inline bool @@ -246,7 +219,6 @@ same_direction_tag(const typename K::Vector_3 &u, } } - template inline bool @@ -274,7 +246,6 @@ same_direction_tag(const typename K::Vector_3 &u, } } - template inline bool @@ -287,70 +258,19 @@ same_direction(const typename K::Vector_3 &u, return same_direction_tag(u, v, k, tag); } +template +inline +typename K::RT +distance_measure_sub(typename K::RT startwdist, typename K::RT endwdist, + const typename K::Vector_3 &start, + const typename K::Vector_3 &end, + const K&) +{ + return CGAL_NTS abs(wmult((K*)0, startwdist, end.hw())) - + CGAL_NTS abs(wmult((K*)0, endwdist, start.hw())); +} } // namespace internal +} // namespace CGAL -template -inline -typename K::FT -squared_distance(const Point_3 & pt1, - const Point_3 & pt2) -{ - return internal::squared_distance(pt1,pt2, K()); -} - - -template -inline -typename K::FT -squared_distance(const Weighted_point_3 & pt1, - const Weighted_point_3 & pt2) -{ - return internal::squared_distance(pt1.point(),pt2.point(), K()); -} - -template -inline -typename K::FT -squared_distance(const Weighted_point_3 & pt1, - const Point_3 & pt2) -{ - return internal::squared_distance(pt1.point(),pt2, K()); -} - -template -inline -typename K::FT -squared_distance(const Point_3 & pt1, - const Weighted_point_3 & pt2) -{ - return internal::squared_distance(pt1,pt2.point(), K()); -} - - - -template -inline -typename K::FT -squared_distance_to_plane(const Vector_3 & normal, - const Vector_3 & diff) -{ - return internal::squared_distance_to_plane(normal, diff, K()); -} - - -template -inline -typename K::FT -squared_distance_to_line(const Vector_3 & dir, - const Vector_3 & diff) -{ - return internal::squared_distance_to_line(dir, diff, K()); -} - - - -} //namespace CGAL - - -#endif +#endif // CGAL_SQUARED_DISTANCE_UTILS_3_H diff --git a/Distance_3/include/CGAL/squared_distance_3.h b/Distance_3/include/CGAL/squared_distance_3.h index b55542f5e7f..bbd90d2d394 100644 --- a/Distance_3/include/CGAL/squared_distance_3.h +++ b/Distance_3/include/CGAL/squared_distance_3.h @@ -18,9 +18,29 @@ #ifndef CGAL_DISTANCE_3_H #define CGAL_DISTANCE_3_H -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include -#endif +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#endif // CGAL_DISTANCE_3_H diff --git a/Distance_3/include/CGAL/squared_distance_3_1.h b/Distance_3/include/CGAL/squared_distance_3_1.h deleted file mode 100644 index e0e63a6fb23..00000000000 --- a/Distance_3/include/CGAL/squared_distance_3_1.h +++ /dev/null @@ -1,1007 +0,0 @@ -// Copyright (c) 1998-2004 -// Utrecht University (The Netherlands), -// ETH Zurich (Switzerland), -// INRIA Sophia-Antipolis (France), -// Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. -// -// This file is part of CGAL (www.cgal.org) -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Geert-Jan Giezeman, Andreas Fabri - - -#ifndef CGAL_DISTANCE_3_1_H -#define CGAL_DISTANCE_3_1_H - - -#include - -#include -#include -#include - - -namespace CGAL { - -namespace internal { - -template -typename K::FT -squared_distance( - const typename K::Point_3 &pt, - const typename K::Line_3 &line, - const K& k) -{ - typedef typename K::Vector_3 Vector_3; - typename K::Construct_vector_3 construct_vector; - Vector_3 dir(line.direction().vector()); - Vector_3 diff = construct_vector(line.point(), pt); - return internal::squared_distance_to_line(dir, diff, k); -} - -template -inline -typename K::FT -squared_distance( - const typename K::Line_3 & line, - const typename K::Point_3 & pt, - const K& k) -{ - return squared_distance(pt, line, k); -} - - -template -typename K::FT -squared_distance( - const typename K::Point_3 &pt, - const typename K::Ray_3 &ray, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Vector_3 Vector_3; - - Vector_3 diff = construct_vector(ray.source(), pt); - const Vector_3 &dir = ray.direction().vector(); - if (!is_acute_angle(dir,diff, k) ) - return (typename K::FT)(diff*diff); - return squared_distance_to_line(dir, diff, k); -} - - -template -inline -typename K::FT -squared_distance( - const typename K::Ray_3 & ray, - const typename K::Point_3 & pt, - const K& k) -{ - return squared_distance(pt, ray, k); -} - - - - -template -typename K::FT -squared_distance( - const typename K::Point_3 &pt, - const typename K::Segment_3 &seg, - const K& k, - const Homogeneous_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; - // assert that the segment is valid (non zero length). - 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) - return (FT(diff*diff)); - RT e = wdot(segvec,segvec, k); - if ( (d * segvec.hw()) > (e * diff.hw())) - return squared_distance(pt, seg.target(), k); - - Vector_3 wcr = wcross(segvec, diff, k); - return FT(wcr*wcr)/FT(e * diff.hw() * diff.hw()); -} - -template -typename K::FT -squared_distance( - const typename K::Point_3 &pt, - 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; - // assert that the segment is valid (non zero length). - 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) - return (FT(diff*diff)); - RT e = wdot(segvec,segvec, k); - if (d > e) - return squared_distance(pt, seg.target(), k); - - Vector_3 wcr = wcross(segvec, diff, k); - return FT(wcr*wcr)/e; -} - - -template -inline -typename K::FT -squared_distance( - const typename K::Point_3 &pt, - const typename K::Segment_3 &seg, - const K& k) -{ - typedef typename K::Kernel_tag Tag; - Tag tag; - return squared_distance(pt, seg, k, tag); -} - - -template -inline -typename K::FT -squared_distance( - const typename K::Segment_3 & seg, - const typename K::Point_3 & pt, - const K& k) -{ - return squared_distance(pt, seg, k); -} - - - -template -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 CGAL::compare(d1*e2, d2*e1); -} - -template -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 CGAL::compare(d1*e2, d2); -} - - -template -typename K::FT -squared_distance_parallel( - const typename K::Segment_3 &seg1, - const typename K::Segment_3 &seg2, - const K& k) -{ - typedef typename K::Vector_3 Vector_3; - const Vector_3 &dir1 = seg1.direction().vector(); - const Vector_3 &dir2 = seg2.direction().vector(); - - if (same_direction(dir1, dir2, k)) { - if (!is_acute_angle(seg1.source(), seg1.target(), seg2.source(), k)) - return squared_distance(seg1.target(), seg2.source(), k); - if (!is_acute_angle(seg1.target(), seg1.source(), seg2.target(), k)) - return squared_distance(seg1.source(), seg2.target(), k); - } else { - if (!is_acute_angle(seg1.source(), seg1.target(), seg2.target(), k)) - return squared_distance(seg1.target(), seg2.target(), k); - if (!is_acute_angle(seg1.target(), seg1.source(), seg2.source(), k)) - return squared_distance(seg1.source(), seg2.source(), k); - } - return squared_distance(seg2.source(), seg1.supporting_line(), k); -} - - - -template -inline -typename K::RT -_distance_measure_sub(typename K::RT startwdist, typename K::RT endwdist, - const typename K::Vector_3 &start, - const typename K::Vector_3 &end, - const K&) -{ - return CGAL_NTS abs(wmult((K*)0, startwdist, end.hw())) - - CGAL_NTS abs(wmult((K*)0, endwdist, start.hw())); -} - - -template -typename K::FT -squared_distance( - 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::Point_3 Point_3; - typedef typename K::RT RT; - typedef typename K::FT FT; - const Point_3 &start1 = seg1.source(); - const Point_3 &start2 = seg2.source(); - const Point_3 &end1 = seg1.target(); - const Point_3 &end2 = seg2.target(); - - if (start1 == end1) - return squared_distance(start1, seg2, k); - if (start2 == end2) - return squared_distance(start2, seg1, k); - - Vector_3 dir1, dir2, normal; - dir1 = seg1.direction().vector(); - dir2 = seg2.direction().vector(); - normal = wcross(dir1, dir2, k); - if (is_null(normal, k)) - return squared_distance_parallel(seg1, seg2, k); - - bool crossing1, crossing2; - RT sdm_s1to2, sdm_e1to2, sdm_s2to1, sdm_e2to1; - Vector_3 perpend1, perpend2, s2mins1, e2mins1, e1mins2; - perpend1 = wcross(dir1, normal, k); - perpend2 = wcross(dir2, normal, k); - s2mins1 = construct_vector(start1, start2); - e2mins1 = construct_vector(start1, end2); - e1mins2 = construct_vector(start2, end1); - sdm_s1to2 = -RT(wdot(perpend2, s2mins1, k)); - sdm_e1to2 = wdot(perpend2, e1mins2, k); - sdm_s2to1 = wdot(perpend1, s2mins1, k); - sdm_e2to1 = wdot(perpend1, e2mins1, k); - - if (sdm_s1to2 < RT(0)) { - crossing1 = (sdm_e1to2 >= RT(0)); - } else { - if (sdm_e1to2 <= RT(0)) { - crossing1 = true; - } else { - crossing1 = (sdm_s1to2 == RT(0)); - } - } - if (sdm_s2to1 < RT(0)) { - crossing2 = (sdm_e2to1 >= RT(0)); - } else { - if (sdm_e2to1 <= RT(0)) { - crossing2 = true; - } else { - crossing2 = (sdm_s2to1 == RT(0)); - } - } - - if (crossing1) { - if (crossing2) { - return squared_distance_to_plane(normal, s2mins1, k); - } - - RT dm; - dm = _distance_measure_sub( - sdm_s2to1, sdm_e2to1, s2mins1, e2mins1, k); - if (dm < RT(0)) { - return squared_distance(start2, seg1, k); - } else { - if (dm > RT(0)) { - return squared_distance(end2, seg1, k); - } else { - // should not happen with exact arithmetic. - return squared_distance_parallel(seg1, seg2, k); - } - } - } else { - if (crossing2) { - RT dm; - dm =_distance_measure_sub( - sdm_s1to2, sdm_e1to2, s2mins1, e1mins2, k); - if (dm < RT(0)) { - return squared_distance(start1, seg2, k); - } else { - if (dm > RT(0)) { - return squared_distance(end1, seg2, k); - } else { - // should not happen with exact arithmetic. - return squared_distance_parallel(seg1, seg2, k); - } - } - } else { - FT min1, min2; - RT dm; - dm = _distance_measure_sub( - sdm_s1to2, sdm_e1to2, s2mins1, e1mins2, k); - if (dm == RT(0)) // should not happen with exact arithmetic. - return squared_distance_parallel(seg1, seg2, k); - min1 = (dm < RT(0)) ? - squared_distance(seg1.source(), seg2, k): - squared_distance(end1, seg2, k); - dm = _distance_measure_sub( - sdm_s2to1, sdm_e2to1, s2mins1, e2mins1, k); - if (dm == RT(0)) // should not happen with exact arithmetic. - return squared_distance_parallel(seg1, seg2, k); - min2 = (dm < RT(0)) ? - squared_distance(start2, seg1, k): - squared_distance(end2, seg1, k); - return (min1 < min2) ? min1 : min2; - } - } - -} - - - - - - -template -typename K::FT -squared_distance_parallel( - const typename K::Segment_3 &seg, - const typename K::Ray_3 &ray, - const K& k) -{ - - typedef typename K::Vector_3 Vector_3; - bool same_direction; - const Vector_3 &dir1 = seg.direction().vector(); - const Vector_3 &dir2 = ray.direction().vector(); - if (CGAL_NTS abs(dir1.hx()) > CGAL_NTS abs(dir1.hy())) { - same_direction = (CGAL_NTS sign(dir1.hx()) == CGAL_NTS sign(dir2.hx())); - } else { - same_direction = (CGAL_NTS sign(dir1.hy()) == CGAL_NTS sign(dir2.hy())); - } - if (same_direction) { - if (!is_acute_angle(seg.source(), seg.target(), ray.source(), k)) - return squared_distance(seg.target(), ray.source(), k); - } else { - if (!is_acute_angle(seg.target(), seg.source(), ray.source(), k)) - return squared_distance(seg.source(), ray.source(), k); - } - return squared_distance(ray.source(), seg.supporting_line(), k); -} - - -template -typename K::FT -squared_distance( - const typename K::Segment_3 &seg, - const typename K::Ray_3 &ray, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Point_3 Point_3; - typedef typename K::Vector_3 Vector_3; - typedef typename K::RT RT; - typedef typename K::FT FT; - const Point_3 & ss = seg.source(); - const Point_3 & se = seg.target(); - if (ss == se) - return squared_distance(ss, ray, k); - Vector_3 raydir, segdir, normal; - raydir = ray.direction().vector(); - segdir = seg.direction().vector(); - normal = wcross(segdir, raydir, k); - if (is_null(normal, k)) - return squared_distance_parallel(seg, ray, k); - - bool crossing1, crossing2; - RT sdm_ss2r, sdm_se2r, sdm_rs2s, sdm_re2s; - Vector_3 perpend2seg, perpend2ray, ss_min_rs, se_min_rs; - perpend2seg = wcross(segdir, normal, k); - perpend2ray = wcross(raydir, normal, k); - ss_min_rs = construct_vector(ray.source(), ss); - se_min_rs = construct_vector(ray.source(), se); - sdm_ss2r = wdot(perpend2ray, ss_min_rs, k); - sdm_se2r = wdot(perpend2ray, se_min_rs, k); - if (sdm_ss2r < RT(0)) { - crossing1 = (sdm_se2r >= RT(0)); - } else { - if (sdm_se2r <= RT(0)) { - crossing1 = true; - } else { - crossing1 = (sdm_ss2r == RT(0)); - } - } - - sdm_rs2s = -RT(wdot(perpend2seg, ss_min_rs, k)); - sdm_re2s = wdot(perpend2seg, raydir, k); - if (sdm_rs2s < RT(0)) { - crossing2 = (sdm_re2s >= RT(0)); - } else { - if (sdm_re2s <= RT(0)) { - crossing2 = true; - } else { - crossing2 = (sdm_rs2s == RT(0)); - } - } - - if (crossing1) { - if (crossing2) { - return squared_distance_to_plane(normal, ss_min_rs, k); - } - return squared_distance(ray.source(), seg, k); - } else { - if (crossing2) { - RT dm; - dm = _distance_measure_sub( - sdm_ss2r, sdm_se2r, ss_min_rs, se_min_rs, k); - if (dm < RT(0)) { - return squared_distance(ss, ray, k); - } else { - if (dm > RT(0)) { - return squared_distance(se, ray, k); - } else { - // parallel, should not happen (no crossing) - return squared_distance_parallel(seg, ray, k); - } - } - } else { - FT min1, min2; - RT dm; - dm = _distance_measure_sub( - sdm_ss2r, sdm_se2r, ss_min_rs, se_min_rs, k); - if (dm == RT(0)) - return squared_distance_parallel(seg, ray, k); - min1 = (dm < RT(0)) - ? squared_distance(ss, ray, k) - : squared_distance(se, ray, k); - min2 = squared_distance(ray.source(), seg, k); - return (min1 < min2) ? min1 : min2; - } - } -} - - - -template -inline -typename K::FT -squared_distance( - const typename K::Ray_3 & ray, - const typename K::Segment_3 & seg, - const K& k) -{ - return squared_distance(seg, ray, k); -} - - -template -typename K::FT -squared_distance( - const typename K::Segment_3 &seg, - const typename K::Line_3 &line, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Vector_3 Vector_3; - typedef typename K::Point_3 Point_3; - typedef typename K::RT RT; - const Point_3 &linepoint = line.point(); - const Point_3 &start = seg.source(); - const Point_3 &end = seg.target(); - - if (start == end) - return squared_distance(start, line, k); - Vector_3 linedir = line.direction().vector(); - Vector_3 segdir = seg.direction().vector(); - Vector_3 normal = wcross(segdir, linedir, k); - if (is_null(normal, k)) - return squared_distance_to_line(linedir, - construct_vector(linepoint,start), k); - - bool crossing; - RT sdm_ss2l, sdm_se2l; - Vector_3 perpend2line, start_min_lp, end_min_lp; - perpend2line = wcross(linedir, normal, k); - start_min_lp = construct_vector(linepoint, start); - end_min_lp = construct_vector(linepoint, end); - sdm_ss2l = wdot(perpend2line, start_min_lp, k); - sdm_se2l = wdot(perpend2line, end_min_lp, k); - if (sdm_ss2l < RT(0)) { - crossing = (sdm_se2l >= RT(0)); - } else { - if (sdm_se2l <= RT(0)) { - crossing = true; - } else { - crossing = (sdm_ss2l == RT(0)); - } - } - - if (crossing) { - return squared_distance_to_plane(normal, start_min_lp, k); - } else { - RT dm; - dm = _distance_measure_sub( - sdm_ss2l, sdm_se2l, start_min_lp, end_min_lp, k); - if (dm <= RT(0)) { - return squared_distance_to_line(linedir, start_min_lp, k); - } else { - return squared_distance_to_line(linedir, end_min_lp, k); - } - } -} - - -template -inline -typename K::FT -squared_distance( - const typename K::Line_3 & line, - const typename K::Segment_3 & seg, - const K& k) -{ - return squared_distance(seg, line, k); -} - - - - -template -typename K::FT -ray_ray_squared_distance_parallel( - const typename K::Vector_3 &ray1dir, - const typename K::Vector_3 &ray2dir, - const typename K::Vector_3 &s1_min_s2, - const K& k) -{ - if (!is_acute_angle(ray2dir, s1_min_s2, k)) { - if (!same_direction(ray1dir, ray2dir, k)) - return (typename K::FT)(s1_min_s2*s1_min_s2); - } - return squared_distance_to_line(ray1dir, s1_min_s2, k); -} - - -template -typename K::FT -squared_distance( - const typename K::Ray_3 &ray1, - const typename K::Ray_3 &ray2, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Vector_3 Vector_3; - typedef typename K::Point_3 Point_3; - typedef typename K::RT RT; - typedef typename K::FT FT; - const Point_3 & s1 = ray1.source(); - const Point_3 & s2 = ray2.source(); - Vector_3 dir1, dir2, normal; - dir1 = ray1.direction().vector(); - dir2 = ray2.direction().vector(); - normal = wcross(dir1, dir2, k); - Vector_3 s1_min_s2 = construct_vector(s2, s1); - if (is_null(normal, k)) - return ray_ray_squared_distance_parallel(dir1, dir2, s1_min_s2, k); - - bool crossing1, crossing2; - RT sdm_s1_2, sdm_s2_1; - Vector_3 perpend1, perpend2; - perpend1 = wcross(dir1, normal, k); - perpend2 = wcross(dir2, normal, k); - - sdm_s1_2 = wdot(perpend2, s1_min_s2, k); - if (sdm_s1_2 < RT(0)) { - crossing1 = (RT(wdot(perpend2, dir1, k)) >= RT(0)); - } else { - if (RT(wdot(perpend2, dir1, k)) <= RT(0)) { - crossing1 = true; - } else { - crossing1 = (sdm_s1_2 == RT(0)); - } - } - sdm_s2_1 = -RT(wdot(perpend1, s1_min_s2, k)); - if (sdm_s2_1 < RT(0)) { - crossing2 = (RT(wdot(perpend1, dir2, k)) >= RT(0)); - } else { - if (RT(wdot(perpend1, dir2, k)) <= RT(0)) { - crossing2 = true; - } else { - crossing2 = (sdm_s2_1 == RT(0)); - } - } - if (crossing1) { - if (crossing2) - return squared_distance_to_plane(normal, s1_min_s2, k); - return squared_distance(ray2.source(), ray1, k); - } else { - if (crossing2) { - return squared_distance(ray1.source(), ray2, k); - } else { - FT min1, min2; - min1 = squared_distance(ray1.source(), ray2, k); - min2 = squared_distance(ray2.source(), ray1, k); - return (min1 < min2) ? min1 : min2; - } - } -} - - - - - -template -typename K::FT -squared_distance( - const typename K::Line_3 &line, - const typename K::Ray_3 &ray, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Vector_3 Vector_3; - typedef typename K::Point_3 Point_3; - typedef typename K::RT RT; - const Point_3 & rs =ray.source(); - Vector_3 raydir, linedir, normal; - linedir = line.direction().vector(); - raydir = ray.direction().vector(); - normal = wcross(raydir, linedir, k); - Vector_3 rs_min_lp = construct_vector(line.point(), rs); - if (is_null(normal, k)) - return squared_distance_to_line(linedir, rs_min_lp, k); - - bool crossing; - RT sdm_sr_l; - Vector_3 perpend2l; - perpend2l = wcross(linedir, normal, k); - - sdm_sr_l = wdot(perpend2l, rs_min_lp, k); - if (sdm_sr_l < RT(0)) { - crossing = (RT(wdot(perpend2l, raydir, k)) >= RT(0)); - } else { - if (RT(wdot(perpend2l, raydir, k)) <= RT(0)) { - crossing = true; - } else { - crossing = (sdm_sr_l == RT(0)); - } - } - - if (crossing) - return squared_distance_to_plane(normal, rs_min_lp, k); - else - return squared_distance_to_line(linedir, rs_min_lp, k); -} - - -template -inline typename K::FT -squared_distance( - const typename K::Ray_3 & ray, - const typename K::Line_3 & line, - const K& k) -{ - return squared_distance(line, ray, k); -} - - - - -template -typename K::FT -squared_distance( - const typename K::Line_3 &line1, - const typename K::Line_3 &line2, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Vector_3 Vector_3; - - Vector_3 dir1, dir2, normal, diff; - dir1 = line1.direction().vector(); - dir2 = line2.direction().vector(); - normal = wcross(dir1, dir2, k); - diff = construct_vector(line1.point(), line2.point()); - if (is_null(normal, k)) - return squared_distance_to_line(dir2, diff, k); - return squared_distance_to_plane(normal, diff, k); -} - - - -} // namespace internal - - - -template -inline -typename K::FT -squared_distance(const Point_3 &pt, - const Line_3 &line) -{ - return internal::squared_distance(pt, line, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Line_3 & line, - const Point_3 & pt) -{ - return internal::squared_distance(pt, line, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Point_3 &pt, - const Ray_3 &ray) -{ - return internal::squared_distance(pt, ray, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Ray_3 & ray, - const Point_3 & pt) -{ - return internal::squared_distance(pt, ray, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Point_3 &pt, - const Segment_3 &seg) -{ - return internal::squared_distance(pt, seg, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Segment_3 & seg, - const Point_3 & pt) -{ - return internal::squared_distance(pt, seg, K()); -} - - - - -template -inline -typename K::FT -squared_distance_parallel( - const Segment_3 &seg1, - const Segment_3 &seg2) -{ - return internal::squared_distance_parallel(seg1, seg2, K()); -} - - - - -template -inline -typename K::FT -squared_distance(const Segment_3 &seg1, - const Segment_3 &seg2) -{ - return internal::squared_distance(seg1, seg2, K()); -} - - - - - - -template -inline -typename K::FT -squared_distance_parallel( - const Segment_3 &seg, - const Ray_3 &ray) -{ - return internal::squared_distance_parallel(ray,seg, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Segment_3 &seg, - const Ray_3 &ray) -{ - return internal::squared_distance(ray, seg, K()); -} - - - -template -inline -typename K::FT -squared_distance( - const Ray_3 & ray, - const Segment_3 & seg) -{ - return internal::squared_distance(seg, ray, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Segment_3 &seg, - const Line_3 &line) -{ - return internal::squared_distance(seg, line, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Line_3 & line, - const Segment_3 & seg) -{ - return internal::squared_distance(seg, line, K()); -} - - - - -template -inline -typename K::FT -ray_ray_squared_distance_parallel( - const Vector_3 &ray1dir, - const Vector_3 &ray2dir, - const Vector_3 &s1_min_s2) -{ - return internal::ray_ray_squared_distance_parallel(ray1dir, ray2dir, - s1_min_s2, K()); -} - -template -inline -typename K::FT -squared_distance( - const Ray_3 &ray1, - const Ray_3 &ray2) -{ - return internal::squared_distance(ray1, ray2, K()); -} - - - - - -template -inline -typename K::FT -squared_distance( - const Line_3 &line, - const Ray_3 &ray) -{ - return internal::squared_distance(line, ray, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Ray_3 & ray, - const Line_3 & line) -{ - return internal::squared_distance(line, ray, K()); -} - - - - -template -inline -typename K::FT -squared_distance( - const Line_3 &line1, - const Line_3 &line2) -{ - return internal::squared_distance(line1, line2, K()); -} - - -} //namespace CGAL - - -#endif diff --git a/Distance_3/include/CGAL/squared_distance_3_2.h b/Distance_3/include/CGAL/squared_distance_3_2.h deleted file mode 100644 index 78af20db08f..00000000000 --- a/Distance_3/include/CGAL/squared_distance_3_2.h +++ /dev/null @@ -1,414 +0,0 @@ -// Copyright (c) 1998-2004 -// Utrecht University (The Netherlands), -// ETH Zurich (Switzerland), -// INRIA Sophia-Antipolis (France), -// Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. -// -// This file is part of CGAL (www.cgal.org) -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Geert-Jan Giezeman, Andreas Fabri - - -#ifndef CGAL_DISTANCE_3_2_H -#define CGAL_DISTANCE_3_2_H - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace CGAL { - -namespace internal { - -template -bool -contains_vector(const typename K::Plane_3 &pl, - const typename K::Vector_3 &vec, - const K&) -{ - typedef typename K::RT RT; - return pl.a()*vec.hx() + pl.b()*vec.hy() + pl.c() * vec.hz() == RT(0); -} - - -template -inline typename K::FT -squared_distance( - const typename K::Point_3 & pt, - const typename K::Plane_3 & plane, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Vector_3 Vector_3; - Vector_3 diff = construct_vector(plane.point(), pt); - return squared_distance_to_plane(plane.orthogonal_vector(), diff, k); -} - - - -template -inline typename K::FT -squared_distance( - const typename K::Plane_3 & plane, - const typename K::Point_3 & pt, - const K& k) -{ - return squared_distance(pt, plane, k); -} - -template -typename K::FT -squared_distance( - const typename K::Line_3 &line, - const typename K::Plane_3 &plane, - const K& k) -{ - typedef typename K::FT FT; - if (contains_vector(plane, line.direction().vector(), k)) - return squared_distance(plane, line.point(), k); - return FT(0); -} - - -template -inline typename K::FT -squared_distance( - const typename K::Plane_3 & p, - const typename K::Line_3 & line, - const K& k) -{ - return squared_distance(line, p, k); -} - -template -typename K::FT -squared_distance( - const typename K::Ray_3 &ray, - const typename K::Plane_3 &plane, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Point_3 Point_3; - typedef typename K::Vector_3 Vector_3; - typedef typename K::RT RT; - typedef typename K::FT FT; - const Point_3 &start = ray.start(); - const Point_3 &planepoint = plane.point(); - Vector_3 start_min_pp = construct_vector(planepoint, start); - Vector_3 end_min_pp = ray.direction().vector(); - const Vector_3 &normal = plane.orthogonal_vector(); - RT sdm_rs2pp = wdot(normal, start_min_pp, k); - RT sdm_re2pp = wdot(normal, end_min_pp, k); - switch (CGAL_NTS sign(sdm_rs2pp)) { - case -1: - if (sdm_re2pp > RT(0)) - return FT(0); - return squared_distance_to_plane(normal, start_min_pp, k); - case 0: - default: - return FT(0); - case 1: - if (sdm_re2pp < RT(0)) - return FT(0); - return squared_distance_to_plane(normal, start_min_pp, k); - } -} - - -template -inline typename K::FT -squared_distance( - const typename K::Plane_3 & plane, - const typename K::Ray_3 & ray, - const K& k) -{ - return squared_distance(ray, plane, k); -} - -template -typename K::FT -squared_distance( - const typename K::Segment_3 &seg, - const typename K::Plane_3 &plane, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Point_3 Point_3; - typedef typename K::Vector_3 Vector_3; - typedef typename K::RT RT; - typedef typename K::FT FT; - const Point_3 &start = seg.start(); - const Point_3 &end = seg.end(); - if (start == end) - return squared_distance(start, plane, k); - const Point_3 &planepoint = plane.point(); - Vector_3 start_min_pp = construct_vector(planepoint, start); - Vector_3 end_min_pp = construct_vector(planepoint, end); - const Vector_3 &normal = plane.orthogonal_vector(); - RT sdm_ss2pp = wdot(normal, start_min_pp, k); - RT sdm_se2pp = wdot(normal, end_min_pp, k); - switch (CGAL_NTS sign(sdm_ss2pp)) { - case -1: - if (sdm_se2pp >= RT(0)) - return FT(0); - if (sdm_ss2pp * end_min_pp.hw() >= sdm_se2pp * start_min_pp.hw()) - return squared_distance_to_plane(normal, start_min_pp, k); - else - return squared_distance_to_plane(normal, end_min_pp, k); - case 0: - default: - return FT(0); - case 1: - if (sdm_se2pp <= RT(0)) - return FT(0); - if (sdm_ss2pp * end_min_pp.hw() <= sdm_se2pp * start_min_pp.hw()) - return squared_distance_to_plane(normal, start_min_pp, k); - else - return squared_distance_to_plane(normal, end_min_pp, k); - } -} - - -template -inline typename K::FT -squared_distance( - const typename K::Plane_3 & plane, - const typename K::Segment_3 & seg, - const K& k) -{ - return squared_distance(seg, plane, k); -} - - -template -inline bool -on_left_of_triangle_edge(const typename K::Point_3 & pt, - const typename K::Vector_3 & normal, - const typename K::Point_3 & ep0, - const typename K::Point_3 & ep1, - const K& k) -{ - // return true iff pt is on the negative side of the plane defined - // by (ep0, ep1) and normal - typename K::Construct_vector_3 vector; - typename K::Vector_3 edge = vector(ep0, ep1); - typename K::Vector_3 diff = vector(ep0, pt); - - typedef typename K::RT RT; - - const bool result = - RT(wdot(wcross(edge, - normal, - k), - diff, - k)) <= RT(0); - return result; -} - -template -inline typename K::FT -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, - bool & inside, - const K& k) -{ - typename K::Construct_vector_3 vector; - typedef typename K::Vector_3 Vector_3; - 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 - && on_left_of_triangle_edge(pt, normal, t0, t1, k) - && on_left_of_triangle_edge(pt, normal, t1, t2, k) - && on_left_of_triangle_edge(pt, normal, t2, t0, k)) - { - // the projection of pt is inside the triangle - inside = true; - return squared_distance_to_plane(normal, vector(t0, pt), k); - } - else { - // 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. - typename K::FT d1 = squared_distance(pt, - typename K::Segment_3(t2, t0), - k); - typename K::FT d2 = squared_distance(pt, - typename K::Segment_3(t1, t2), - k); - typename K::FT d3 = squared_distance(pt, - typename K::Segment_3(t0, t1), - k); - - return (std::min)( (std::min)(d1, d2), d3); - } -} - -template -inline typename K::FT -squared_distance( - const typename K::Point_3 & pt, - const typename K::Triangle_3 & t, - const K& k) -{ - typename K::Construct_vertex_3 vertex; - bool inside = false; - return squared_distance_to_triangle(pt, - vertex(t, 0), - vertex(t, 1), - vertex(t, 2), - inside, - k); -} - -} // namespace internal - - -template -bool -contains_vector(const Plane_3 &pl, const Vector_3 &vec) -{ - return internal::contains_vector(pl,vec, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Point_3 & pt, - const Plane_3 & plane) -{ - return internal::squared_distance(pt, plane, K()); -} - - - -template -inline -typename K::FT -squared_distance( - const Plane_3 & plane, - const Point_3 & pt) -{ - return internal::squared_distance(pt, plane, K()); -} - -template -inline -typename K::FT -squared_distance( - const Line_3 &line, - const Plane_3 &plane) -{ - return internal::squared_distance(line, plane, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Plane_3 & p, - const Line_3 & line) -{ - return internal::squared_distance(line, p, K()); -} - -template -inline -typename K::FT -squared_distance( - const Ray_3 &ray, - const Plane_3 &plane) -{ - return internal::squared_distance(ray, plane, K()); -} - - - -template -inline -typename K::FT -squared_distance( - const Plane_3 & plane, - const Ray_3 & ray) -{ - return internal::squared_distance(ray, plane, K()); -} - -template -inline -typename K::FT -squared_distance( - const Segment_3 &seg, - const Plane_3 &plane) -{ - return internal::squared_distance(seg, plane, K()); - -} - - -template -inline -typename K::FT -squared_distance( - const Plane_3 & plane, - const Segment_3 & seg) -{ - return internal::squared_distance(seg, plane, K()); -} - -template -inline -typename K::FT -squared_distance(const Point_3 & pt, - const Triangle_3 & t) { - return internal::squared_distance(pt, t, K()); -} - - -template -inline -typename K::FT -squared_distance(const Triangle_3 & t, - const Point_3 & pt) { - return internal::squared_distance(pt, t, K()); -} - - -template -inline -typename K::FT -squared_distance(const Plane_3 & p1, - const Plane_3 & p2) { - K k; - typename K::Construct_orthogonal_vector_3 ortho_vec = - k.construct_orthogonal_vector_3_object(); - if (!internal::is_null(internal::wcross(ortho_vec(p1), ortho_vec(p2), k), k)) - return typename K::FT(0); - else - return internal::squared_distance(p1.point(), p2, k); -} - -} //namespace CGAL - - -#endif diff --git a/Distance_3/include/CGAL/squared_distance_3_3.h b/Distance_3/include/CGAL/squared_distance_3_3.h deleted file mode 100644 index 8f2987a0d5f..00000000000 --- a/Distance_3/include/CGAL/squared_distance_3_3.h +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) 1998-2021 -// Utrecht University (The Netherlands), -// ETH Zurich (Switzerland), -// INRIA Sophia-Antipolis (France), -// Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. -// -// This file is part of CGAL (www.cgal.org) -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Geert-Jan Giezeman, Andreas Fabri - - -#ifndef CGAL_DISTANCE_3_3_H -#define CGAL_DISTANCE_3_3_H - -#include - -#include -#include - -namespace CGAL { - -namespace internal { - -template -inline -typename K::FT -squared_distance(const typename K::Tetrahedron_3 & t, - const typename K::Point_3 & pt, - const K& k) -{ - bool on_bounded_side = true; - const typename K::Point_3 t0 = t[0]; - const typename K::Point_3 t1 = t[1]; - const typename K::Point_3 t2 = t[2]; - const typename K::Point_3 t3 = t[3]; - - bool dmin_initialized = false; - typename K::FT dmin; - bool inside = false; - if(orientation(t0,t1,t2, pt) == NEGATIVE){ - on_bounded_side = false; - dmin = squared_distance_to_triangle(pt, t0, t1, t2, inside, k); - dmin_initialized = true; - if(inside){ - return dmin; - } - } - - if(orientation(t0,t3,t1, pt) == NEGATIVE){ - on_bounded_side = false; - const typename K::FT d = squared_distance_to_triangle(pt, t0, t3, t1, inside, k); - if(inside){ - return d; - } - if(! dmin_initialized){ - dmin = d; - dmin_initialized = true; - }else{ - dmin = (std::min)(d,dmin); - } - } - - if(orientation(t1,t3,t2, pt) == NEGATIVE){ - on_bounded_side = false; - const typename K::FT d = squared_distance_to_triangle(pt, t1, t3, t2, inside, k); - if(inside){ - return d; - } - if(! dmin_initialized){ - dmin = d; - dmin_initialized = true; - }else{ - dmin = (std::min)(d,dmin); - } - } - - if(orientation(t2,t3,t0, pt) == NEGATIVE){ - on_bounded_side = false; - const typename K::FT d = squared_distance_to_triangle(pt, t2, t3, t0, inside, k); - if(inside){ - return d; - } - if(! dmin_initialized){ - dmin = d; - dmin_initialized = true; - }else{ - dmin = (std::min)(d,dmin); - } - } - - if(on_bounded_side){ - return typename K::FT(0); - } - return dmin; -} - -} // namespace internal - - -template -typename K::FT -squared_distance(const Tetrahedron_3 & t, - const Point_3 & pt) -{ - return internal::squared_distance(t,pt,K()); -} - - -template -typename K::FT -squared_distance(const Point_3 & pt, - const Tetrahedron_3 & t) -{ - return internal::squared_distance(t,pt,K()); -} - -} //namespace CGAL - - -#endif diff --git a/Distance_3/include/CGAL/squared_distance_Line_3_Line_3.h b/Distance_3/include/CGAL/squared_distance_Line_3_Line_3.h new file mode 100644 index 00000000000..7f9098f4815 --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Line_3_Line_3.h @@ -0,0 +1,61 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_LINE_3_LINE_3_H +#define CGAL_DISTANCE_3_LINE_3_LINE_3_H + +#include + +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Line_3& line1, + const typename K::Line_3& line2, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + Vector_3 dir1, dir2, normal, diff; + dir1 = line1.direction().vector(); + dir2 = line2.direction().vector(); + normal = wcross(dir1, dir2, k); + diff = vector(line1.point(), line2.point()); + if (is_null(normal, k)) + return squared_distance_to_line(dir2, diff, k); + + return squared_distance_to_plane(normal, diff, k); +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance(const Line_3& line1, + const Line_3& line2) +{ + return internal::squared_distance(line1, line2, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_LINE_3_LINE_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Line_3_Plane_3.h b/Distance_3/include/CGAL/squared_distance_Line_3_Plane_3.h new file mode 100644 index 00000000000..10becb28625 --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Line_3_Plane_3.h @@ -0,0 +1,85 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_LINE_3_PLANE_3_H +#define CGAL_DISTANCE_3_LINE_3_PLANE_3_H + +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +bool +contains_vector(const typename K::Plane_3& pl, + const typename K::Vector_3& vec, + const K&) +{ + typedef typename K::RT RT; + + return pl.a()*vec.hx() + pl.b()*vec.hy() + pl.c() * vec.hz() == RT(0); +} + +template +typename K::FT +squared_distance(const typename K::Line_3& l, + const typename K::Plane_3& pl, + const K& k) +{ + typedef typename K::FT FT; + + if (contains_vector(pl, l.direction().vector(), k)) + return squared_distance(pl, l.point(), k); + + return FT(0); +} + +template +inline typename K::FT +squared_distance(const typename K::Plane_3& pl, + const typename K::Line_3& l, + const K& k) +{ + return squared_distance(l, pl, k); +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance(const Line_3& line, + const Plane_3& plane) +{ + return internal::squared_distance(line, plane, K()); +} + +template +inline +typename K::FT +squared_distance(const Plane_3& plane, + const Line_3& line) +{ + return internal::squared_distance(line, plane, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_LINE_3_PLANE_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Plane_3_Plane_3.h b/Distance_3/include/CGAL/squared_distance_Plane_3_Plane_3.h new file mode 100644 index 00000000000..dcfa26de7c3 --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Plane_3_Plane_3.h @@ -0,0 +1,44 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_PLANE_3_PLANE_3_H +#define CGAL_DISTANCE_3_PLANE_3_PLANE_3_H + +#include +#include + +#include + +namespace CGAL { + +template +inline +typename K::FT +squared_distance(const Plane_3& plane1, + const Plane_3& plane2) +{ + K k; + typename K::Construct_orthogonal_vector_3 ortho_vec = k.construct_orthogonal_vector_3_object(); + + if (!internal::is_null(internal::wcross(ortho_vec(plane1), ortho_vec(plane2), k), k)) + return typename K::FT(0); + else + return internal::squared_distance(plane1.point(), plane2, k); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_PLANE_3_PLANE_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Line_3.h b/Distance_3/include/CGAL/squared_distance_Point_3_Line_3.h new file mode 100644 index 00000000000..5af9a9ab14e --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Point_3_Line_3.h @@ -0,0 +1,75 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_POINT_3_LINE_3_H +#define CGAL_DISTANCE_3_POINT_3_LINE_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Point_3& pt, + const typename K::Line_3& line, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 construct_vector; + Vector_3 dir(line.direction().vector()); + Vector_3 diff = construct_vector(line.point(), pt); + + return internal::squared_distance_to_line(dir, diff, k); +} + +template +inline +typename K::FT +squared_distance(const typename K::Line_3& line, + const typename K::Point_3& pt, + const K& k) +{ + return squared_distance(pt, line, k); +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance(const Point_3& pt, + const Line_3& line) +{ + return internal::squared_distance(pt, line, K()); +} + +template +inline +typename K::FT +squared_distance(const Line_3& line, + const Point_3& pt) +{ + return internal::squared_distance(pt, line, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_POINT_3_LINE_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Plane_3.h b/Distance_3/include/CGAL/squared_distance_Point_3_Plane_3.h new file mode 100644 index 00000000000..d327e11dc9a --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Point_3_Plane_3.h @@ -0,0 +1,73 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_POINT_3_PLANE_3_H +#define CGAL_DISTANCE_3_POINT_3_PLANE_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +inline typename K::FT +squared_distance(const typename K::Point_3& pt, + const typename K::Plane_3& plane, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + Vector_3 diff = vector(plane.point(), pt); + return squared_distance_to_plane(plane.orthogonal_vector(), diff, k); +} + +template +inline typename K::FT +squared_distance(const typename K::Plane_3& plane, + const typename K::Point_3& pt, + const K& k) +{ + return squared_distance(pt, plane, k); +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance(const Point_3& pt, + const Plane_3& plane) +{ + return internal::squared_distance(pt, plane, K()); +} + +template +inline +typename K::FT +squared_distance(const Plane_3& plane, + const Point_3& pt) +{ + return internal::squared_distance(pt, plane, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_POINT_3_PLANE_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Point_3.h b/Distance_3/include/CGAL/squared_distance_Point_3_Point_3.h new file mode 100644 index 00000000000..6b307e571c7 --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Point_3_Point_3.h @@ -0,0 +1,48 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_POINT_3_POINT_3_H +#define CGAL_DISTANCE_3_POINT_3_POINT_3_H + +#include + +namespace CGAL { +namespace internal { + +template +inline +typename K::FT +squared_distance(const typename K::Point_3& pt1, + const typename K::Point_3& pt2, + const K& k) +{ + return k.compute_squared_distance_3_object()(pt1, pt2); +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance(const Point_3& pt1, + const Point_3& pt2) +{ + return internal::squared_distance(pt1, pt2, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_POINT_3_POINT_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Ray_3.h b/Distance_3/include/CGAL/squared_distance_Point_3_Ray_3.h new file mode 100644 index 00000000000..0c943ce7c71 --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Point_3_Ray_3.h @@ -0,0 +1,78 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_POINT_3_RAY_3_H +#define CGAL_DISTANCE_3_POINT_3_RAY_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Point_3& pt, + const typename K::Ray_3& ray, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 construct_vector; + + Vector_3 diff = construct_vector(ray.source(), pt); + const Vector_3 &dir = ray.direction().vector(); + + if(!is_acute_angle(dir, diff, k)) + return (typename K::FT)(diff*diff); + + return squared_distance_to_line(dir, diff, k); +} + +template +typename K::FT +squared_distance(const typename K::Ray_3& ray, + const typename K::Point_3& pt, + const K& k) +{ + return squared_distance(pt, ray, k); +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance(const Point_3& pt, + const Ray_3& ray) +{ + return internal::squared_distance(pt, ray, K()); +} + +template +inline +typename K::FT +squared_distance(const Ray_3& ray, + const Point_3& pt) +{ + return internal::squared_distance(pt, ray, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_POINT_3_RAY_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Segment_3.h b/Distance_3/include/CGAL/squared_distance_Point_3_Segment_3.h new file mode 100644 index 00000000000..010ef89f852 --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Point_3_Segment_3.h @@ -0,0 +1,130 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_POINT_3_SEGMENT_3_H +#define CGAL_DISTANCE_3_POINT_3_SEGMENT_3_H + +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Point_3& pt, + const typename K::Segment_3& seg, + const K& k, + const Homogeneous_tag&) +{ + typedef typename K::Vector_3 Vector_3; + typedef typename K::RT RT; + typedef typename K::FT FT; + + typename K::Construct_vector_3 construct_vector; + + // assert that the segment is valid (non zero length). + 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)) + return FT(diff*diff); + RT e = wdot(segvec,segvec, k); + if((d * segvec.hw()) > (e * diff.hw())) + return squared_distance(pt, seg.target(), k); + + Vector_3 wcr = wcross(segvec, diff, k); + return FT(wcr*wcr)/FT(e * diff.hw() * diff.hw()); +} + +template +typename K::FT +squared_distance(const typename K::Point_3& pt, + const typename K::Segment_3& seg, + const K& k, + const Cartesian_tag&) +{ + typedef typename K::Vector_3 Vector_3; + typedef typename K::RT RT; + typedef typename K::FT FT; + + typename K::Construct_vector_3 construct_vector; + + // assert that the segment is valid (non zero length). + 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)) + return (FT(diff*diff)); + + RT e = wdot(segvec,segvec, k); + if(d > e) + return squared_distance(pt, seg.target(), k); + + Vector_3 wcr = wcross(segvec, diff, k); + return FT(wcr*wcr)/e; +} + +template +inline +typename K::FT +squared_distance(const typename K::Point_3& pt, + const typename K::Segment_3& seg, + const K& k) +{ + typedef typename K::Kernel_tag Tag; + Tag tag; + return squared_distance(pt, seg, k, tag); +} + +template +inline +typename K::FT +squared_distance(const typename K::Segment_3& seg, + const typename K::Point_3& pt, + const K& k) +{ + return squared_distance(pt, seg, k); +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance(const Point_3& pt, + const Segment_3& seg) +{ + return internal::squared_distance(pt, seg, K()); +} + +template +inline +typename K::FT +squared_distance(const Segment_3& seg, + const Point_3& pt) +{ + return internal::squared_distance(pt, seg, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_POINT_3_SEGMENT_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Tetrahedron_3.h b/Distance_3/include/CGAL/squared_distance_Point_3_Tetrahedron_3.h new file mode 100644 index 00000000000..8accd9b7d30 --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Point_3_Tetrahedron_3.h @@ -0,0 +1,148 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Andreas Fabri + +#ifndef CGAL_DISTANCE_3_POINT_3_TETRAHEDRON_3_H +#define CGAL_DISTANCE_3_POINT_3_TETRAHEDRON_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +inline +typename K::FT +squared_distance(const typename K::Point_3& pt, + const typename K::Tetrahedron_3& tet, + const K& k) +{ + typedef typename K::Point_3 Point_3; + + typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); + typename K::Orientation_3 orientation = k.orientation_3_object(); + + bool on_bounded_side = true; + const Point_3& t0 = vertex(tet, 0); + const Point_3& t1 = vertex(tet, 1); + const Point_3& t2 = vertex(tet, 2); + const Point_3& t3 = vertex(tet, 3); + + bool dmin_initialized = false; + typename K::FT dmin; + bool inside = false; + if(orientation(t0,t1,t2, pt) == NEGATIVE) + { + on_bounded_side = false; + dmin = squared_distance_to_triangle(pt, t0, t1, t2, k, inside); + dmin_initialized = true; + if(inside) + return dmin; + } + + if(orientation(t0,t3,t1, pt) == NEGATIVE) + { + on_bounded_side = false; + const typename K::FT d = squared_distance_to_triangle(pt, t0, t3, t1, k, inside); + if(inside) + return d; + + if(!dmin_initialized) + { + dmin = d; + dmin_initialized = true; + } + else + { + dmin = (std::min)(d, dmin); + } + } + + if(orientation(t1,t3,t2, pt) == NEGATIVE) + { + on_bounded_side = false; + const typename K::FT d = squared_distance_to_triangle(pt, t1, t3, t2, k, inside); + if(inside) + return d; + + if(!dmin_initialized) + { + dmin = d; + dmin_initialized = true; + } + else + { + dmin = (std::min)(d, dmin); + } + } + + if(orientation(t2,t3,t0, pt) == NEGATIVE) + { + on_bounded_side = false; + const typename K::FT d = squared_distance_to_triangle(pt, t2, t3, t0, k, inside); + if(inside) + return d; + + if(!dmin_initialized) + { + dmin = d; + dmin_initialized = true; + } + else + { + dmin = (std::min)(d, dmin); + } + } + + if(on_bounded_side) + return typename K::FT(0); + + return dmin; +} + +template +inline +typename K::FT +squared_distance(const typename K::Tetrahedron_3& tet, + const typename K::Point_3& pt, + const K& k) +{ + return squared_distance(pt, tet, k); +} + +} // namespace internal + +template +typename K::FT +squared_distance(const Tetrahedron_3& tet, + const Point_3& pt) +{ + return internal::squared_distance(pt, tet, K()); +} + +template +typename K::FT +squared_distance(const Point_3& pt, + const Tetrahedron_3& tet) +{ + return internal::squared_distance(pt, tet, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_POINT_3_TETRAHEDRON_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Triangle_3.h b/Distance_3/include/CGAL/squared_distance_Point_3_Triangle_3.h new file mode 100644 index 00000000000..bde0aa1511f --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Point_3_Triangle_3.h @@ -0,0 +1,125 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_POINT_3_TRIANGLE_3_H +#define CGAL_DISTANCE_3_POINT_3_TRIANGLE_3_H + +#include +#include + +namespace CGAL { +namespace internal { + +template +inline bool +on_left_of_triangle_edge(const typename K::Point_3& pt, + const typename K::Vector_3& normal, + const typename K::Point_3& ep0, + const typename K::Point_3& ep1, + const K& k) +{ + // returns true iff pt is on the negative side of the plane defined by (ep0, ep1) and normal + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + typename K::Vector_3 edge = vector(ep0, ep1); + typename K::Vector_3 diff = vector(ep0, pt); + + typedef typename K::RT RT; + + const bool result = RT(wdot(wcross(edge, normal, k), diff, k)) <= RT(0); + return result; +} + +template +inline typename K::FT +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, + 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(); + + 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 && + on_left_of_triangle_edge(pt, normal, t0, t1, k) && + on_left_of_triangle_edge(pt, normal, t1, t2, k) && + on_left_of_triangle_edge(pt, normal, t2, t0, k)) + { + // the projection of pt is inside the triangle + inside = true; + return squared_distance_to_plane(normal, vector(t0, pt), k); + } + else + { + // 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. + typename K::FT d1 = internal::squared_distance(pt, segment(t2, t0), k); + typename K::FT d2 = internal::squared_distance(pt, segment(t1, t2), k); + typename K::FT d3 = internal::squared_distance(pt, segment(t0, t1), k); + + return (std::min)( (std::min)(d1, d2), d3); + } +} + +template +inline typename K::FT +squared_distance(const typename K::Point_3& pt, + const typename K::Triangle_3& t, + const K& k) +{ + typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); + + bool unused_inside = false; + return squared_distance_to_triangle(pt, + vertex(t, 0), + vertex(t, 1), + vertex(t, 2), + k, + unused_inside); +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance(const Point_3& pt, + const Triangle_3& t) +{ + return internal::squared_distance(pt, t, K()); +} + +template +inline +typename K::FT +squared_distance(const Triangle_3& t, + const Point_3& pt) +{ + return internal::squared_distance(pt, t, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_POINT_3_TRIANGLE_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Weighted_point_3.h b/Distance_3/include/CGAL/squared_distance_Point_3_Weighted_point_3.h new file mode 100644 index 00000000000..934cfaedf96 --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Point_3_Weighted_point_3.h @@ -0,0 +1,47 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_POINT_3_WEIGHTED_POINT_3_H +#define CGAL_DISTANCE_3_POINT_3_WEIGHTED_POINT_3_H + +#include + +#include +#include + +namespace CGAL { + +template +inline +typename K::FT +squared_distance(const Weighted_point_3& wpt, + const Point_3& pt) +{ + return internal::squared_distance(wpt.point(), pt, K()); +} + +template +inline +typename K::FT +squared_distance(const Point_3& pt, + const Weighted_point_3& wpt) +{ + return internal::squared_distance(pt, wpt.point(), K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_POINT_3_WEIGHTED_POINT_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Ray_3_Line_3.h b/Distance_3/include/CGAL/squared_distance_Ray_3_Line_3.h new file mode 100644 index 00000000000..1c5dec16d06 --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Ray_3_Line_3.h @@ -0,0 +1,97 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_RAY_3_LINE_3_H +#define CGAL_DISTANCE_3_RAY_3_LINE_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Line_3& line, + const typename K::Ray_3& ray, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + typedef typename K::Point_3 Point_3; + typedef typename K::RT RT; + + typename K::Construct_vector_3 construct_vector; + + const Point_3& rs = ray.source(); + + Vector_3 raydir, linedir, normal; + linedir = line.direction().vector(); + raydir = ray.direction().vector(); + normal = wcross(raydir, linedir, k); + + Vector_3 rs_min_lp = construct_vector(line.point(), rs); + if (is_null(normal, k)) + return squared_distance_to_line(linedir, rs_min_lp, k); + + bool crossing; + RT sdm_sr_l; + Vector_3 perpend2l; + perpend2l = wcross(linedir, normal, k); + + sdm_sr_l = wdot(perpend2l, rs_min_lp, k); + if (sdm_sr_l < RT(0)) + { + crossing = (RT(wdot(perpend2l, raydir, k)) >= RT(0)); + } + else + { + if (RT(wdot(perpend2l, raydir, k)) <= RT(0)) + crossing = true; + else + crossing = (sdm_sr_l == RT(0)); + } + + if (crossing) + return squared_distance_to_plane(normal, rs_min_lp, k); + else + return squared_distance_to_line(linedir, rs_min_lp, k); +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance(const Line_3 &line, + const Ray_3 &ray) +{ + return internal::squared_distance(line, ray, K()); +} + +template +inline +typename K::FT +squared_distance(const Ray_3& ray, + const Line_3& line) +{ + return internal::squared_distance(line, ray, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_RAY_3_LINE_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Ray_3_Plane_3.h b/Distance_3/include/CGAL/squared_distance_Ray_3_Plane_3.h new file mode 100644 index 00000000000..43cdcd22c75 --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Ray_3_Plane_3.h @@ -0,0 +1,97 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_RAY_3_PLANE_3_H +#define CGAL_DISTANCE_3_RAY_3_PLANE_3_H + +#include + +#include +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Ray_3 &ray, + const typename K::Plane_3 &plane, + const K& k) +{ + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; + typedef typename K::RT RT; + typedef typename K::FT FT; + + typename K::Construct_vector_3 construct_vector; + + const Point_3 &start = ray.start(); + const Point_3 &planepoint = plane.point(); + Vector_3 start_min_pp = construct_vector(planepoint, start); + Vector_3 end_min_pp = ray.direction().vector(); + const Vector_3 &normal = plane.orthogonal_vector(); + RT sdm_rs2pp = wdot(normal, start_min_pp, k); + RT sdm_re2pp = wdot(normal, end_min_pp, k); + + switch (CGAL_NTS sign(sdm_rs2pp)) + { + case -1: + if (sdm_re2pp > RT(0)) + return FT(0); + return squared_distance_to_plane(normal, start_min_pp, k); + case 0: + default: + return FT(0); + case 1: + if (sdm_re2pp < RT(0)) + return FT(0); + return squared_distance_to_plane(normal, start_min_pp, k); + } +} + +template +inline typename K::FT +squared_distance(const typename K::Plane_3& plane, + const typename K::Ray_3& ray, + const K& k) +{ + return squared_distance(ray, plane, k); +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance(const Ray_3& ray, + const Plane_3& plane) +{ + return internal::squared_distance(ray, plane, K()); +} + +template +inline +typename K::FT +squared_distance(const Plane_3& plane, + const Ray_3& ray) +{ + return internal::squared_distance(ray, plane, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_RAY_3_PLANE_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Ray_3_Ray_3.h b/Distance_3/include/CGAL/squared_distance_Ray_3_Ray_3.h new file mode 100644 index 00000000000..29ae66a63f9 --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Ray_3_Ray_3.h @@ -0,0 +1,131 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_RAY_3_RAY_3_H +#define CGAL_DISTANCE_3_RAY_3_RAY_3_H + +#include + +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +ray_ray_squared_distance_parallel(const typename K::Vector_3& ray1dir, + const typename K::Vector_3& ray2dir, + const typename K::Vector_3& s1_min_s2, + const K& k) +{ + if (!is_acute_angle(ray2dir, s1_min_s2, k)) + if (!same_direction(ray1dir, ray2dir, k)) + return typename K::FT(s1_min_s2*s1_min_s2); + + return squared_distance_to_line(ray1dir, s1_min_s2, k); +} + +template +typename K::FT +squared_distance(const typename K::Ray_3& ray1, + const typename K::Ray_3& ray2, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + typedef typename K::Point_3 Point_3; + typedef typename K::RT RT; + typedef typename K::FT FT; + + typename K::Construct_vector_3 construct_vector; + + const Point_3& s1 = ray1.source(); + const Point_3& s2 = ray2.source(); + Vector_3 dir1, dir2, normal; + dir1 = ray1.direction().vector(); + dir2 = ray2.direction().vector(); + normal = wcross(dir1, dir2, k); + Vector_3 s1_min_s2 = construct_vector(s2, s1); + if (is_null(normal, k)) + return ray_ray_squared_distance_parallel(dir1, dir2, s1_min_s2, k); + + bool crossing1, crossing2; + RT sdm_s1_2, sdm_s2_1; + Vector_3 perpend1, perpend2; + perpend1 = wcross(dir1, normal, k); + perpend2 = wcross(dir2, normal, k); + + sdm_s1_2 = wdot(perpend2, s1_min_s2, k); + if (sdm_s1_2 < RT(0)) { + crossing1 = (RT(wdot(perpend2, dir1, k)) >= RT(0)); + } else { + if (RT(wdot(perpend2, dir1, k)) <= RT(0)) { + crossing1 = true; + } else { + crossing1 = (sdm_s1_2 == RT(0)); + } + } + + sdm_s2_1 = -RT(wdot(perpend1, s1_min_s2, k)); + if (sdm_s2_1 < RT(0)) { + crossing2 = (RT(wdot(perpend1, dir2, k)) >= RT(0)); + } else { + if (RT(wdot(perpend1, dir2, k)) <= RT(0)) { + crossing2 = true; + } else { + crossing2 = (sdm_s2_1 == RT(0)); + } + } + + if (crossing1) { + if (crossing2) + return squared_distance_to_plane(normal, s1_min_s2, k); + return squared_distance(ray2.source(), ray1, k); + } else { + if (crossing2) { + return squared_distance(ray1.source(), ray2, k); + } else { + FT min1, min2; + min1 = squared_distance(ray1.source(), ray2, k); + min2 = squared_distance(ray2.source(), ray1, k); + return (min1 < min2) ? min1 : min2; + } + } +} + +} // namespace internal + +template +inline +typename K::FT +ray_ray_squared_distance_parallel(const Vector_3& ray1dir, + const Vector_3& ray2dir, + const Vector_3& s1_min_s2) +{ + return internal::ray_ray_squared_distance_parallel(ray1dir, ray2dir, s1_min_s2, K()); +} + +template +inline +typename K::FT +squared_distance(const Ray_3& ray1, + const Ray_3& ray2) +{ + return internal::squared_distance(ray1, ray2, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_RAY_3_RAY_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Segment_3_Line_3.h b/Distance_3/include/CGAL/squared_distance_Segment_3_Line_3.h new file mode 100644 index 00000000000..28a530ccce1 --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Segment_3_Line_3.h @@ -0,0 +1,117 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_SEGMENT_3_LINE_3_H +#define CGAL_DISTANCE_3_SEGMENT_3_LINE_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Segment_3& seg, + const typename K::Line_3& line, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + typedef typename K::Point_3 Point_3; + typedef typename K::RT RT; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + const Point_3& linepoint = line.point(); + const Point_3& start = seg.source(); + const Point_3& end = seg.target(); + + if (start == end) + return squared_distance(start, line, k); + + Vector_3 linedir = line.direction().vector(); + Vector_3 segdir = seg.direction().vector(); + Vector_3 normal = wcross(segdir, linedir, k); + + if (is_null(normal, k)) + return squared_distance_to_line(linedir, vector(linepoint,start), k); + + bool crossing; + RT sdm_ss2l, sdm_se2l; + Vector_3 perpend2line, start_min_lp, end_min_lp; + perpend2line = wcross(linedir, normal, k); + start_min_lp = vector(linepoint, start); + end_min_lp = vector(linepoint, end); + sdm_ss2l = wdot(perpend2line, start_min_lp, k); + sdm_se2l = wdot(perpend2line, end_min_lp, k); + + if (sdm_ss2l < RT(0)) { + crossing = (sdm_se2l >= RT(0)); + } else { + if (sdm_se2l <= RT(0)) { + crossing = true; + } else { + crossing = (sdm_ss2l == RT(0)); + } + } + + if (crossing) { + return squared_distance_to_plane(normal, start_min_lp, k); + } else { + RT dm; + dm = distance_measure_sub(sdm_ss2l, sdm_se2l, start_min_lp, end_min_lp, k); + if (dm <= RT(0)) { + return squared_distance_to_line(linedir, start_min_lp, k); + } else { + return squared_distance_to_line(linedir, end_min_lp, k); + } + } +} + +template +typename K::FT +squared_distance(const typename K::Line_3& line, + const typename K::Segment_3& seg, + const K& k) +{ + return squared_distance(seg, line, k); +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance(const Segment_3& seg, + const Line_3& line) +{ + return internal::squared_distance(seg, line, K()); +} + +template +inline +typename K::FT +squared_distance(const Line_3& line, + const Segment_3& seg) +{ + return internal::squared_distance(seg, line, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_SEGMENT_3_LINE_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Segment_3_Plane_3.h b/Distance_3/include/CGAL/squared_distance_Segment_3_Plane_3.h new file mode 100644 index 00000000000..dad2579ac76 --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Segment_3_Plane_3.h @@ -0,0 +1,105 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_SEGMENT_3_PLANE_3_H +#define CGAL_DISTANCE_3_SEGMENT_3_PLANE_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Segment_3 &seg, + const typename K::Plane_3 &plane, + const K& k) +{ + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; + typedef typename K::RT RT; + typedef typename K::FT FT; + + typename K::Construct_vector_3 construct_vector; + + const Point_3 &start = seg.start(); + const Point_3 &end = seg.end(); + if (start == end) + return squared_distance(start, plane, k); + + const Point_3 &planepoint = plane.point(); + Vector_3 start_min_pp = construct_vector(planepoint, start); + Vector_3 end_min_pp = construct_vector(planepoint, end); + const Vector_3 &normal = plane.orthogonal_vector(); + RT sdm_ss2pp = wdot(normal, start_min_pp, k); + RT sdm_se2pp = wdot(normal, end_min_pp, k); + switch (CGAL_NTS sign(sdm_ss2pp)) + { + case -1: + if (sdm_se2pp >= RT(0)) + return FT(0); + if (sdm_ss2pp * end_min_pp.hw() >= sdm_se2pp * start_min_pp.hw()) + return squared_distance_to_plane(normal, start_min_pp, k); + else + return squared_distance_to_plane(normal, end_min_pp, k); + case 0: + default: + return FT(0); + case 1: + if (sdm_se2pp <= RT(0)) + return FT(0); + if (sdm_ss2pp * end_min_pp.hw() <= sdm_se2pp * start_min_pp.hw()) + return squared_distance_to_plane(normal, start_min_pp, k); + else + return squared_distance_to_plane(normal, end_min_pp, k); + } +} + +template +inline typename K::FT +squared_distance(const typename K::Plane_3& plane, + const typename K::Segment_3& seg, + const K& k) +{ + return squared_distance(seg, plane, k); +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance(const Segment_3& seg, + const Plane_3& plane) +{ + return internal::squared_distance(seg, plane, K()); +} + +template +inline +typename K::FT +squared_distance(const Plane_3& plane, + const Segment_3& seg) +{ + return internal::squared_distance(seg, plane, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_SEGMENT_3_PLANE_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Segment_3_Ray_3.h b/Distance_3/include/CGAL/squared_distance_Segment_3_Ray_3.h new file mode 100644 index 00000000000..f6935116c8c --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Segment_3_Ray_3.h @@ -0,0 +1,194 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_SEGMENT_3_RAY_3_H +#define CGAL_DISTANCE_3_SEGMENT_3_RAY_3_H + +#include +#include +#include +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance_parallel(const typename K::Segment_3& seg, + const typename K::Ray_3& ray, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + + bool same_direction; + const Vector_3 &dir1 = seg.direction().vector(); + const Vector_3 &dir2 = ray.direction().vector(); + + if (CGAL_NTS abs(dir1.hx()) > CGAL_NTS abs(dir1.hy())) { + same_direction = (CGAL_NTS sign(dir1.hx()) == CGAL_NTS sign(dir2.hx())); + } else { + same_direction = (CGAL_NTS sign(dir1.hy()) == CGAL_NTS sign(dir2.hy())); + } + + if (same_direction) { + if (!is_acute_angle(seg.source(), seg.target(), ray.source(), k)) + return squared_distance(seg.target(), ray.source(), k); + } else { + if (!is_acute_angle(seg.target(), seg.source(), ray.source(), k)) + return squared_distance(seg.source(), ray.source(), k); + } + + return squared_distance(ray.source(), seg.supporting_line(), k); +} + +template +typename K::FT +squared_distance(const typename K::Segment_3& seg, + const typename K::Ray_3& ray, + const K& k) +{ + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; + typedef typename K::RT RT; + typedef typename K::FT FT; + + typename K::Construct_vector_3 construct_vector; + + const Point_3& ss = seg.source(); + const Point_3& se = seg.target(); + + if (ss == se) + return squared_distance(ss, ray, k); + + Vector_3 raydir, segdir, normal; + raydir = ray.direction().vector(); + segdir = seg.direction().vector(); + normal = wcross(segdir, raydir, k); + + if (is_null(normal, k)) + return squared_distance_parallel(seg, ray, k); + + bool crossing1, crossing2; + RT sdm_ss2r, sdm_se2r, sdm_rs2s, sdm_re2s; + Vector_3 perpend2seg, perpend2ray, ss_min_rs, se_min_rs; + perpend2seg = wcross(segdir, normal, k); + perpend2ray = wcross(raydir, normal, k); + ss_min_rs = construct_vector(ray.source(), ss); + se_min_rs = construct_vector(ray.source(), se); + sdm_ss2r = wdot(perpend2ray, ss_min_rs, k); + sdm_se2r = wdot(perpend2ray, se_min_rs, k); + + if (sdm_ss2r < RT(0)) { + crossing1 = (sdm_se2r >= RT(0)); + } else { + if (sdm_se2r <= RT(0)) { + crossing1 = true; + } else { + crossing1 = (sdm_ss2r == RT(0)); + } + } + + sdm_rs2s = -RT(wdot(perpend2seg, ss_min_rs, k)); + sdm_re2s = wdot(perpend2seg, raydir, k); + if (sdm_rs2s < RT(0)) { + crossing2 = (sdm_re2s >= RT(0)); + } else { + if (sdm_re2s <= RT(0)) { + crossing2 = true; + } else { + crossing2 = (sdm_rs2s == RT(0)); + } + } + + if (crossing1) { + if (crossing2) { + return squared_distance_to_plane(normal, ss_min_rs, k); + } + return squared_distance(ray.source(), seg, k); + } else { + if (crossing2) { + RT dm; + dm = distance_measure_sub(sdm_ss2r, sdm_se2r, ss_min_rs, se_min_rs, k); + if (dm < RT(0)) { + return squared_distance(ss, ray, k); + } else { + if (dm > RT(0)) { + return squared_distance(se, ray, k); + } else { + // parallel, should not happen (no crossing) + return squared_distance_parallel(seg, ray, k); + } + } + } else { + FT min1, min2; + RT dm; + dm = distance_measure_sub(sdm_ss2r, sdm_se2r, ss_min_rs, se_min_rs, k); + if (dm == RT(0)) + return squared_distance_parallel(seg, ray, k); + min1 = (dm < RT(0)) + ? squared_distance(ss, ray, k) + : squared_distance(se, ray, k); + min2 = squared_distance(ray.source(), seg, k); + return (min1 < min2) ? min1 : min2; + } + } +} + +template +typename K::FT +squared_distance(const typename K::Ray_3& ray, + const typename K::Segment_3& seg, + const K& k) +{ + return squared_distance(seg, ray, k); +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance_parallel(const Segment_3& seg, + const Ray_3& ray) +{ + return internal::squared_distance_parallel(ray,seg, K()); +} + +template +inline +typename K::FT +squared_distance(const Segment_3& seg, + const Ray_3& ray) +{ + return internal::squared_distance(seg, ray, K()); +} + +template +inline +typename K::FT +squared_distance(const Ray_3& ray, + const Segment_3& seg) +{ + return internal::squared_distance(seg, ray, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_SEGMENT_3_RAY_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h b/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h new file mode 100644 index 00000000000..6ae796f4b49 --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h @@ -0,0 +1,193 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Mael Rouxel-Labbé + +#ifndef CGAL_DISTANCE_3_SEGMENT_3_SEGMENT_3_H +#define CGAL_DISTANCE_3_SEGMENT_3_SEGMENT_3_H + +#include +#include + +#include + +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance_parallel(const typename K::Segment_3& seg1, + const typename K::Segment_3& seg2, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + + const Vector_3& dir1 = seg1.direction().vector(); + const Vector_3& dir2 = seg2.direction().vector(); + + if(same_direction(dir1, dir2, k)) + { + if(!is_acute_angle(seg1.source(), seg1.target(), seg2.source(), k)) + return squared_distance(seg1.target(), seg2.source(), k); + if(!is_acute_angle(seg1.target(), seg1.source(), seg2.target(), k)) + return squared_distance(seg1.source(), seg2.target(), k); + } + else + { + if(!is_acute_angle(seg1.source(), seg1.target(), seg2.target(), k)) + return squared_distance(seg1.target(), seg2.target(), k); + if(!is_acute_angle(seg1.target(), seg1.source(), seg2.source(), k)) + return squared_distance(seg1.source(), seg2.source(), k); + } + return squared_distance(seg2.source(), seg1.supporting_line(), k); +} + +template +typename K::FT +squared_distance(const typename K::Segment_3& seg1, + const typename K::Segment_3& seg2, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + typedef typename K::Point_3 Point_3; + typedef typename K::RT RT; + typedef typename K::FT FT; + + typename K::Construct_vector_3 construct_vector; + + const Point_3& start1 = seg1.source(); + const Point_3& start2 = seg2.source(); + const Point_3& end1 = seg1.target(); + const Point_3& end2 = seg2.target(); + + if(start1 == end1) + return squared_distance(start1, seg2, k); + if(start2 == end2) + return squared_distance(start2, seg1, k); + + Vector_3 dir1, dir2, normal; + dir1 = seg1.direction().vector(); + dir2 = seg2.direction().vector(); + normal = wcross(dir1, dir2, k); + if(is_null(normal, k)) + return squared_distance_parallel(seg1, seg2, k); + + bool crossing1, crossing2; + RT sdm_s1to2, sdm_e1to2, sdm_s2to1, sdm_e2to1; + Vector_3 perpend1, perpend2, s2mins1, e2mins1, e1mins2; + perpend1 = wcross(dir1, normal, k); + perpend2 = wcross(dir2, normal, k); + s2mins1 = construct_vector(start1, start2); + e2mins1 = construct_vector(start1, end2); + e1mins2 = construct_vector(start2, end1); + sdm_s1to2 = -RT(wdot(perpend2, s2mins1, k)); + sdm_e1to2 = wdot(perpend2, e1mins2, k); + sdm_s2to1 = wdot(perpend1, s2mins1, k); + sdm_e2to1 = wdot(perpend1, e2mins1, k); + + if(sdm_s1to2 < RT(0)) { + crossing1 = (sdm_e1to2 >= RT(0)); + } else { + if(sdm_e1to2 <= RT(0)) { + crossing1 = true; + } else { + crossing1 = (sdm_s1to2 == RT(0)); + } + } + if(sdm_s2to1 < RT(0)) { + crossing2 = (sdm_e2to1 >= RT(0)); + } else { + if(sdm_e2to1 <= RT(0)) { + crossing2 = true; + } else { + crossing2 = (sdm_s2to1 == RT(0)); + } + } + + if(crossing1) { + if(crossing2) { + return squared_distance_to_plane(normal, s2mins1, k); + } + + RT dm; + dm = distance_measure_sub(sdm_s2to1, sdm_e2to1, s2mins1, e2mins1, k); + if(dm < RT(0)) { + return squared_distance(start2, seg1, k); + } else { + if(dm > RT(0)) { + return squared_distance(end2, seg1, k); + } else { + // should not happen with exact arithmetic. + return squared_distance_parallel(seg1, seg2, k); + } + } + } else { + if(crossing2) { + RT dm; + dm =distance_measure_sub(sdm_s1to2, sdm_e1to2, s2mins1, e1mins2, k); + if(dm < RT(0)) { + return squared_distance(start1, seg2, k); + } else { + if(dm > RT(0)) { + return squared_distance(end1, seg2, k); + } else { + // should not happen with exact arithmetic. + return squared_distance_parallel(seg1, seg2, k); + } + } + } else { + FT min1, min2; + RT dm; + dm = distance_measure_sub(sdm_s1to2, sdm_e1to2, s2mins1, e1mins2, k); + if(dm == RT(0)) // should not happen with exact arithmetic. + return squared_distance_parallel(seg1, seg2, k); + min1 = (dm < RT(0)) ? + squared_distance(seg1.source(), seg2, k): + squared_distance(end1, seg2, k); + dm = distance_measure_sub(sdm_s2to1, sdm_e2to1, s2mins1, e2mins1, k); + if(dm == RT(0)) // should not happen with exact arithmetic. + return squared_distance_parallel(seg1, seg2, k); + min2 = (dm < RT(0)) ? + squared_distance(start2, seg1, k): + squared_distance(end2, seg1, k); + return (min1 < min2) ? min1 : min2; + } + } +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance_parallel(const Segment_3& seg1, + const Segment_3& seg2) +{ + return internal::squared_distance_parallel(seg1, seg2, K()); +} + +template +inline +typename K::FT +squared_distance(const Segment_3& seg1, + const Segment_3& seg2) +{ + return internal::squared_distance(seg1, seg2, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_SEGMENT_3_SEGMENT_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Weighted_point_3_Weighted_point_3.h b/Distance_3/include/CGAL/squared_distance_Weighted_point_3_Weighted_point_3.h new file mode 100644 index 00000000000..6aa9d79a94e --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Weighted_point_3_Weighted_point_3.h @@ -0,0 +1,37 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_WEIGHTED_POINT_3_WEIGHTED_POINT_3_H +#define CGAL_DISTANCE_3_WEIGHTED_POINT_3_WEIGHTED_POINT_3_H + +#include + +#include + +namespace CGAL { + +template +inline +typename K::FT +squared_distance(const Weighted_point_3& wpt1, + const Weighted_point_3& wpt2) +{ + return internal::squared_distance(wpt1.point(), wpt2.point(), K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_WEIGHTED_POINT_3_WEIGHTED_POINT_3_H diff --git a/Distance_3/test/Distance_3/test_distance_3.cpp b/Distance_3/test/Distance_3/test_distance_3.cpp index 3a1f72fe786..31265cfbb01 100644 --- a/Distance_3/test/Distance_3/test_distance_3.cpp +++ b/Distance_3/test/Distance_3/test_distance_3.cpp @@ -1,22 +1,34 @@ -// 3D distance tests. - -#ifdef NDEBUG -#undef NDEBUG //this testsuite requires NDEBUG to be not defined -#endif - #include #include +#include +#include + +#include + +#include +#include + +#include + +#include +#include + +#include -#include -#include #include +#include -const double epsilon = 0.001; +const double epsilon = 1e-14; -struct randomint { +struct randomint +{ randomint() ; - int get() const { return sequence[cur]; } - int next() { cur = (cur+1)%11; return get();} + int get() const { return sequence[cur]; } + int next() { + cur = (cur + 1) % 11; + return get(); + } + private: int sequence[11]; int cur; @@ -40,43 +52,31 @@ inline randomint::randomint() randomint ri; -inline double to_nt(int d) +template +struct Test { - return double(d); -} - -template < typename K > -struct Test { - + typedef typename K::RT RT; typedef typename K::FT FT; - typedef CGAL::Point_3< K > P; - typedef CGAL::Line_3< K > L; - typedef CGAL::Segment_3< K > S; - typedef CGAL::Ray_3< K > R; - typedef CGAL::Triangle_3< K > T; - typedef CGAL::Plane_3< K > Pl; - typedef CGAL::Iso_cuboid_3< K > Cub; - typedef CGAL::Tetrahedron_3< K > Tet; + typedef typename K::Point_3 P; + typedef typename K::Segment_3 S; + typedef typename K::Vector_3 V; + typedef typename K::Ray_3 R; + typedef typename K::Line_3 L; + typedef typename K::Triangle_3 T; + typedef typename K::Plane_3 Pl; + typedef typename K::Iso_cuboid_3 Cub; +private: + CGAL::Random& r; + const bool exact; + int N = 1000; + double m = 0, M = 1; - template < typename Type > - bool approx_equal_nt(const Type &t1, const Type &t2) - { - if (t1 == t2) - return true; - if (CGAL::abs(t1 - t2) / (CGAL::max)(CGAL::abs(t1), CGAL::abs(t2)) < epsilon) - return true; - std::cout << " Approximate comparison failed between : " << t1 << " and " << t2 << "\n"; - return false; - } - - template < typename O1, typename O2 > - void check_squared_distance(const O1& o1, const O2& o2, const FT& result) - { - assert(approx_equal_nt(CGAL::squared_distance(o1, o2), result)); - assert(approx_equal_nt(CGAL::squared_distance(o2, o1), result)); - } +public: + Test(CGAL::Random& r, bool exact) : r(r), exact(exact) { } +private: + inline RT to_nt(int d) const { return RT(d); } P p(int x, int y, int z) { @@ -84,34 +84,132 @@ struct Test { return P(to_nt(x*w), to_nt(y*w), to_nt(z*w), to_nt(w)); } + P random_point() const + { + return P(r.get_double(m, M), r.get_double(m, M), r.get_double(m, M)); + } + Pl pl(int a, int b, int c, int d) { int w = ri.next(); return Pl(to_nt(a*w), to_nt(b*w), to_nt(c*w), to_nt(d*w)); } +private: + template + bool are_equal(const Type& t1, const Type& t2, const bool verbose = true) + { + if(exact) + { + if(t1 != t2) + { + if(verbose) + { + std::cerr << "Approximate comparison failed: got " << t1 << " but expected " << t2 << std::endl; + std::cerr << "Diff: " << CGAL::abs(t1 - t2) << std::endl; + } + return false; + } + } + else // !exact + { + const FT diff = CGAL::abs(t1 - t2); + if(diff > std::numeric_limits::epsilon() && + diff > epsilon * (CGAL::abs(t1) + CGAL::abs(t2))) + { + if(verbose) + { + std::cerr << "Approximate comparison failed (t1|t2): got " << t1 << " but expected " << t2 << std::endl; + std::cerr << "Diff: " << CGAL::abs(t1 - t2) << " vs eps: " << epsilon * (CGAL::abs(t1) + CGAL::abs(t2)) << std::endl; + } + return false; + } + } + return true; + } + + template + void check_ss_distance(const O1& o1, const O2& o2) + { + FT res = CGAL::squared_distance(o1, o2); + FT asd = compute_squared_distance_interval_between_segments(o1.source(), o1.target(), + o2.source(), o2.target(), K()); + + assert(res == asd); + + std::cout << "input: " << o1.source() << " " << o1.target() << " " << o2.source() << " " << o2.target() << std::endl; + std::cout << "result (old) = " << res << std::endl; + std::cout << "result (new) = " << asd << std::endl; + } + + template + void do_intersect_check(const O1& o1, const O2& o2) + { + if(!o1.is_degenerate() && !o2.is_degenerate() && CGAL::do_intersect(o1, o2)) + { + assert(are_equal(CGAL::squared_distance(o1, o2), FT(0))); + assert(are_equal(CGAL::squared_distance(o2, o1), FT(0))); + } + } + + template + void do_intersect_check(const O1& o1, const O2& o2, const FT res) + { + // @todo remove is_degenerate() checks when do_intersect can handle degenerate objects + if(!o1.is_degenerate() && !o2.is_degenerate() && CGAL::do_intersect(o1, o2)) + assert(are_equal(res, FT(0))); + } + + template + void check_squared_distance(const O1& o1, const O2& o2, const FT& expected_result) + { + const FT res_o1o2 = CGAL::squared_distance(o1, o2); + const FT res_o2o1 = CGAL::squared_distance(o2, o1); + + assert(are_equal(res_o1o2, expected_result)); + assert(are_equal(res_o2o1, expected_result)); + + do_intersect_check(o1, o2, res_o1o2); + do_intersect_check(o1, o2, res_o2o1); + } + + template + void check_squared_distance_with_bound(const O1& o1, const O2& o2, const FT& ubound) + { + std::cout << "ex: " << CGAL::squared_distance(o1, o2) << " vs bound " << ubound << std::endl; + + const FT res_o1o2 = CGAL::squared_distance(o1, o2); + const FT res_o2o1 = CGAL::squared_distance(o2, o1); + + do_intersect_check(o1, o2, res_o1o2); + do_intersect_check(o1, o2, res_o2o1); + + assert(res_o1o2 <= ubound); + assert(res_o2o1 <= ubound); + } + +private: void P_P() { - std::cout << "Point - Point\n"; - check_squared_distance (p(0, 0, 0), p(0, 0, 0), 0); - check_squared_distance (p(1, 1, 1), p(0, 0, 0), 3); + std::cout << "Point - Point" << std::endl; + check_squared_distance(p(0, 0, 0), p(0, 0, 0), 0); + check_squared_distance(p(3, 5, 7), p(0, 0, 0), 83); } void P_S() { - // Note : the values are not verified by hand - std::cout << "Point - Segment\n"; - check_squared_distance (p(0, 1, 2), S(p(-3, 0, 0), p( 2, 0, 0)), 5); - check_squared_distance (p(0, 1, 2), S(p( 3, 0, 0), p( 2, 0, 0)), 9); - check_squared_distance (p(0, 1, 2), S(p( 2, 0, 0), p( 3, 0, 0)), 9); - check_squared_distance (p(6, 1, 2), S(p( 2, 0, 0), p( 3, 0, 0)), 14); + std::cout << "Point - Segment" << std::endl; + check_squared_distance(p(0, 1, 2), S{p(-3, 0, 0), p( 2, 0, 0)}, 5); + check_squared_distance(p(0, 1, 2), S{p( 3, 0, 0), p( 2, 0, 0)}, 9); + check_squared_distance(p(0, 1, 2), S{p( 2, 0, 0), p( 3, 0, 0)}, 9); + check_squared_distance(p(6, 1, 2), S{p( 2, 0, 0), p( 3, 0, 0)}, 14); } void P_T() { - std::cout << "Point - Triangle\n"; - check_squared_distance (p(0, 1, 2), T(p(0, 0, 0), p( 2, 0, 0), p( 0, 2, 0)), 4); + std::cout << "Point - Triangle" << std::endl; + check_squared_distance(p(0, 1, 2), T{p(0, 0, 0), p(2, 0, 0), p(0, 2, 0)}, 4); } void P_Tet() @@ -125,150 +223,479 @@ struct Test { void S_S() { - std::cout << "Segment - Segment\n"; - check_squared_distance (S(p( -8, -7, 0), p( 11, 6, 0)), S(p(23, -27, 2), p( -17, 16, 2)), 4); - check_squared_distance (S(p( 0, 0, 0), p( 5, 0, 0)), S(p( 1, 1, 2), p( 6, 1, 2)), 5); - check_squared_distance (S(p( 0, 0, 0), p( 5, 0, 0)), S(p( 1, 1, 2), p( 2, 1, 2)), 5); - check_squared_distance (S(p( 5, 0, 0), p( 8, 0, 0)), S(p( 1, 1, 2), p( 2, 1, 2)), 14); - check_squared_distance (S(p( 5, 0, 0), p( 0, 0, 0)), S(p( 1, 1, 2), p( 2, 1, 2)), 5); - check_squared_distance (S(p( 0, 0, 0), p( 5, 0, 0)), S(p( 6, 1, 2), p( 8, 1, 2)), 6); - check_squared_distance (S(p( 0, 0, 0), p( 0,-3, 0)), S(p( 1, 4, 2), p( 1, 7, 2)), 21); - check_squared_distance (S(p( 0, 0, 0), p( 5, 0, 0)), S(p( 8, 1, 2), p( 6, 1, 2)), 6); - check_squared_distance (S(p( 0, 0, 0), p( 0, 0, 0)), S(p( 8, 1, 2), p( 6, 1, 2)), 41); - check_squared_distance (S(p( 0, 0, 0), p( 1, 0, 0)), S(p( 2, 1, 2), p( 2, -1, 2)), 5); - check_squared_distance (S(p( 2, 0, 0), p( 0, 2, 0)), S(p( 1, 1, 4), p( 4, 0, 4)), 16); - check_squared_distance (S(p( 10, 0, 0), p( 0,10, 0)), S(p( 6, 6,20), p( 20, 0,20)), 402); - check_squared_distance (S(p(-10,-13, 0), p( 0,10, 0)), S(p(10, 5,20), p( 70,-30,20)), 524.642); - check_squared_distance (S(p( 0, 0, 0), p(30,-10, 0)), S(p(-5, 20,20), p( 40, 30,20)), 824.706); - check_squared_distance (S(p( 4, 0, 0), p(-3, -1, 0)), S(p( 1, 1, 2), p( 2, 11, 2)), 6); - check_squared_distance (S(p( 3, 4, 0), p( 7, 7, 0)), S(p( 7, 0, 2), p( 6, 5, 2)), 5); - check_squared_distance (S(p( -1, 1, 0), p( 3, 4, 0)), S(p( 7, 0, 2), p( 6, 5, 2)), 13.8462); + std::cout << "Segment - Segment" << std::endl; + + // coplanar segments (hardcoded) + double z = std::sqrt(2.); + P p0 = p(-1, 0, z); + P p1 = p( 1, 0, z); + + // translations of (0, -1, z) -- (0, 1, z) to have all variations of x&y (<0, [0;1]; >1) in the code + for(int j=-2;j<4; j+=2) + { + for(int k=-3;k<3; k+=2) + { + P p2 = p(j, k, z); + P p3 = p(j, k+2, z); + + // to explicit the expected distances + if(j == -2 && k == -3) + check_squared_distance(S{p0, p1}, S{p2, p3}, CGAL::squared_distance(p3, p0)); + else if(j == -2 && k == -1) + check_squared_distance(S{p0, p1}, S{p2, p3}, 1); + else if(j == -2 && k == 1) + check_squared_distance(S{p0, p1}, S{p2, p3}, CGAL::squared_distance(p2, p0)); + else if(j == 0 && k == -3) + check_squared_distance(S{p0, p1}, S{p2, p3}, 1); + else if(j == 0 && k == -1) + check_squared_distance(S{p0, p1}, S{p2, p3}, 0); + else if(j == 0 && k == 1) + check_squared_distance(S{p0, p1}, S{p2, p3}, 1); + else if(j == 2 && k == -3) + check_squared_distance(S{p0, p1}, S{p2, p3}, CGAL::squared_distance(p3, p1)); + else if(j == 2 && k == -1) + check_squared_distance(S{p0, p1}, S{p2, p3}, 1); + else if(j == 2 && k == 1) + check_squared_distance(S{p0, p1}, S{p2, p3}, CGAL::squared_distance(p2, p1)); + } + } + + for(int i=0; i, gte::Segment<3, FT> > GTE_SS_checker; + gte::Segment<3, FT> gte_s1{{p8.x(), p8.y(), p8.z()}, {p9.x(), p9.y(), p9.z()}}; + gte::Segment<3, FT> gte_s2{{p3.x(), p3.y(), p3.z()}, {p2.x(), p2.y(), p2.z()}}; + auto gte_res = GTE_SS_checker(gte_s1, gte_s2); + std::cout << "old: " << CGAL::internal::squared_distance_old(s89, s32, K()) << std::endl; + std::cout << "dist (GTE) : " << gte_res.sqrDistance << std::endl; + + // Because do_intersect() with constructions is likely to return 'false' even for overlaps + assert(are_equal(CGAL::squared_distance(s89, s32), result, false /*verbose*/) || + are_equal(CGAL::squared_distance(s32, s89), FT(0))); + } + + // completely generic + S s1{p0, p1}, s2{p2, p3}; + do_intersect_check(s1, s2); + + // GTE ----------------------------------------------------------------------------------------- + gte::DCPQuery, gte::Segment<3, FT> > GTE_SS_checker; + gte::Segment<3, FT> gte_s1{{p0.x(), p0.y(), p0.z()}, {p1.x(), p1.y(), p1.z()}}; + gte::Segment<3, FT> gte_s2{{p2.x(), p2.y(), p2.z()}, {p3.x(), p3.y(), p3.z()}}; + auto gte_res = GTE_SS_checker(gte_s1, gte_s2); + + std::cout << "dist (CGAL) : " << CGAL::squared_distance(s1, s2) << std::endl; + std::cout << "dist (GTE) : " << gte_res.sqrDistance << std::endl; + assert(are_equal(CGAL::squared_distance(s1, s2), gte_res.sqrDistance)); + } + + // a few brute force checks: sample a segments and use squared_distance(P3, S3) + for(int i=0; i<10; ++i) + { + P p0 = random_point(); + P p1 = random_point(); + P p2 = random_point(); + P p3 = random_point(); + + S s01{p0, p1}; + S s23{p2, p3}; + + FT upper_bound = CGAL::squared_distance(p0, p2); + + V p01 = V{p0, p1} / N; + for(int l=0; l PQP_checker; +// auto pqp_res = PQP_checker(p0, p1, p2, p3, p4, p5); +// std::cout << "dist (PQP) : " << pqp_res << std::endl; + + // GTE ----------------------------------------------------------------------------------------- +// gte::DCPQuery, gte::Triangle3 > GTE_TT_checker; +// gte::Triangle3 gte_tr1{{CGAL::to_double(p0.x()), CGAL::to_double(p0.y()), CGAL::to_double(p0.z())}, +// {CGAL::to_double(p1.x()), CGAL::to_double(p1.y()), CGAL::to_double(p1.z())}, +// {CGAL::to_double(p2.x()), CGAL::to_double(p2.y()), CGAL::to_double(p2.z())}}; +// gte::Triangle3 gte_tr2{{CGAL::to_double(p3.x()), CGAL::to_double(p3.y()), CGAL::to_double(p3.z())}, +// {CGAL::to_double(p4.x()), CGAL::to_double(p4.y()), CGAL::to_double(p4.z())}, +// {CGAL::to_double(p5.x()), CGAL::to_double(p5.y()), CGAL::to_double(p5.z())}}; +// auto gte_res = GTE_TT_checker(gte_tr1, gte_tr2); + + gte::DCPQuery, gte::Triangle3 > GTE_TT_checker; + gte::Triangle3 gte_tr1{{p0.x(), p0.y(), p0.z()}, {p1.x(), p1.y(), p1.z()}, {p2.x(), p2.y(), p2.z()}}; + gte::Triangle3 gte_tr2{{p3.x(), p3.y(), p3.z()}, {p4.x(), p4.y(), p4.z()}, {p5.x(), p5.y(), p5.z()}}; + auto gte_res = GTE_TT_checker(gte_tr1, gte_tr2); + +// std::cout << "dist (CGAL) : " << CGAL::squared_distance(tr1, tr2) << std::endl; +// std::cout << "dist (GTE) : " << gte_res.sqrDistance << std::endl; +// std::cout << "diff CGAL GTE : " << (gte_res.sqrDistance - CGAL::squared_distance(tr1, tr2)) << std::endl; +// std::cout << "diff CGAL PQP : " << (pqp_res - CGAL::squared_distance(tr1, tr2)) << std::endl; + if(!are_equal(CGAL::squared_distance(tr1, tr2), gte_res.sqrDistance)) + std::cerr <<"uh-oh" << std::endl; + } + } + +public: void run() { - std::cout << "3D Distance tests\n"; - P_P(); - P_S(); - P_T(); - P_Tet(); - S_S(); - P_R(); - R_R(); - S_R(); - R_L(); - P_L(); - S_L(); - L_L(); - P_Pl(); - S_Pl(); - R_Pl(); - L_Pl(); - Pl_Pl(); - } + std::cout << "Kernel: " << typeid(K).name() << std::endl; +// P_P(); +// P_S(); +// P_R(); +// P_L(); +// P_T(); +// P_Pl(); + + S_S(); +// S_R(); +// S_L(); +// S_Pl(); + +// R_R(); +// R_L(); +// R_Pl(); + +// L_L(); +// L_Pl(); + + T_T(); + +// Pl_Pl(); + } }; int main() { - Test< CGAL::Simple_cartesian >().run(); - Test< CGAL::Simple_homogeneous >().run(); - // TODO : test more kernels. + std::cout.precision(17); + std::cerr.precision(17); + + std::cout << "3D Distance tests" << std::endl; + + CGAL::Random r; + std::cout << "random seed = " << r.get_seed() << std::endl; + +// Test >(r, false).run(); +// Test >(r, false).run(); + +// Test(r, false).run(); + Test(r, true).run(); + + std::cout << "Done!" << std::endl; + + return EXIT_SUCCESS; } From 2046f7368ba387173044056308d2b4accff5dc4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 12 Mar 2021 11:51:30 +0100 Subject: [PATCH 02/23] Improve Segment_3-Segment_3 distance computation --- .../squared_distance_Segment_3_Segment_3.h | 222 +++++++++--------- 1 file changed, 117 insertions(+), 105 deletions(-) diff --git a/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h b/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h index 6ae796f4b49..e2fb59ae0fa 100644 --- a/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h +++ b/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h @@ -25,6 +25,119 @@ #include namespace CGAL { +namespace Distance_3 { +namespace internal { + +template +struct Segment_3_Segment_3_Result +{ + typename K::FT x, y; + typename K::FT squared_distance; +}; + +// Using Lumelsky, 'On Fast Computation of Distance Between Line Segments' 1984 +template +Segment_3_Segment_3_Result +squared_distance(const typename K::Segment_3& s1, + const typename K::Segment_3& s2, + const K& k) +{ + typedef typename K::FT FT; + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); + typename K::Construct_vector_3 cv = k.construct_vector_3_object(); + typename K::Compute_scalar_product_3 sp = k.compute_scalar_product_3_object(); + + Segment_3_Segment_3_Result res; + + const Point_3& p1 = vertex(s1, 0); + const Point_3& q1 = vertex(s1, 1); + const Point_3& p2 = vertex(s2, 0); + const Point_3& q2 = vertex(s2, 1); + const Vector_3 v1 = cv(p1, q1), v2 = cv(p2, q2); + const Vector_3 p1p2 = cv(p1, p2); + + // @todo compute these only when needed? + const FT a = sp(v1, v1); + const FT b = - sp(v1, v2); + const FT c = - b; + const FT d = - sp(v2, v2); + const FT e = sp(v1, p1p2); + const FT f = sp(v2, p1p2); + + if(p1 == q1) + { + if(p2 == q2) + { + res.x = 0; + res.y = 0; + res.squared_distance = CGAL::squared_distance(p1, p2); + return res; + } + + CGAL_assertion(d != 0); + + res.x = 0; + res.y = boost::algorithm::clamp(f/d, 0, 1); // (f - x*c) / d + res.squared_distance = CGAL::squared_distance(p1, p2 + res.y*v2); + + return res; + } + else if(p2 == q2) + { + CGAL_assertion(a != 0); + + res.y = 0; + res.x = boost::algorithm::clamp(e/a, 0, 1); // (e + y*c) / a + res.squared_distance = CGAL::squared_distance(p1 + res.x*v1, p2); + + return res; + } + + CGAL_assertion(a > 0 && d < 0); + + const FT det = a*d - b*c; + if(det == 0) + res.x = 0; + else + res.x = boost::algorithm::clamp((e*d - b*f) / det, 0, 1); + + FT xc = res.x*c; + // res.y = (f - xc) / d, by definition, but building it up more efficiently + if(f > xc) // y < 0 <=> f - xc / d < 0 <=> f - xc > 0 (since d is -||v2||) + { + res.y = 0; + res.x = boost::algorithm::clamp(e/a, 0, 1); // (e + y*c) / a + } + else // y >= 0 + { + FT n = f - xc; // delay the division by d + if(n < d) // y > 1 <=> n / d > 1 <=> n < d (once again, important to note that d is negative!) + { + res.y = 1; + res.x = boost::algorithm::clamp((e + c) / a, 0, 1); // (e + y*c) / a + } + else // 0 <= y <= 1 + { + res.y = n / d; + } + } + + CGAL_postcondition(FT(0) <= res.x && res.x <= FT(1)); + CGAL_postcondition(FT(0) <= res.y && res.y <= FT(1)); + + res.squared_distance = CGAL::squared_distance(p1 + res.x*v1, p2 + res.y*v2); + + CGAL_postcondition(res.squared_distance >= FT(0)); + + return res; +} + +} // namespace internal +} // namespace Distance_3 + namespace internal { template @@ -55,117 +168,16 @@ squared_distance_parallel(const typename K::Segment_3& seg1, return squared_distance(seg2.source(), seg1.supporting_line(), k); } -template +template typename K::FT squared_distance(const typename K::Segment_3& seg1, const typename K::Segment_3& seg2, const K& k) { - typedef typename K::Vector_3 Vector_3; - typedef typename K::Point_3 Point_3; - typedef typename K::RT RT; - typedef typename K::FT FT; + Distance_3::internal::Segment_3_Segment_3_Result res = + Distance_3::internal::squared_distance(seg1, seg2, k); - typename K::Construct_vector_3 construct_vector; - - const Point_3& start1 = seg1.source(); - const Point_3& start2 = seg2.source(); - const Point_3& end1 = seg1.target(); - const Point_3& end2 = seg2.target(); - - if(start1 == end1) - return squared_distance(start1, seg2, k); - if(start2 == end2) - return squared_distance(start2, seg1, k); - - Vector_3 dir1, dir2, normal; - dir1 = seg1.direction().vector(); - dir2 = seg2.direction().vector(); - normal = wcross(dir1, dir2, k); - if(is_null(normal, k)) - return squared_distance_parallel(seg1, seg2, k); - - bool crossing1, crossing2; - RT sdm_s1to2, sdm_e1to2, sdm_s2to1, sdm_e2to1; - Vector_3 perpend1, perpend2, s2mins1, e2mins1, e1mins2; - perpend1 = wcross(dir1, normal, k); - perpend2 = wcross(dir2, normal, k); - s2mins1 = construct_vector(start1, start2); - e2mins1 = construct_vector(start1, end2); - e1mins2 = construct_vector(start2, end1); - sdm_s1to2 = -RT(wdot(perpend2, s2mins1, k)); - sdm_e1to2 = wdot(perpend2, e1mins2, k); - sdm_s2to1 = wdot(perpend1, s2mins1, k); - sdm_e2to1 = wdot(perpend1, e2mins1, k); - - if(sdm_s1to2 < RT(0)) { - crossing1 = (sdm_e1to2 >= RT(0)); - } else { - if(sdm_e1to2 <= RT(0)) { - crossing1 = true; - } else { - crossing1 = (sdm_s1to2 == RT(0)); - } - } - if(sdm_s2to1 < RT(0)) { - crossing2 = (sdm_e2to1 >= RT(0)); - } else { - if(sdm_e2to1 <= RT(0)) { - crossing2 = true; - } else { - crossing2 = (sdm_s2to1 == RT(0)); - } - } - - if(crossing1) { - if(crossing2) { - return squared_distance_to_plane(normal, s2mins1, k); - } - - RT dm; - dm = distance_measure_sub(sdm_s2to1, sdm_e2to1, s2mins1, e2mins1, k); - if(dm < RT(0)) { - return squared_distance(start2, seg1, k); - } else { - if(dm > RT(0)) { - return squared_distance(end2, seg1, k); - } else { - // should not happen with exact arithmetic. - return squared_distance_parallel(seg1, seg2, k); - } - } - } else { - if(crossing2) { - RT dm; - dm =distance_measure_sub(sdm_s1to2, sdm_e1to2, s2mins1, e1mins2, k); - if(dm < RT(0)) { - return squared_distance(start1, seg2, k); - } else { - if(dm > RT(0)) { - return squared_distance(end1, seg2, k); - } else { - // should not happen with exact arithmetic. - return squared_distance_parallel(seg1, seg2, k); - } - } - } else { - FT min1, min2; - RT dm; - dm = distance_measure_sub(sdm_s1to2, sdm_e1to2, s2mins1, e1mins2, k); - if(dm == RT(0)) // should not happen with exact arithmetic. - return squared_distance_parallel(seg1, seg2, k); - min1 = (dm < RT(0)) ? - squared_distance(seg1.source(), seg2, k): - squared_distance(end1, seg2, k); - dm = distance_measure_sub(sdm_s2to1, sdm_e2to1, s2mins1, e2mins1, k); - if(dm == RT(0)) // should not happen with exact arithmetic. - return squared_distance_parallel(seg1, seg2, k); - min2 = (dm < RT(0)) ? - squared_distance(start2, seg1, k): - squared_distance(end2, seg1, k); - return (min1 < min2) ? min1 : min2; - } - } + return res.squared_distance; } } // namespace internal From 29d8b296edf9cba131e4fbf6831841f986a4612d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 12 Mar 2021 11:51:56 +0100 Subject: [PATCH 03/23] Add Triangle_3-Triangle_3 distance --- Distance_3/include/CGAL/squared_distance_3.h | 2 + .../squared_distance_Triangle_3_Triangle_3.h | 231 ++++++++++++++++++ 2 files changed, 233 insertions(+) create mode 100644 Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h diff --git a/Distance_3/include/CGAL/squared_distance_3.h b/Distance_3/include/CGAL/squared_distance_3.h index bbd90d2d394..ffe555175b4 100644 --- a/Distance_3/include/CGAL/squared_distance_3.h +++ b/Distance_3/include/CGAL/squared_distance_3.h @@ -41,6 +41,8 @@ #include #include +#include + #include #endif // CGAL_DISTANCE_3_H diff --git a/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h b/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h new file mode 100644 index 00000000000..7d83415a38d --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h @@ -0,0 +1,231 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Mael Rouxel-Labbé + +#ifndef CGAL_DISTANCE_3_TRIANGLE_3_TRIANGLE_3_H +#define CGAL_DISTANCE_3_TRIANGLE_3_TRIANGLE_3_H + +#include +#include + +#include + +namespace CGAL { +namespace Distance_3 { +namespace internal { + +template +std::pair, bool> +test_edge_pair(const typename K::Point_3& p1, + const typename K::Point_3& q1, + const typename K::Point_3& r1, + const typename K::Point_3& p2, + const typename K::Point_3& q2, + const typename K::Point_3& r2, + const K& k, + typename K::FT& global_min_sqd, + bool& are_triangles_known_to_be_disjoint) +{ + typedef typename K::FT FT; + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; + + typename K::Compute_scalar_product_3 scalar_product = k.compute_scalar_product_3_object(); + typename K::Construct_segment_3 segment = k.construct_segment_3_object(); + typename K::Construct_scaled_vector_3 scale_vector = k.construct_scaled_vector_3_object(); + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + typename K::Construct_translated_point_3 translate = k.construct_translated_point_3_object(); + + Distance_3::internal::Segment_3_Segment_3_Result res = + internal::squared_distance(segment(p1, q1), segment(p2, q2), k); + + if(res.squared_distance <= global_min_sqd) + global_min_sqd = res.squared_distance; + else + return std::make_pair(res, false); + + const Vector_3 v1 = vector(p1, q1), v2 = vector(p2, q2); + const Point_3 m1 = translate(p1, scale_vector(v1, res.x)); + const Point_3 m2 = translate(p2, scale_vector(v2, res.y)); + const Vector_3 vr1 = vector(m1, r1), vr2 = vector(m2, r2); + const Vector_3 n = vector(m1, m2); + + const FT sp_r1 = scalar_product(vr1, n); + const FT sp_r2 = scalar_product(vr2, n); + const bool is_r1_closer = (sp_r1 > 0); // Plane_3{m1, n}.has_on_positive_side(r1); + const bool is_r2_closer = (sp_r2 < 0); // Plane_3{m2, -n}.has_on_positive_side(r2); + const bool is_best_pair = !is_r1_closer && !is_r2_closer; + + // Even if it is not the best pair, one may be able to deduce if the triangles do not intersect + // by checking if there is a void space between the planes orthogonal to the vector realizing + // the min distance between the edges and passing through the third points. + if(!is_best_pair) + { + FT separating_distance = res.squared_distance; + if(is_r1_closer) + separating_distance -= sp_r1; + if(is_r2_closer) + separating_distance += sp_r2; + + if(separating_distance > 0) + are_triangles_known_to_be_disjoint = true; + } + + return std::make_pair(res, is_best_pair); +} + +template +std::pair +test_vertex_triangle(const typename K::Triangle_3& tr1, + const typename K::Triangle_3& tr2, + const K& k, + bool& are_triangles_known_to_be_disjoint) +{ + typedef typename K::FT FT; + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; + + typename K::Compute_scalar_product_3 scalar_product = k.compute_scalar_product_3_object(); + typename K::Construct_cross_product_vector_3 cross_product = k.construct_cross_product_vector_3_object(); + typename K::Construct_scaled_vector_3 scale_vector = k.construct_scaled_vector_3_object(); + typename K::Construct_translated_point_3 translate = k.construct_translated_point_3_object(); + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); + + const Point_3& p1 = vertex(tr1, 0); + const Point_3& q1 = vertex(tr1, 1); + const Point_3& r1 = vertex(tr1, 2); + const Point_3& p2 = vertex(tr2, 0); + const Point_3& q2 = vertex(tr2, 1); + const Point_3& r2 = vertex(tr2, 2); + + const Vector_3 p2q2 = vector(p2, q2); + const Vector_3 p2r2 = vector(p2, r2); + const Vector_3 n2 = cross_product(p2q2, p2r2); + + if(scalar_product(n2, n2) == FT(0)) + return std::make_pair(0, false); + + std::array sps = { scalar_product(vector(p2, p1), n2), + scalar_product(vector(p2, q1), n2), + scalar_product(vector(p2, r1), n2) }; + + // All the vertices of tr1 must be on the same side of tr2 + // Coplanarity is tolerated, so '1' and '0' should be allowed, but not '1' and '-1' + if(CGAL::sign(sps[0]) == - CGAL::sign(sps[1]) || CGAL::sign(sps[1]) == - CGAL::sign(sps[2])) + return std::make_pair(0, false); + + std::for_each(sps.begin(), sps.end(), [](FT& v) { v = abs(v); }); + auto min_pos = std::min_element(sps.begin(), sps.end()); + auto min_id = std::distance(sps.begin(), min_pos); + + if(sps[min_id] > 0) + are_triangles_known_to_be_disjoint = true; + + const Point_3& x1 = vertex(tr1, min_id); + + if(on_left_of_triangle_edge(x1, n2, p2, q2, k) && + on_left_of_triangle_edge(x1, n2, q2, r2, k) && + on_left_of_triangle_edge(x1, n2, r2, p2, k)) + { + // the projection of `x1` is inside the triangle + return std::make_pair(squared_distance_to_plane(n2, vector(p2, x1), k), true); + } + + return std::make_pair(0, false); +} + +} // namespace internal +} // namespace Distance_3 + +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Triangle_3& tr1, + const typename K::Triangle_3& tr2, + const K& k) +{ + typedef typename K::FT FT; + + typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); + + // ideally just limits::infinity|max(), but it is not available for exact NTs... + FT global_min_sqd = CGAL::squared_distance(vertex(tr1, 0), vertex(tr2, 0)); + + bool are_triangles_known_to_be_disjoint = false; + std::pair, bool> ss_res; + for(int i=0; i<3; ++i) + { + for(int j=0; j<3; ++j) + { + ss_res = Distance_3::internal::test_edge_pair( + vertex(tr1, i%3), vertex(tr1, (i+1)%3), vertex(tr1, (i+2)%3), + vertex(tr2, j%3), vertex(tr2, (j+1)%3), vertex(tr2, (j+2)%3), k, + global_min_sqd, are_triangles_known_to_be_disjoint); + + if(ss_res.second) + return ss_res.first.squared_distance; + } + } + + // Failed to find a minimum between segment pairs, explore vertex-triangle distances + +#if 1 + std::pair pt_res = + Distance_3::internal::test_vertex_triangle(tr1, tr2, k, are_triangles_known_to_be_disjoint); + if(pt_res.second) + return pt_res.first; + + pt_res = Distance_3::internal::test_vertex_triangle(tr2, tr1, k, are_triangles_known_to_be_disjoint); + if(pt_res.second) + return pt_res.first; + + if(are_triangles_known_to_be_disjoint) + return global_min_sqd; + else + return 0; +#else // A tiny bit less efficient, but a lot clearer! + // @todo does not handle degenerate inputs + if(!are_triangles_known_to_be_disjoint && CGAL::do_intersect(tr1, tr2)) + return 0; + + FT sqd_p1 = CGAL::squared_distance(vertex(tr1, 0), tr2); + FT sqd_q1 = CGAL::squared_distance(vertex(tr1, 1), tr2); + FT sqd_r1 = CGAL::squared_distance(vertex(tr1, 2), tr2); + FT sqd_p2 = CGAL::squared_distance(vertex(tr2, 0), tr1); + FT sqd_q2 = CGAL::squared_distance(vertex(tr2, 1), tr1); + FT sqd_r2 = CGAL::squared_distance(vertex(tr2, 2), tr1); + + const FT m = std::min({sqd_p1, sqd_q1, sqd_r1, sqd_p2, sqd_q2, sqd_r2}); + + return m; +#endif +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance(const Triangle_3& tr1, + const Triangle_3& tr2) +{ + return internal::squared_distance(tr1, tr2, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_TRIANGLE_3_TRIANGLE_3_H From 5278c3044f74994ca9c238e86d8d9f7d76f5709c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 12 Mar 2021 11:54:19 +0100 Subject: [PATCH 04/23] Add some real tests for Seg_3-Seg_3 and Tri_3-Tri_3 --- .../test/Distance_3/test_distance_3.cpp | 168 ++++++++---------- 1 file changed, 74 insertions(+), 94 deletions(-) diff --git a/Distance_3/test/Distance_3/test_distance_3.cpp b/Distance_3/test/Distance_3/test_distance_3.cpp index 31265cfbb01..3d219582b6e 100644 --- a/Distance_3/test/Distance_3/test_distance_3.cpp +++ b/Distance_3/test/Distance_3/test_distance_3.cpp @@ -8,18 +8,15 @@ #include #include -#include - +// #define CGAL_USE_GTE_AS_SANITY_CHECK +#ifdef CGAL_USE_GTE_AS_SANITY_CHECK #include #include - -#include +#endif #include #include -const double epsilon = 1e-14; - struct randomint { randomint() ; @@ -64,16 +61,17 @@ struct Test typedef typename K::Line_3 L; typedef typename K::Triangle_3 T; typedef typename K::Plane_3 Pl; + typedef typename K::Tetrahedron_3 Tet; typedef typename K::Iso_cuboid_3 Cub; private: CGAL::Random& r; - const bool exact; + const double epsilon = 1e-14; int N = 1000; double m = 0, M = 1; public: - Test(CGAL::Random& r, bool exact) : r(r), exact(exact) { } + Test(CGAL::Random& r, const double epsilon) : r(r), epsilon(epsilon) { } private: inline RT to_nt(int d) const { return RT(d); } @@ -99,31 +97,16 @@ private: template bool are_equal(const Type& t1, const Type& t2, const bool verbose = true) { - if(exact) + const FT diff = CGAL::abs(t1 - t2); + if(diff > std::numeric_limits::epsilon() && + diff > epsilon * (CGAL::abs(t1) + CGAL::abs(t2))) { - if(t1 != t2) + if(verbose) { - if(verbose) - { - std::cerr << "Approximate comparison failed: got " << t1 << " but expected " << t2 << std::endl; - std::cerr << "Diff: " << CGAL::abs(t1 - t2) << std::endl; - } - return false; - } - } - else // !exact - { - const FT diff = CGAL::abs(t1 - t2); - if(diff > std::numeric_limits::epsilon() && - diff > epsilon * (CGAL::abs(t1) + CGAL::abs(t2))) - { - if(verbose) - { - std::cerr << "Approximate comparison failed (t1|t2): got " << t1 << " but expected " << t2 << std::endl; - std::cerr << "Diff: " << CGAL::abs(t1 - t2) << " vs eps: " << epsilon * (CGAL::abs(t1) + CGAL::abs(t2)) << std::endl; - } - return false; + std::cerr << "Approximate comparison failed (t1|t2): got " << t1 << " but expected " << t2 << std::endl; + std::cerr << "Diff: " << CGAL::abs(t1 - t2) << " vs eps: " << epsilon * (CGAL::abs(t1) + CGAL::abs(t2)) << std::endl; } + return false; } return true; @@ -143,6 +126,18 @@ private: std::cout << "result (new) = " << asd << std::endl; } + void do_intersect_check(const P&, const P&) { } + + template + void do_intersect_check(const P& p, const O2& o2) + { + if(!o2.is_degenerate() && CGAL::do_intersect(p, o2)) + { + assert(are_equal(CGAL::squared_distance(p, o2), FT(0))); + assert(are_equal(CGAL::squared_distance(o2, p), FT(0))); + } + } + template void do_intersect_check(const O1& o1, const O2& o2) { @@ -153,14 +148,6 @@ private: } } - template - void do_intersect_check(const O1& o1, const O2& o2, const FT res) - { - // @todo remove is_degenerate() checks when do_intersect can handle degenerate objects - if(!o1.is_degenerate() && !o2.is_degenerate() && CGAL::do_intersect(o1, o2)) - assert(are_equal(res, FT(0))); - } - template void check_squared_distance(const O1& o1, const O2& o2, const FT& expected_result) { @@ -170,20 +157,18 @@ private: assert(are_equal(res_o1o2, expected_result)); assert(are_equal(res_o2o1, expected_result)); - do_intersect_check(o1, o2, res_o1o2); - do_intersect_check(o1, o2, res_o2o1); + do_intersect_check(o1, o2); + do_intersect_check(o1, o2); } template void check_squared_distance_with_bound(const O1& o1, const O2& o2, const FT& ubound) { - std::cout << "ex: " << CGAL::squared_distance(o1, o2) << " vs bound " << ubound << std::endl; - const FT res_o1o2 = CGAL::squared_distance(o1, o2); const FT res_o2o1 = CGAL::squared_distance(o2, o1); - do_intersect_check(o1, o2, res_o1o2); - do_intersect_check(o1, o2, res_o2o1); + do_intersect_check(o1, o2); + do_intersect_check(o1, o2); assert(res_o1o2 <= ubound); assert(res_o2o1 <= ubound); @@ -310,7 +295,7 @@ private: const double lambda_7 = r.get_double(1, 2); const P p7 = p3 + lambda_7 * (p3 - p2); - // [p2;p3] left of [p6;p7] + // [p2;p3] disjoint && left of [p6;p7] check_squared_distance(S{p2, p3}, S{p6, p7}, CGAL::squared_distance(p3, p6)); check_squared_distance(S{p2, p3}, S{p7, p6}, CGAL::squared_distance(p3, p6)); check_squared_distance(S{p3, p2}, S{p6, p7}, CGAL::squared_distance(p3, p6)); @@ -321,7 +306,6 @@ private: const P p8 = p2 + lambda_8 * (p3 - p2); const double lambda_9 = r.get_double(-M, M); const P p9 = p2 + lambda_9 * (p3 - p2); - std::cout << "p2389 " << p2 << " " << p3 << " " << p8 << " " << p9 << std::endl; S s89(p8, p9); S s32(p3, p2); @@ -336,12 +320,15 @@ private: (std::min)(CGAL::squared_distance(p3, p8), CGAL::squared_distance(p3, p9)))); +#ifdef CGAL_USE_GTE_AS_SANITY_CHECK gte::DCPQuery, gte::Segment<3, FT> > GTE_SS_checker; gte::Segment<3, FT> gte_s1{{p8.x(), p8.y(), p8.z()}, {p9.x(), p9.y(), p9.z()}}; gte::Segment<3, FT> gte_s2{{p3.x(), p3.y(), p3.z()}, {p2.x(), p2.y(), p2.z()}}; auto gte_res = GTE_SS_checker(gte_s1, gte_s2); + std::cout << "-------" << std::endl; std::cout << "old: " << CGAL::internal::squared_distance_old(s89, s32, K()) << std::endl; std::cout << "dist (GTE) : " << gte_res.sqrDistance << std::endl; +#endif // Because do_intersect() with constructions is likely to return 'false' even for overlaps assert(are_equal(CGAL::squared_distance(s89, s32), result, false /*verbose*/) || @@ -352,7 +339,7 @@ private: S s1{p0, p1}, s2{p2, p3}; do_intersect_check(s1, s2); - // GTE ----------------------------------------------------------------------------------------- +#ifdef CGAL_USE_GTE_AS_SANITY_CHECK gte::DCPQuery, gte::Segment<3, FT> > GTE_SS_checker; gte::Segment<3, FT> gte_s1{{p0.x(), p0.y(), p0.z()}, {p1.x(), p1.y(), p1.z()}}; gte::Segment<3, FT> gte_s2{{p2.x(), p2.y(), p2.z()}, {p3.x(), p3.y(), p3.z()}}; @@ -361,6 +348,7 @@ private: std::cout << "dist (CGAL) : " << CGAL::squared_distance(s1, s2) << std::endl; std::cout << "dist (GTE) : " << gte_res.sqrDistance << std::endl; assert(are_equal(CGAL::squared_distance(s1, s2), gte_res.sqrDistance)); +#endif } // a few brute force checks: sample a segments and use squared_distance(P3, S3) @@ -385,8 +373,8 @@ private: upper_bound = sqd; } - // bit ugly, but if constructions are not exact, building tp introduces some error - if(!exact) + // bit ugly, but if constructions are not exact, building `tp` introduces some error + if(epsilon != 0) upper_bound *= (1 + 1e-10); check_squared_distance_with_bound(s01, s23, upper_bound); @@ -397,14 +385,14 @@ private: { // Note : the value is not verified by hand std::cout << "Point - Ray" << std::endl; - check_squared_distance(p( -8, -7, 0), R{p(23, -27, 2), p( -17, 16, 2)}, 86.3685); + check_squared_distance_with_bound(p( -8, -7, 0), R{p(23, -27, 2), p( -17, 16, 2)}, 86.368512613); } void R_R() { // Note : the values are not verified by hand std::cout << "Ray - Ray" << std::endl; - check_squared_distance(R{p( 0, 0, 30), p( 0, 30, 30)}, R{p(100, -100, 0), p( 200, 1, 0)}, 20899.5); + check_squared_distance_with_bound(R{p( 0, 0, 30), p( 0, 30, 30)}, R{p(100, -100, 0), p( 200, 1, 0)}, 20899.504975002); check_squared_distance(R{p( 1, 0, 0), p( 0, 0, 0)}, R{p( 1, 3, 3), p( 0, 0, 3)}, 9); check_squared_distance(R{p( 0, 0, 0), p( 1, 0, 0)}, R{p( 0, 0, 2), p( -1, 0, 2)}, 4); } @@ -413,15 +401,15 @@ private: { // Note : the values are not verified by hand std::cout << "Segment - Ray" << std::endl; - check_squared_distance(S{p( 0, 0, 30), p( 0, 30, 30)}, R{p(100, -100, 0), p( 200, 1, 0)}, 20899.5); + check_squared_distance_with_bound(S{p( 0, 0, 30), p( 0, 30, 30)}, R{p(100, -100, 0), p( 200, 1, 0)}, 20899.504975002); } void R_L() { // Note : the values are not verified by hand std::cout << "Ray - Line" << std::endl; + check_squared_distance_with_bound(R{p( 0, 0, 30), p( 0, 30, 30)}, L{p(100, -100, 0), p( 200, 1, 0)}, 20899.504975002); check_squared_distance(R{p(10, 0, 0), p( 20, 0, 0)}, L{p( 0, 0, 3), p( 0, 3, 3)}, 109); - check_squared_distance(R{p( 0, 0, 30), p( 0, 30, 30)}, L{p(100, -100, 0), p( 200, 1, 0)}, 20899.5); check_squared_distance(R{p( 1, 0, 0), p( 0, 0, 0)}, L{p( 1, 3, 3), p( 0, 0, 3)}, 9); check_squared_distance(R{p( 0, 0, 0), p( 1, 0, 0)}, L{p( 0, 0, 2), p( -1, 0, 2)}, 4); } @@ -484,7 +472,7 @@ private: std::cout << "Plane - Plane" << std::endl; Pl p1(0, 1, 0, 0); typename K::Vector_3 v = -p1.orthogonal_vector(); - v /= CGAL::sqrt(v.squared_length()); + v /= CGAL::approximate_sqrt(v.squared_length()); Pl p2 = Pl(0,-1,0,6); check_squared_distance(p1,p2, 36); check_squared_distance(Pl(-2, 1, 1, 0), Pl(2, 1, 3, 0), 0); @@ -620,32 +608,19 @@ private: T tr1{p0, p1, p2}, tr2{p3, p4, p5}; do_intersect_check(tr1, tr2); - // PQP ----------------------------------------------------------------------------------------- -// CGAL::PQP_Checker PQP_checker; -// auto pqp_res = PQP_checker(p0, p1, p2, p3, p4, p5); -// std::cout << "dist (PQP) : " << pqp_res << std::endl; - - // GTE ----------------------------------------------------------------------------------------- -// gte::DCPQuery, gte::Triangle3 > GTE_TT_checker; -// gte::Triangle3 gte_tr1{{CGAL::to_double(p0.x()), CGAL::to_double(p0.y()), CGAL::to_double(p0.z())}, -// {CGAL::to_double(p1.x()), CGAL::to_double(p1.y()), CGAL::to_double(p1.z())}, -// {CGAL::to_double(p2.x()), CGAL::to_double(p2.y()), CGAL::to_double(p2.z())}}; -// gte::Triangle3 gte_tr2{{CGAL::to_double(p3.x()), CGAL::to_double(p3.y()), CGAL::to_double(p3.z())}, -// {CGAL::to_double(p4.x()), CGAL::to_double(p4.y()), CGAL::to_double(p4.z())}, -// {CGAL::to_double(p5.x()), CGAL::to_double(p5.y()), CGAL::to_double(p5.z())}}; -// auto gte_res = GTE_TT_checker(gte_tr1, gte_tr2); - +#ifdef CGAL_USE_GTE_AS_SANITY_CHECK gte::DCPQuery, gte::Triangle3 > GTE_TT_checker; gte::Triangle3 gte_tr1{{p0.x(), p0.y(), p0.z()}, {p1.x(), p1.y(), p1.z()}, {p2.x(), p2.y(), p2.z()}}; gte::Triangle3 gte_tr2{{p3.x(), p3.y(), p3.z()}, {p4.x(), p4.y(), p4.z()}, {p5.x(), p5.y(), p5.z()}}; auto gte_res = GTE_TT_checker(gte_tr1, gte_tr2); -// std::cout << "dist (CGAL) : " << CGAL::squared_distance(tr1, tr2) << std::endl; -// std::cout << "dist (GTE) : " << gte_res.sqrDistance << std::endl; -// std::cout << "diff CGAL GTE : " << (gte_res.sqrDistance - CGAL::squared_distance(tr1, tr2)) << std::endl; -// std::cout << "diff CGAL PQP : " << (pqp_res - CGAL::squared_distance(tr1, tr2)) << std::endl; - if(!are_equal(CGAL::squared_distance(tr1, tr2), gte_res.sqrDistance)) - std::cerr <<"uh-oh" << std::endl; + std::cout << "dist (CGAL) : " << CGAL::squared_distance(tr1, tr2) << std::endl; + std::cout << "dist (GTE) : " << gte_res.sqrDistance << std::endl; + std::cout << "diff CGAL GTE : " << (gte_res.sqrDistance - CGAL::squared_distance(tr1, tr2)) << std::endl; + + // don't assert on purpose, GTE has slightly (10^-30 different results, even with an exact NT) + are_equal(CGAL::squared_distance(tr1, tr2), gte_res.sqrDistance); +#endif } } @@ -654,28 +629,29 @@ public: { std::cout << "Kernel: " << typeid(K).name() << std::endl; -// P_P(); -// P_S(); -// P_R(); -// P_L(); -// P_T(); -// P_Pl(); + P_P(); + P_S(); + P_R(); + P_L(); + P_T(); + P_Pl(); + P_Tet(); S_S(); -// S_R(); -// S_L(); -// S_Pl(); + S_R(); + S_L(); + S_Pl(); -// R_R(); -// R_L(); -// R_Pl(); + R_R(); + R_L(); + R_Pl(); -// L_L(); -// L_Pl(); + L_L(); + L_Pl(); T_T(); -// Pl_Pl(); + Pl_Pl(); } }; @@ -689,11 +665,15 @@ int main() CGAL::Random r; std::cout << "random seed = " << r.get_seed() << std::endl; -// Test >(r, false).run(); -// Test >(r, false).run(); + // @todo Some tests are too difficult for these kernels +// Test >(r, 1e-5).run(); +// Test >(r, 1e-5).run(); +// Test > >(r, 1e-5).run(); -// Test(r, false).run(); - Test(r, true).run(); + const double epick_eps = 10 * std::numeric_limits::epsilon(); + Test(r, epick_eps).run(); + + Test(r, 0).run(); std::cout << "Done!" << std::endl; From 27069d423c8d4299db4f4364b4b69824969699e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 12 Mar 2021 11:55:00 +0100 Subject: [PATCH 05/23] Update header includes --- .../Triangle_3_Sphere_3_do_intersect.h | 20 ++++++++++--------- .../squared_distance_Point_3_Triangle_3.h | 3 +-- .../include/CGAL/statistics_helpers.h | 3 ++- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Sphere_3_do_intersect.h b/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Sphere_3_do_intersect.h index 72df357bd03..ce578a114cf 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Sphere_3_do_intersect.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Sphere_3_do_intersect.h @@ -13,7 +13,9 @@ #ifndef CGAL_TRIANGLE_3_SPHERE_3_DO_INTERSECT_H #define CGAL_TRIANGLE_3_SPHERE_3_DO_INTERSECT_H -#include +#include +#include +#include #include namespace CGAL { @@ -77,42 +79,42 @@ template inline typename K::Boolean do_intersect(const typename K::Sphere_3 &sp, - const typename K::Ray_3 &lin, + const typename K::Ray_3 &ray, const K & /* k */) { - return squared_distance(sp.center(), lin) <= sp.squared_radius(); + return squared_distance(sp.center(), ray) <= sp.squared_radius(); } template inline typename K::Boolean -do_intersect(const typename K::Ray_3 &lin, +do_intersect(const typename K::Ray_3 &ray, const typename K::Sphere_3 &sp, const K & /* k */) { - return squared_distance(sp.center(), lin) <= sp.squared_radius(); + return squared_distance(sp.center(), ray) <= sp.squared_radius(); } template inline typename K::Boolean do_intersect(const typename K::Sphere_3 &sp, - const typename K::Segment_3 &lin, + const typename K::Segment_3 &seg, const K & /* k */) { - return squared_distance(sp.center(), lin) <= sp.squared_radius(); + return squared_distance(sp.center(), seg) <= sp.squared_radius(); } template inline typename K::Boolean -do_intersect(const typename K::Segment_3 &lin, +do_intersect(const typename K::Segment_3 &seg, const typename K::Sphere_3 &sp, const K & /* k */) { - return squared_distance(sp.center(), lin) <= sp.squared_radius(); + return squared_distance(sp.center(), seg) <= sp.squared_radius(); } } // namespace internal diff --git a/Mesh_3/include/CGAL/Mesh_3/squared_distance_Point_3_Triangle_3.h b/Mesh_3/include/CGAL/Mesh_3/squared_distance_Point_3_Triangle_3.h index 5e8595daf22..e3fb8c3b259 100644 --- a/Mesh_3/include/CGAL/Mesh_3/squared_distance_Point_3_Triangle_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/squared_distance_Point_3_Triangle_3.h @@ -16,7 +16,6 @@ #include - -#include +#include #endif // CGAL_SQUARED_DISTANCE_POINT_3_TRIANGLE_3_H diff --git a/Polyhedron/demo/Polyhedron/include/CGAL/statistics_helpers.h b/Polyhedron/demo/Polyhedron/include/CGAL/statistics_helpers.h index 11eb9c99e5e..d7a9c3b9010 100644 --- a/Polyhedron/demo/Polyhedron/include/CGAL/statistics_helpers.h +++ b/Polyhedron/demo/Polyhedron/include/CGAL/statistics_helpers.h @@ -1,7 +1,8 @@ #ifndef POLYHEDRON_DEMO_STATISTICS_HELPERS_H #define POLYHEDRON_DEMO_STATISTICS_HELPERS_H -#include +#include +#include #include #include From ba76299e4f911afc15713b0eaa99074a1f48df79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 12 Mar 2021 12:49:14 +0100 Subject: [PATCH 06/23] Add missing include --- Distance_3/include/CGAL/squared_distance_Ray_3_Ray_3.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Distance_3/include/CGAL/squared_distance_Ray_3_Ray_3.h b/Distance_3/include/CGAL/squared_distance_Ray_3_Ray_3.h index 29ae66a63f9..1494f6e40e7 100644 --- a/Distance_3/include/CGAL/squared_distance_Ray_3_Ray_3.h +++ b/Distance_3/include/CGAL/squared_distance_Ray_3_Ray_3.h @@ -20,6 +20,7 @@ #include #include +#include namespace CGAL { namespace internal { From 2adddeacc173d594435fa4edc6efa679596bdf27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 12 Mar 2021 13:08:16 +0100 Subject: [PATCH 07/23] Add missing includes --- Cartesian_kernel/include/CGAL/Cartesian/function_objects.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h index ac34f9564b1..bc8b47e102e 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h @@ -23,6 +23,8 @@ #include #include #include +#include +#include namespace CGAL { From 596f3e3013c100e7ca33bbb91bfbe2510fe2cb61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 12 Mar 2021 14:34:36 +0100 Subject: [PATCH 08/23] Fix namespaces --- .../include/CGAL/Cartesian/function_objects.h | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h index bc8b47e102e..9657a137946 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h @@ -480,15 +480,15 @@ namespace CartesianKernelFunctors { { Vector_3 diff = construct_vector(seg1.source(), pt); Vector_3 segvec = construct_vector(seg1.source(), seg1.target()); - RT d = wdot(diff,segvec, k); + RT d = CGAL::internal::wdot(diff,segvec, k); if (d <= (RT)0){ d1 = (FT(diff*diff)); }else{ - RT e = wdot(segvec,segvec, k); + RT e = CGAL::internal::wdot(segvec,segvec, k); if (d > e){ - d1 = squared_distance(pt, seg1.target(), k); + d1 = CGAL::internal::squared_distance(pt, seg1.target(), k); } else{ - Vector_3 wcr = wcross(segvec, diff, k); + Vector_3 wcr = CGAL::internal::wcross(segvec, diff, k); d1 = FT(wcr*wcr); e1 = e; } @@ -498,15 +498,15 @@ namespace CartesianKernelFunctors { { Vector_3 diff = construct_vector(seg2.source(), pt); Vector_3 segvec = construct_vector(seg2.source(), seg2.target()); - RT d = wdot(diff,segvec, k); + RT d = CGAL::internal::wdot(diff,segvec, k); if (d <= (RT)0){ d2 = (FT(diff*diff)); }else{ - RT e = wdot(segvec,segvec, k); + RT e = CGAL::internal::wdot(segvec,segvec, k); if (d > e){ - d2 = squared_distance(pt, seg2.target(), k); + d2 = CGAL::internal::squared_distance(pt, seg2.target(), k); } else{ - Vector_3 wcr = wcross(segvec, diff, k); + Vector_3 wcr = CGAL::internal::wcross(segvec, diff, k); d2 = FT(wcr*wcr); e2 = e; } @@ -531,20 +531,20 @@ namespace CartesianKernelFunctors { RT e2 = RT(1); // assert that the segment is valid (non zero length). - FT d1 = squared_distance(pt, pt2, k); + FT d1 = CGAL::internal::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); + RT d = CGAL::internal::wdot(diff,segvec, k); if (d <= (RT)0){ d2 = (FT(diff*diff)); }else{ - RT e = wdot(segvec,segvec, k); + RT e = CGAL::internal::wdot(segvec,segvec, k); if (d > e){ - d2 = squared_distance(pt, seg.target(), k); + d2 = CGAL::internal::squared_distance(pt, seg.target(), k); } else{ - Vector_3 wcr = wcross(segvec, diff, k); + Vector_3 wcr = CGAL::internal::wcross(segvec, diff, k); d2 = FT(wcr*wcr); e2 = e; } From cf55bca4b9f490fbfdc4e71d070375c3d2b38a46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 12 Mar 2021 15:19:55 +0100 Subject: [PATCH 09/23] Add missing includes --- Distance_3/include/CGAL/squared_distance_Point_3_Triangle_3.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Triangle_3.h b/Distance_3/include/CGAL/squared_distance_Point_3_Triangle_3.h index bde0aa1511f..efb25b4895e 100644 --- a/Distance_3/include/CGAL/squared_distance_Point_3_Triangle_3.h +++ b/Distance_3/include/CGAL/squared_distance_Point_3_Triangle_3.h @@ -17,6 +17,9 @@ #ifndef CGAL_DISTANCE_3_POINT_3_TRIANGLE_3_H #define CGAL_DISTANCE_3_POINT_3_TRIANGLE_3_H +#include +#include + #include #include From 28377db26139d64ab46a8b0911ebab79f991b0b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 25 Mar 2021 10:48:26 +0100 Subject: [PATCH 10/23] Add T3/T3 to the supported CGAL::squared_distance combinations --- Kernel_23/doc/Kernel_23/CGAL/squared_distance_2.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Kernel_23/doc/Kernel_23/CGAL/squared_distance_2.h b/Kernel_23/doc/Kernel_23/CGAL/squared_distance_2.h index 5927a121da3..91e332a1bdc 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/squared_distance_2.h +++ b/Kernel_23/doc/Kernel_23/CGAL/squared_distance_2.h @@ -30,8 +30,7 @@ In 2D, the types `Type1` and `Type2` can be any of the following: as well as any combination of `Kernel::Point_2` and `Kernel::Weighted_point_2` -In 3D, the types `Type1` and `Type2` can be any of the -following: +In 3D, the types `Type1` and `Type2` can be any of the following: - `Point_3` - `Line_3` @@ -39,9 +38,12 @@ following: - `Segment_3` - `Plane_3` -as well as combinations `Point_3`/`Triangle_3`, -and `Weighted_point_3`/`Triangle_3`, as well as `Point_3`/`Tetrahedron_3`, -and `Weighted_point_3`/`Tetrahedron_3` +as well as the following combinations: +- `Point_3`/`Triangle_3` +- `Point_3`/`Tetrahedron_3` +- `Weighted_point_3`/`Triangle_3` +- `Weighted_point_3`/`Tetrahedron_3` +- `Triangle_3`/`Triangle_3` \sa `compare_distance_to_point_grp` \sa `compare_signed_distance_to_line_grp` From e18e75f4aab8ca7215e1d3f0048604b72d0b06cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 26 Mar 2021 09:38:52 +0100 Subject: [PATCH 11/23] Remove unused functors --- .../include/CGAL/squared_distance_Triangle_3_Triangle_3.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h b/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h index 7d83415a38d..f7e292ece21 100644 --- a/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h +++ b/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h @@ -99,8 +99,6 @@ test_vertex_triangle(const typename K::Triangle_3& tr1, typename K::Compute_scalar_product_3 scalar_product = k.compute_scalar_product_3_object(); typename K::Construct_cross_product_vector_3 cross_product = k.construct_cross_product_vector_3_object(); - typename K::Construct_scaled_vector_3 scale_vector = k.construct_scaled_vector_3_object(); - typename K::Construct_translated_point_3 translate = k.construct_translated_point_3_object(); typename K::Construct_vector_3 vector = k.construct_vector_3_object(); typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); From 8bdba67281b64a52bc9f68fe89f467b70219545c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 26 Mar 2021 09:39:15 +0100 Subject: [PATCH 12/23] Fix double -> int loss --- Distance_3/test/Distance_3/test_distance_3.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Distance_3/test/Distance_3/test_distance_3.cpp b/Distance_3/test/Distance_3/test_distance_3.cpp index 3d219582b6e..4354d158286 100644 --- a/Distance_3/test/Distance_3/test_distance_3.cpp +++ b/Distance_3/test/Distance_3/test_distance_3.cpp @@ -212,16 +212,16 @@ private: // coplanar segments (hardcoded) double z = std::sqrt(2.); - P p0 = p(-1, 0, z); - P p1 = p( 1, 0, z); + P p0{-1, 0, z}; + P p1{ 1, 0, z}; // translations of (0, -1, z) -- (0, 1, z) to have all variations of x&y (<0, [0;1]; >1) in the code for(int j=-2;j<4; j+=2) { for(int k=-3;k<3; k+=2) { - P p2 = p(j, k, z); - P p3 = p(j, k+2, z); + P p2{j, k, z}; + P p3{j, k+2, z}; // to explicit the expected distances if(j == -2 && k == -3) From 33d7501a3e14de145acc788331c48618696029b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 31 Mar 2021 12:17:24 +0200 Subject: [PATCH 13/23] Fix conversion warnings --- .../include/CGAL/squared_distance_Triangle_3_Triangle_3.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h b/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h index f7e292ece21..b074553ae3e 100644 --- a/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h +++ b/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h @@ -126,13 +126,13 @@ test_vertex_triangle(const typename K::Triangle_3& tr1, return std::make_pair(0, false); std::for_each(sps.begin(), sps.end(), [](FT& v) { v = abs(v); }); - auto min_pos = std::min_element(sps.begin(), sps.end()); - auto min_id = std::distance(sps.begin(), min_pos); + const auto min_pos = std::min_element(sps.begin(), sps.end()); + const std::size_t min_id = static_cast(std::distance(sps.begin(), min_pos)); if(sps[min_id] > 0) are_triangles_known_to_be_disjoint = true; - const Point_3& x1 = vertex(tr1, min_id); + const Point_3& x1 = vertex(tr1, static_cast(min_id)); if(on_left_of_triangle_edge(x1, n2, p2, q2, k) && on_left_of_triangle_edge(x1, n2, q2, r2, k) && From 6d3eacd2cd45f767b2d691b428dfff29421bb467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 6 Apr 2021 12:48:39 +0200 Subject: [PATCH 14/23] Fix namespaces --- .../include/CGAL/squared_distance_Triangle_3_Triangle_3.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h b/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h index b074553ae3e..ac1dbcbb24c 100644 --- a/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h +++ b/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h @@ -134,12 +134,12 @@ test_vertex_triangle(const typename K::Triangle_3& tr1, const Point_3& x1 = vertex(tr1, static_cast(min_id)); - if(on_left_of_triangle_edge(x1, n2, p2, q2, k) && - on_left_of_triangle_edge(x1, n2, q2, r2, k) && - on_left_of_triangle_edge(x1, n2, r2, p2, k)) + if(CGAL::internal::on_left_of_triangle_edge(x1, n2, p2, q2, k) && + CGAL::internal::on_left_of_triangle_edge(x1, n2, q2, r2, k) && + CGAL::internal::on_left_of_triangle_edge(x1, n2, r2, p2, k)) { // the projection of `x1` is inside the triangle - return std::make_pair(squared_distance_to_plane(n2, vector(p2, x1), k), true); + return std::make_pair(CGAL::internal::squared_distance_to_plane(n2, vector(p2, x1), k), true); } return std::make_pair(0, false); From 306fbaacb3ed51d21b5f3ec65172c3be8a8fca48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 6 Apr 2021 16:12:53 +0200 Subject: [PATCH 15/23] Fix compilation with gmpxx --- .../CGAL/squared_distance_Segment_3_Segment_3.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h b/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h index e2fb59ae0fa..ed967bce474 100644 --- a/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h +++ b/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h @@ -80,7 +80,7 @@ squared_distance(const typename K::Segment_3& s1, CGAL_assertion(d != 0); res.x = 0; - res.y = boost::algorithm::clamp(f/d, 0, 1); // (f - x*c) / d + res.y = boost::algorithm::clamp(f/d, 0, 1); // (f - x*c) / d res.squared_distance = CGAL::squared_distance(p1, p2 + res.y*v2); return res; @@ -90,7 +90,7 @@ squared_distance(const typename K::Segment_3& s1, CGAL_assertion(a != 0); res.y = 0; - res.x = boost::algorithm::clamp(e/a, 0, 1); // (e + y*c) / a + res.x = boost::algorithm::clamp(e/a, 0, 1); // (e + y*c) / a res.squared_distance = CGAL::squared_distance(p1 + res.x*v1, p2); return res; @@ -102,14 +102,14 @@ squared_distance(const typename K::Segment_3& s1, if(det == 0) res.x = 0; else - res.x = boost::algorithm::clamp((e*d - b*f) / det, 0, 1); + res.x = boost::algorithm::clamp((e*d - b*f) / det, 0, 1); FT xc = res.x*c; // res.y = (f - xc) / d, by definition, but building it up more efficiently if(f > xc) // y < 0 <=> f - xc / d < 0 <=> f - xc > 0 (since d is -||v2||) { res.y = 0; - res.x = boost::algorithm::clamp(e/a, 0, 1); // (e + y*c) / a + res.x = boost::algorithm::clamp(e/a, 0, 1); // (e + y*c) / a } else // y >= 0 { @@ -117,7 +117,7 @@ squared_distance(const typename K::Segment_3& s1, if(n < d) // y > 1 <=> n / d > 1 <=> n < d (once again, important to note that d is negative!) { res.y = 1; - res.x = boost::algorithm::clamp((e + c) / a, 0, 1); // (e + y*c) / a + res.x = boost::algorithm::clamp((e + c) / a, 0, 1); // (e + y*c) / a } else // 0 <= y <= 1 { From 7b1dfd498375bc5b2c2dc1cfb84f44173881cd9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 6 Apr 2021 16:25:04 +0200 Subject: [PATCH 16/23] Tiny assertion improvements --- .../include/CGAL/squared_distance_Segment_3_Segment_3.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h b/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h index ed967bce474..cc19b069204 100644 --- a/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h +++ b/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h @@ -77,7 +77,7 @@ squared_distance(const typename K::Segment_3& s1, return res; } - CGAL_assertion(d != 0); + CGAL_assertion(d < 0); res.x = 0; res.y = boost::algorithm::clamp(f/d, 0, 1); // (f - x*c) / d @@ -87,7 +87,7 @@ squared_distance(const typename K::Segment_3& s1, } else if(p2 == q2) { - CGAL_assertion(a != 0); + CGAL_assertion(a > 0); res.y = 0; res.x = boost::algorithm::clamp(e/a, 0, 1); // (e + y*c) / a From 5deb509374a91fe485241e2b4d207cd9f23592d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 12 Apr 2021 14:42:44 +0200 Subject: [PATCH 17/23] Move to Distance_3/X_Y.h rather than squared_distance_X_Y.h (as Intersections) --- .../include/CGAL/Cartesian/function_objects.h | 4 +- .../Line_3_Line_3.h} | 2 +- .../Line_3_Plane_3.h} | 4 +- .../Plane_3_Plane_3.h} | 4 +- .../Point_3_Line_3.h} | 2 +- .../Point_3_Plane_3.h} | 2 +- .../Point_3_Point_3.h} | 0 .../Point_3_Ray_3.h} | 2 +- .../Point_3_Segment_3.h} | 4 +- .../Point_3_Tetrahedron_3.h} | 2 +- .../Point_3_Triangle_3.h} | 4 +- .../Point_3_Weighted_point_3.h} | 2 +- .../Ray_3_Line_3.h} | 2 +- .../Ray_3_Plane_3.h} | 2 +- .../Ray_3_Ray_3.h} | 2 +- .../Segment_3_Line_3.h} | 2 +- .../Segment_3_Plane_3.h} | 2 +- .../Segment_3_Ray_3.h} | 10 ++--- .../Segment_3_Segment_3.h} | 4 +- .../Triangle_3_Triangle_3.h} | 4 +- .../Weighted_point_3_Weighted_point_3.h} | 2 +- .../internal/squared_distance_utils_3.h | 0 Distance_3/include/CGAL/squared_distance_3.h | 40 +++++++++---------- .../Triangle_3_Sphere_3_do_intersect.h | 6 +-- ...tialize_triangulation_from_labeled_image.h | 2 +- .../squared_distance_Point_3_Triangle_3.h | 2 +- .../include/CGAL/statistics_helpers.h | 4 +- 27 files changed, 58 insertions(+), 58 deletions(-) rename Distance_3/include/CGAL/{squared_distance_Line_3_Line_3.h => Distance_3/Line_3_Line_3.h} (95%) rename Distance_3/include/CGAL/{squared_distance_Line_3_Plane_3.h => Distance_3/Line_3_Plane_3.h} (94%) rename Distance_3/include/CGAL/{squared_distance_Plane_3_Plane_3.h => Distance_3/Plane_3_Plane_3.h} (90%) rename Distance_3/include/CGAL/{squared_distance_Point_3_Line_3.h => Distance_3/Point_3_Line_3.h} (96%) rename Distance_3/include/CGAL/{squared_distance_Point_3_Plane_3.h => Distance_3/Point_3_Plane_3.h} (96%) rename Distance_3/include/CGAL/{squared_distance_Point_3_Point_3.h => Distance_3/Point_3_Point_3.h} (100%) rename Distance_3/include/CGAL/{squared_distance_Point_3_Ray_3.h => Distance_3/Point_3_Ray_3.h} (96%) rename Distance_3/include/CGAL/{squared_distance_Point_3_Segment_3.h => Distance_3/Point_3_Segment_3.h} (96%) rename Distance_3/include/CGAL/{squared_distance_Point_3_Tetrahedron_3.h => Distance_3/Point_3_Tetrahedron_3.h} (98%) rename Distance_3/include/CGAL/{squared_distance_Point_3_Triangle_3.h => Distance_3/Point_3_Triangle_3.h} (97%) rename Distance_3/include/CGAL/{squared_distance_Point_3_Weighted_point_3.h => Distance_3/Point_3_Weighted_point_3.h} (95%) rename Distance_3/include/CGAL/{squared_distance_Ray_3_Line_3.h => Distance_3/Ray_3_Line_3.h} (97%) rename Distance_3/include/CGAL/{squared_distance_Ray_3_Plane_3.h => Distance_3/Ray_3_Plane_3.h} (97%) rename Distance_3/include/CGAL/{squared_distance_Ray_3_Ray_3.h => Distance_3/Ray_3_Ray_3.h} (98%) rename Distance_3/include/CGAL/{squared_distance_Segment_3_Line_3.h => Distance_3/Segment_3_Line_3.h} (97%) rename Distance_3/include/CGAL/{squared_distance_Segment_3_Plane_3.h => Distance_3/Segment_3_Plane_3.h} (97%) rename Distance_3/include/CGAL/{squared_distance_Segment_3_Ray_3.h => Distance_3/Segment_3_Ray_3.h} (95%) rename Distance_3/include/CGAL/{squared_distance_Segment_3_Segment_3.h => Distance_3/Segment_3_Segment_3.h} (98%) rename Distance_3/include/CGAL/{squared_distance_Triangle_3_Triangle_3.h => Distance_3/Triangle_3_Triangle_3.h} (98%) rename Distance_3/include/CGAL/{squared_distance_Weighted_point_3_Weighted_point_3.h => Distance_3/Weighted_point_3_Weighted_point_3.h} (94%) rename Distance_3/include/CGAL/{ => Distance_3}/internal/squared_distance_utils_3.h (100%) diff --git a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h index 9657a137946..fe06dc9af43 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h @@ -23,8 +23,8 @@ #include #include #include -#include -#include +#include +#include namespace CGAL { diff --git a/Distance_3/include/CGAL/squared_distance_Line_3_Line_3.h b/Distance_3/include/CGAL/Distance_3/Line_3_Line_3.h similarity index 95% rename from Distance_3/include/CGAL/squared_distance_Line_3_Line_3.h rename to Distance_3/include/CGAL/Distance_3/Line_3_Line_3.h index 7f9098f4815..88a69f727e3 100644 --- a/Distance_3/include/CGAL/squared_distance_Line_3_Line_3.h +++ b/Distance_3/include/CGAL/Distance_3/Line_3_Line_3.h @@ -17,7 +17,7 @@ #ifndef CGAL_DISTANCE_3_LINE_3_LINE_3_H #define CGAL_DISTANCE_3_LINE_3_LINE_3_H -#include +#include #include diff --git a/Distance_3/include/CGAL/squared_distance_Line_3_Plane_3.h b/Distance_3/include/CGAL/Distance_3/Line_3_Plane_3.h similarity index 94% rename from Distance_3/include/CGAL/squared_distance_Line_3_Plane_3.h rename to Distance_3/include/CGAL/Distance_3/Line_3_Plane_3.h index 10becb28625..69bea4dcbe5 100644 --- a/Distance_3/include/CGAL/squared_distance_Line_3_Plane_3.h +++ b/Distance_3/include/CGAL/Distance_3/Line_3_Plane_3.h @@ -17,8 +17,8 @@ #ifndef CGAL_DISTANCE_3_LINE_3_PLANE_3_H #define CGAL_DISTANCE_3_LINE_3_PLANE_3_H -#include -#include +#include +#include #include #include diff --git a/Distance_3/include/CGAL/squared_distance_Plane_3_Plane_3.h b/Distance_3/include/CGAL/Distance_3/Plane_3_Plane_3.h similarity index 90% rename from Distance_3/include/CGAL/squared_distance_Plane_3_Plane_3.h rename to Distance_3/include/CGAL/Distance_3/Plane_3_Plane_3.h index dcfa26de7c3..8feada6266d 100644 --- a/Distance_3/include/CGAL/squared_distance_Plane_3_Plane_3.h +++ b/Distance_3/include/CGAL/Distance_3/Plane_3_Plane_3.h @@ -17,8 +17,8 @@ #ifndef CGAL_DISTANCE_3_PLANE_3_PLANE_3_H #define CGAL_DISTANCE_3_PLANE_3_PLANE_3_H -#include -#include +#include +#include #include diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Line_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Line_3.h similarity index 96% rename from Distance_3/include/CGAL/squared_distance_Point_3_Line_3.h rename to Distance_3/include/CGAL/Distance_3/Point_3_Line_3.h index 5af9a9ab14e..6ac84fc2223 100644 --- a/Distance_3/include/CGAL/squared_distance_Point_3_Line_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Line_3.h @@ -17,7 +17,7 @@ #ifndef CGAL_DISTANCE_3_POINT_3_LINE_3_H #define CGAL_DISTANCE_3_POINT_3_LINE_3_H -#include +#include #include #include diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Plane_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Plane_3.h similarity index 96% rename from Distance_3/include/CGAL/squared_distance_Point_3_Plane_3.h rename to Distance_3/include/CGAL/Distance_3/Point_3_Plane_3.h index d327e11dc9a..6d0da93dfe0 100644 --- a/Distance_3/include/CGAL/squared_distance_Point_3_Plane_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Plane_3.h @@ -17,7 +17,7 @@ #ifndef CGAL_DISTANCE_3_POINT_3_PLANE_3_H #define CGAL_DISTANCE_3_POINT_3_PLANE_3_H -#include +#include #include #include diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Point_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Point_3.h similarity index 100% rename from Distance_3/include/CGAL/squared_distance_Point_3_Point_3.h rename to Distance_3/include/CGAL/Distance_3/Point_3_Point_3.h diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Ray_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Ray_3.h similarity index 96% rename from Distance_3/include/CGAL/squared_distance_Point_3_Ray_3.h rename to Distance_3/include/CGAL/Distance_3/Point_3_Ray_3.h index 0c943ce7c71..a3c4ab12dc9 100644 --- a/Distance_3/include/CGAL/squared_distance_Point_3_Ray_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Ray_3.h @@ -17,7 +17,7 @@ #ifndef CGAL_DISTANCE_3_POINT_3_RAY_3_H #define CGAL_DISTANCE_3_POINT_3_RAY_3_H -#include +#include #include #include diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Segment_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Segment_3.h similarity index 96% rename from Distance_3/include/CGAL/squared_distance_Point_3_Segment_3.h rename to Distance_3/include/CGAL/Distance_3/Point_3_Segment_3.h index 010ef89f852..a28dd10a33c 100644 --- a/Distance_3/include/CGAL/squared_distance_Point_3_Segment_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Segment_3.h @@ -17,8 +17,8 @@ #ifndef CGAL_DISTANCE_3_POINT_3_SEGMENT_3_H #define CGAL_DISTANCE_3_POINT_3_SEGMENT_3_H -#include -#include +#include +#include #include #include diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Tetrahedron_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Tetrahedron_3.h similarity index 98% rename from Distance_3/include/CGAL/squared_distance_Point_3_Tetrahedron_3.h rename to Distance_3/include/CGAL/Distance_3/Point_3_Tetrahedron_3.h index 8accd9b7d30..c2bedd0aba1 100644 --- a/Distance_3/include/CGAL/squared_distance_Point_3_Tetrahedron_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Tetrahedron_3.h @@ -17,7 +17,7 @@ #ifndef CGAL_DISTANCE_3_POINT_3_TETRAHEDRON_3_H #define CGAL_DISTANCE_3_POINT_3_TETRAHEDRON_3_H -#include +#include #include #include diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Triangle_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Triangle_3.h similarity index 97% rename from Distance_3/include/CGAL/squared_distance_Point_3_Triangle_3.h rename to Distance_3/include/CGAL/Distance_3/Point_3_Triangle_3.h index efb25b4895e..7f1c4d5acdd 100644 --- a/Distance_3/include/CGAL/squared_distance_Point_3_Triangle_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Triangle_3.h @@ -17,8 +17,8 @@ #ifndef CGAL_DISTANCE_3_POINT_3_TRIANGLE_3_H #define CGAL_DISTANCE_3_POINT_3_TRIANGLE_3_H -#include -#include +#include +#include #include #include diff --git a/Distance_3/include/CGAL/squared_distance_Point_3_Weighted_point_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Weighted_point_3.h similarity index 95% rename from Distance_3/include/CGAL/squared_distance_Point_3_Weighted_point_3.h rename to Distance_3/include/CGAL/Distance_3/Point_3_Weighted_point_3.h index 934cfaedf96..5f19203a64b 100644 --- a/Distance_3/include/CGAL/squared_distance_Point_3_Weighted_point_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Weighted_point_3.h @@ -17,7 +17,7 @@ #ifndef CGAL_DISTANCE_3_POINT_3_WEIGHTED_POINT_3_H #define CGAL_DISTANCE_3_POINT_3_WEIGHTED_POINT_3_H -#include +#include #include #include diff --git a/Distance_3/include/CGAL/squared_distance_Ray_3_Line_3.h b/Distance_3/include/CGAL/Distance_3/Ray_3_Line_3.h similarity index 97% rename from Distance_3/include/CGAL/squared_distance_Ray_3_Line_3.h rename to Distance_3/include/CGAL/Distance_3/Ray_3_Line_3.h index 1c5dec16d06..63b98004ac0 100644 --- a/Distance_3/include/CGAL/squared_distance_Ray_3_Line_3.h +++ b/Distance_3/include/CGAL/Distance_3/Ray_3_Line_3.h @@ -17,7 +17,7 @@ #ifndef CGAL_DISTANCE_3_RAY_3_LINE_3_H #define CGAL_DISTANCE_3_RAY_3_LINE_3_H -#include +#include #include #include diff --git a/Distance_3/include/CGAL/squared_distance_Ray_3_Plane_3.h b/Distance_3/include/CGAL/Distance_3/Ray_3_Plane_3.h similarity index 97% rename from Distance_3/include/CGAL/squared_distance_Ray_3_Plane_3.h rename to Distance_3/include/CGAL/Distance_3/Ray_3_Plane_3.h index 43cdcd22c75..c72ee2975ee 100644 --- a/Distance_3/include/CGAL/squared_distance_Ray_3_Plane_3.h +++ b/Distance_3/include/CGAL/Distance_3/Ray_3_Plane_3.h @@ -17,7 +17,7 @@ #ifndef CGAL_DISTANCE_3_RAY_3_PLANE_3_H #define CGAL_DISTANCE_3_RAY_3_PLANE_3_H -#include +#include #include #include diff --git a/Distance_3/include/CGAL/squared_distance_Ray_3_Ray_3.h b/Distance_3/include/CGAL/Distance_3/Ray_3_Ray_3.h similarity index 98% rename from Distance_3/include/CGAL/squared_distance_Ray_3_Ray_3.h rename to Distance_3/include/CGAL/Distance_3/Ray_3_Ray_3.h index 1494f6e40e7..015e9a734c1 100644 --- a/Distance_3/include/CGAL/squared_distance_Ray_3_Ray_3.h +++ b/Distance_3/include/CGAL/Distance_3/Ray_3_Ray_3.h @@ -17,7 +17,7 @@ #ifndef CGAL_DISTANCE_3_RAY_3_RAY_3_H #define CGAL_DISTANCE_3_RAY_3_RAY_3_H -#include +#include #include #include diff --git a/Distance_3/include/CGAL/squared_distance_Segment_3_Line_3.h b/Distance_3/include/CGAL/Distance_3/Segment_3_Line_3.h similarity index 97% rename from Distance_3/include/CGAL/squared_distance_Segment_3_Line_3.h rename to Distance_3/include/CGAL/Distance_3/Segment_3_Line_3.h index 28a530ccce1..a6717e4e853 100644 --- a/Distance_3/include/CGAL/squared_distance_Segment_3_Line_3.h +++ b/Distance_3/include/CGAL/Distance_3/Segment_3_Line_3.h @@ -17,7 +17,7 @@ #ifndef CGAL_DISTANCE_3_SEGMENT_3_LINE_3_H #define CGAL_DISTANCE_3_SEGMENT_3_LINE_3_H -#include +#include #include #include diff --git a/Distance_3/include/CGAL/squared_distance_Segment_3_Plane_3.h b/Distance_3/include/CGAL/Distance_3/Segment_3_Plane_3.h similarity index 97% rename from Distance_3/include/CGAL/squared_distance_Segment_3_Plane_3.h rename to Distance_3/include/CGAL/Distance_3/Segment_3_Plane_3.h index dad2579ac76..d67c6c3e543 100644 --- a/Distance_3/include/CGAL/squared_distance_Segment_3_Plane_3.h +++ b/Distance_3/include/CGAL/Distance_3/Segment_3_Plane_3.h @@ -17,7 +17,7 @@ #ifndef CGAL_DISTANCE_3_SEGMENT_3_PLANE_3_H #define CGAL_DISTANCE_3_SEGMENT_3_PLANE_3_H -#include +#include #include #include diff --git a/Distance_3/include/CGAL/squared_distance_Segment_3_Ray_3.h b/Distance_3/include/CGAL/Distance_3/Segment_3_Ray_3.h similarity index 95% rename from Distance_3/include/CGAL/squared_distance_Segment_3_Ray_3.h rename to Distance_3/include/CGAL/Distance_3/Segment_3_Ray_3.h index f6935116c8c..aa3fb6c1ee7 100644 --- a/Distance_3/include/CGAL/squared_distance_Segment_3_Ray_3.h +++ b/Distance_3/include/CGAL/Distance_3/Segment_3_Ray_3.h @@ -17,11 +17,11 @@ #ifndef CGAL_DISTANCE_3_SEGMENT_3_RAY_3_H #define CGAL_DISTANCE_3_SEGMENT_3_RAY_3_H -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include diff --git a/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h b/Distance_3/include/CGAL/Distance_3/Segment_3_Segment_3.h similarity index 98% rename from Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h rename to Distance_3/include/CGAL/Distance_3/Segment_3_Segment_3.h index cc19b069204..8232a7647b7 100644 --- a/Distance_3/include/CGAL/squared_distance_Segment_3_Segment_3.h +++ b/Distance_3/include/CGAL/Distance_3/Segment_3_Segment_3.h @@ -17,8 +17,8 @@ #ifndef CGAL_DISTANCE_3_SEGMENT_3_SEGMENT_3_H #define CGAL_DISTANCE_3_SEGMENT_3_SEGMENT_3_H -#include -#include +#include +#include #include diff --git a/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h b/Distance_3/include/CGAL/Distance_3/Triangle_3_Triangle_3.h similarity index 98% rename from Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h rename to Distance_3/include/CGAL/Distance_3/Triangle_3_Triangle_3.h index ac1dbcbb24c..5454d73d67f 100644 --- a/Distance_3/include/CGAL/squared_distance_Triangle_3_Triangle_3.h +++ b/Distance_3/include/CGAL/Distance_3/Triangle_3_Triangle_3.h @@ -17,8 +17,8 @@ #ifndef CGAL_DISTANCE_3_TRIANGLE_3_TRIANGLE_3_H #define CGAL_DISTANCE_3_TRIANGLE_3_TRIANGLE_3_H -#include -#include +#include +#include #include diff --git a/Distance_3/include/CGAL/squared_distance_Weighted_point_3_Weighted_point_3.h b/Distance_3/include/CGAL/Distance_3/Weighted_point_3_Weighted_point_3.h similarity index 94% rename from Distance_3/include/CGAL/squared_distance_Weighted_point_3_Weighted_point_3.h rename to Distance_3/include/CGAL/Distance_3/Weighted_point_3_Weighted_point_3.h index 6aa9d79a94e..bd880062faf 100644 --- a/Distance_3/include/CGAL/squared_distance_Weighted_point_3_Weighted_point_3.h +++ b/Distance_3/include/CGAL/Distance_3/Weighted_point_3_Weighted_point_3.h @@ -17,7 +17,7 @@ #ifndef CGAL_DISTANCE_3_WEIGHTED_POINT_3_WEIGHTED_POINT_3_H #define CGAL_DISTANCE_3_WEIGHTED_POINT_3_WEIGHTED_POINT_3_H -#include +#include #include diff --git a/Distance_3/include/CGAL/internal/squared_distance_utils_3.h b/Distance_3/include/CGAL/Distance_3/internal/squared_distance_utils_3.h similarity index 100% rename from Distance_3/include/CGAL/internal/squared_distance_utils_3.h rename to Distance_3/include/CGAL/Distance_3/internal/squared_distance_utils_3.h diff --git a/Distance_3/include/CGAL/squared_distance_3.h b/Distance_3/include/CGAL/squared_distance_3.h index ffe555175b4..69436bbe6dc 100644 --- a/Distance_3/include/CGAL/squared_distance_3.h +++ b/Distance_3/include/CGAL/squared_distance_3.h @@ -18,31 +18,31 @@ #ifndef CGAL_DISTANCE_3_H #define CGAL_DISTANCE_3_H -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include -#include +#include -#include -#include -#include -#include +#include +#include +#include +#include -#include -#include -#include +#include +#include +#include -#include -#include +#include +#include -#include +#include -#include +#include #endif // CGAL_DISTANCE_3_H diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Sphere_3_do_intersect.h b/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Sphere_3_do_intersect.h index ce578a114cf..31c9dbf6489 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Sphere_3_do_intersect.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Sphere_3_do_intersect.h @@ -13,9 +13,9 @@ #ifndef CGAL_TRIANGLE_3_SPHERE_3_DO_INTERSECT_H #define CGAL_TRIANGLE_3_SPHERE_3_DO_INTERSECT_H -#include -#include -#include +#include +#include +#include #include namespace CGAL { diff --git a/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h index 873ae27786a..d06c2be35e6 100644 --- a/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include diff --git a/Mesh_3/include/CGAL/Mesh_3/squared_distance_Point_3_Triangle_3.h b/Mesh_3/include/CGAL/Mesh_3/squared_distance_Point_3_Triangle_3.h index e3fb8c3b259..7af0376d312 100644 --- a/Mesh_3/include/CGAL/Mesh_3/squared_distance_Point_3_Triangle_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/squared_distance_Point_3_Triangle_3.h @@ -16,6 +16,6 @@ #include -#include +#include #endif // CGAL_SQUARED_DISTANCE_POINT_3_TRIANGLE_3_H diff --git a/Polyhedron/demo/Polyhedron/include/CGAL/statistics_helpers.h b/Polyhedron/demo/Polyhedron/include/CGAL/statistics_helpers.h index d7a9c3b9010..82a081b8083 100644 --- a/Polyhedron/demo/Polyhedron/include/CGAL/statistics_helpers.h +++ b/Polyhedron/demo/Polyhedron/include/CGAL/statistics_helpers.h @@ -1,8 +1,8 @@ #ifndef POLYHEDRON_DEMO_STATISTICS_HELPERS_H #define POLYHEDRON_DEMO_STATISTICS_HELPERS_H -#include -#include +#include +#include #include #include From 7e62c0217693bb8f3570c2d2171a49754f89ee92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 12 Apr 2021 14:02:37 +0200 Subject: [PATCH 18/23] Re-organize into Distance_2/X_Y.h to align with Distance_3 --- .../include/CGAL/Distance_2/Line_2_Line_2.h | 56 ++ .../CGAL/Distance_2/Line_2_Triangle_2.h | 88 ++ .../include/CGAL/Distance_2/Point_2_Line_2.h | 108 +++ .../include/CGAL/Distance_2/Point_2_Point_2.h | 49 + .../include/CGAL/Distance_2/Point_2_Ray_2.h | 108 +++ .../CGAL/Distance_2/Point_2_Segment_2.h | 122 +++ .../CGAL/Distance_2/Point_2_Triangle_2.h | 264 ++++++ .../include/CGAL/Distance_2/Ray_2_Line_2.h | 88 ++ .../include/CGAL/Distance_2/Ray_2_Ray_2.h | 114 +++ .../CGAL/Distance_2/Ray_2_Triangle_2.h | 121 +++ .../CGAL/Distance_2/Segment_2_Line_2.h | 129 +++ .../include/CGAL/Distance_2/Segment_2_Ray_2.h | 197 ++++ .../CGAL/Distance_2/Segment_2_Segment_2.h | 341 +++++++ .../CGAL/Distance_2/Segment_2_Triangle_2.h | 135 +++ .../CGAL/Distance_2/Triangle_2_Triangle_2.h | 123 +++ .../internal/squared_distance_utils_2.h} | 1 - Distance_2/include/CGAL/squared_distance_2.h | 22 +- .../include/CGAL/squared_distance_2_1.h | 857 ------------------ .../include/CGAL/squared_distance_2_2.h | 566 ------------ .../test/Distance_2/test_distance_2.cpp | 32 +- .../CGAL/Intersections_2/Circle_2_Circle_2.h | 6 +- .../CGAL/Intersections_2/Circle_2_Line_2.h | 5 +- .../CGAL/Intersections_2/Circle_2_Ray_2.h | 5 +- .../CGAL/Intersections_2/Circle_2_Segment_2.h | 5 +- .../Intersections_2/Circle_2_Triangle_2.h | 6 +- .../Intersections_2/internal/Straight_2.h | 2 +- .../Triangle_2_Triangle_2_intersection_impl.h | 1 + Nef_2/include/CGAL/Extended_homogeneous.h | 2 +- Point_set_2/include/CGAL/Point_set_2.h | 1 - .../CGAL/nearest_neighbor_delaunay_2.h | 1 - .../boost/graph/properties_Polyhedron_3.h | 2 +- 31 files changed, 2100 insertions(+), 1457 deletions(-) create mode 100644 Distance_2/include/CGAL/Distance_2/Line_2_Line_2.h create mode 100644 Distance_2/include/CGAL/Distance_2/Line_2_Triangle_2.h create mode 100644 Distance_2/include/CGAL/Distance_2/Point_2_Line_2.h create mode 100644 Distance_2/include/CGAL/Distance_2/Point_2_Point_2.h create mode 100644 Distance_2/include/CGAL/Distance_2/Point_2_Ray_2.h create mode 100644 Distance_2/include/CGAL/Distance_2/Point_2_Segment_2.h create mode 100644 Distance_2/include/CGAL/Distance_2/Point_2_Triangle_2.h create mode 100644 Distance_2/include/CGAL/Distance_2/Ray_2_Line_2.h create mode 100644 Distance_2/include/CGAL/Distance_2/Ray_2_Ray_2.h create mode 100644 Distance_2/include/CGAL/Distance_2/Ray_2_Triangle_2.h create mode 100644 Distance_2/include/CGAL/Distance_2/Segment_2_Line_2.h create mode 100644 Distance_2/include/CGAL/Distance_2/Segment_2_Ray_2.h create mode 100644 Distance_2/include/CGAL/Distance_2/Segment_2_Segment_2.h create mode 100644 Distance_2/include/CGAL/Distance_2/Segment_2_Triangle_2.h create mode 100644 Distance_2/include/CGAL/Distance_2/Triangle_2_Triangle_2.h rename Distance_2/include/CGAL/{squared_distance_utils.h => Distance_2/internal/squared_distance_utils_2.h} (99%) delete mode 100644 Distance_2/include/CGAL/squared_distance_2_1.h delete mode 100644 Distance_2/include/CGAL/squared_distance_2_2.h diff --git a/Distance_2/include/CGAL/Distance_2/Line_2_Line_2.h b/Distance_2/include/CGAL/Distance_2/Line_2_Line_2.h new file mode 100644 index 00000000000..b87124a8ee9 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Line_2_Line_2.h @@ -0,0 +1,56 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_LINE_2_LINE_2_H +#define CGAL_DISTANCE_2_LINE_2_LINE_2_H + +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +inline typename K::FT +squared_distance(const typename K::Line_2& line1, + const typename K::Line_2& line2, + const K& k) +{ + typedef typename K::FT FT; + if(internal::parallel(line1, line2, k)) + return internal::squared_distance(line1.point(), line2, k); + else + return FT(0); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Line_2& line1, + const Line_2& line2) +{ + return internal::squared_distance(line1, line2, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_LINE_2_LINE_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Line_2_Triangle_2.h b/Distance_2/include/CGAL/Distance_2/Line_2_Triangle_2.h new file mode 100644 index 00000000000..6ba20ce2eef --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Line_2_Triangle_2.h @@ -0,0 +1,88 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_LINE_2_TRIANGLE_2_H +#define CGAL_DISTANCE_2_LINE_2_TRIANGLE_2_H + +#include +#include + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Line_2& line, + const typename K::Triangle_2& triangle, + const K& k) +{ + typedef typename K::FT FT; + + Oriented_side side0 = line.oriented_side(triangle.vertex(0)); + if(line.oriented_side(triangle.vertex(1)) != side0) + return FT(0); + + if(line.oriented_side(triangle.vertex(2)) != side0) + return FT(0); + + FT mindist = internal::squared_distance(triangle.vertex(0), line, k); + for(int i=1; i<3; ++i) + { + FT dist = internal::squared_distance(triangle.vertex(i), line, k); + if(dist < mindist) + mindist = dist; + } + + return mindist; +} + +template +inline typename K::FT +squared_distance(const typename K::Triangle_2& triangle, + const typename K::Line_2& line, + const K& k) +{ + return internal::squared_distance(line, triangle, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Line_2& line, + const Triangle_2& triangle) +{ + return internal::squared_distance(line, triangle, K()); +} + +template +inline typename K::FT +squared_distance(const Triangle_2& triangle, + const Line_2& line) +{ + return internal::squared_distance(line, triangle, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_LINE_2_TRIANGLE_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Point_2_Line_2.h b/Distance_2/include/CGAL/Distance_2/Point_2_Line_2.h new file mode 100644 index 00000000000..43f1ff622ff --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Point_2_Line_2.h @@ -0,0 +1,108 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_POINT_2_LINE_2_H +#define CGAL_DISTANCE_2_POINT_2_LINE_2_H + +#include +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Point_2& pt, + const typename K::Line_2& line, + const K&, + const Homogeneous_tag&) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + + const RT& a = line.a(); + const RT& b = line.b(); + const RT& w = pt.hw(); + RT n = a*pt.hx() + b*pt.hy() + w*line.c(); + RT d = (CGAL_NTS square(a) + CGAL_NTS square(b)) * CGAL_NTS square(w); + + return Rational_traits().make_rational(CGAL_NTS square(n), d); +} + +template +typename K::FT +squared_distance(const typename K::Point_2& pt, + const typename K::Line_2& line, + const K&, + const Cartesian_tag&) +{ + typedef typename K::FT FT; + + const FT& a = line.a(); + const FT& b = line.b(); + FT n = a*pt.x() + b*pt.y() + line.c(); + FT d = CGAL_NTS square(a) + CGAL_NTS square(b); + + return CGAL_NTS square(n)/d; +} + +template +typename K::FT +squared_distance(const typename K::Point_2& pt, + const typename K::Line_2& line, + const K& k) +{ + typedef typename K::Kernel_tag Tag; + Tag tag; + return squared_distance(pt, line, k, tag); +} + +template +inline typename K::FT +squared_distance(const typename K::Line_2& line, + const typename K::Point_2& pt, + const K& k) +{ + return internal::squared_distance(pt, line, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Point_2& pt, + const Line_2& line) +{ + return internal::squared_distance(pt, line, K()); +} + +template +inline typename K::FT +squared_distance(const Line_2& line, + const Point_2& pt) +{ + return internal::squared_distance(pt, line, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_POINT_2_LINE_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Point_2_Point_2.h b/Distance_2/include/CGAL/Distance_2/Point_2_Point_2.h new file mode 100644 index 00000000000..d8ae488e0a7 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Point_2_Point_2.h @@ -0,0 +1,49 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_POINT_2_POINT_2_H +#define CGAL_DISTANCE_2_POINT_2_POINT_2_H + +#include + +namespace CGAL { +namespace internal { + +template +inline typename K::FT +squared_distance(const typename K::Point_2& pt1, + const typename K::Point_2& pt2, + const K& k) +{ + typename K::Vector_2 vec = k.construct_vector_2_object()(pt2, pt1); + return k.compute_squared_length_2_object()(vec); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Point_2& pt1, + const Point_2& pt2) +{ + return internal::squared_distance(pt1, pt2, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_POINT_2_POINT_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Point_2_Ray_2.h b/Distance_2/include/CGAL/Distance_2/Point_2_Ray_2.h new file mode 100644 index 00000000000..c1f4543474e --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Point_2_Ray_2.h @@ -0,0 +1,108 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_POINT_2_RAY_2_H +#define CGAL_DISTANCE_2_POINT_2_RAY_2_H + +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +void +distance_index(int &ind, + const typename K::Point_2 &pt, + const typename K::Ray_2 &ray, + const K& k) +{ + typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object(); + if(!is_acute_angle(ray.direction().vector(), construct_vector(ray.source(), pt), k)) + { + ind = 0; + return; + } + + ind = -1; +} + +template +inline typename K::FT +squared_distance_indexed(const typename K::Point_2 &pt, + const typename K::Ray_2 &ray, + int ind, + const K& k) +{ + if(ind == 0) + return internal::squared_distance(pt, ray.source(), k); + + return internal::squared_distance(pt, ray.supporting_line(), k); +} + +template +typename K::FT +squared_distance(const typename K::Point_2& pt, + const typename K::Ray_2& ray, + const K& k) +{ + typedef typename K::Vector_2 Vector_2; + + typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object(); + + Vector_2 diff = construct_vector(ray.source(), pt); + const Vector_2& dir = ray.direction().vector(); + if (!is_acute_angle(dir, diff, k)) + return k.compute_squared_length_2_object()(diff); + + return internal::squared_distance(pt, ray.supporting_line(), k); +} + +template +inline typename K::FT +squared_distance(const typename K::Ray_2& ray, + const typename K::Point_2& pt, + const K& k) +{ + return internal::squared_distance(pt, ray, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Point_2& pt, + const Ray_2& ray) +{ + return internal::squared_distance(pt, ray, K()); +} + +template +inline typename K::FT +squared_distance(const Ray_2& ray, + const Point_2& pt) +{ + return internal::squared_distance(pt, ray, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_POINT_2_RAY_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Point_2_Segment_2.h b/Distance_2/include/CGAL/Distance_2/Point_2_Segment_2.h new file mode 100644 index 00000000000..c8dd3486141 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Point_2_Segment_2.h @@ -0,0 +1,122 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_POINT_2_SEGMENT_2_H +#define CGAL_DISTANCE_2_POINT_2_SEGMENT_2_H + +#include +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +void +distance_index(int &ind, + const typename K::Point_2 &pt, + const typename K::Segment_2 &seg, + const K& k) +{ + if(!is_acute_angle(seg.target(),seg.source(),pt, k)) + { + ind = 0; + return; + } + + if(!is_acute_angle(seg.source(),seg.target(),pt, k)) + { + ind = 1; + return; + } + ind = -1; +} + +template +inline typename K::FT +squared_distance_indexed(const typename K::Point_2 &pt, + const typename K::Segment_2 &seg, + int ind, + const K& k) +{ + if(ind == 0) + return internal::squared_distance(pt, seg.source(), k); + if(ind == 1) + return internal::squared_distance(pt, seg.target(), k); + return internal::squared_distance(pt, seg.supporting_line(), k); +} + +template +typename K::FT +squared_distance(const typename K::Point_2& pt, + const typename K::Segment_2& seg, + const K& k) +{ + typedef typename K::Vector_2 Vector_2; + typedef typename K::RT RT; + + typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object(); + + // assert that the segment is valid (non zero length). + Vector_2 diff = construct_vector(seg.source(), pt); + Vector_2 segvec = construct_vector(seg.source(), seg.target()); + + RT d = wdot(diff, segvec, k); + if(d <= RT(0)) + return k.compute_squared_length_2_object()(diff); + + RT e = wdot(segvec,segvec, k); + if(wmult((K*)0 ,d, segvec.hw()) > wmult((K*)0, e, diff.hw())) + return internal::squared_distance(pt, seg.target(), k); + + return internal::squared_distance(pt, seg.supporting_line(), k); +} + +template +inline typename K::FT +squared_distance(const typename K::Segment_2& seg, + const typename K::Point_2& pt, + const K& k) +{ + return internal::squared_distance(pt, seg, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Point_2& pt, + const Segment_2& seg) +{ + return internal::squared_distance(pt, seg, K()); +} + +template +inline typename K::FT +squared_distance(const Segment_2& seg, + const Point_2& pt) +{ + return internal::squared_distance(pt, seg, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_POINT_2_SEGMENT_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Point_2_Triangle_2.h b/Distance_2/include/CGAL/Distance_2/Point_2_Triangle_2.h new file mode 100644 index 00000000000..9cd6c83fe14 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Point_2_Triangle_2.h @@ -0,0 +1,264 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_POINT_2_TRIANGLE_2_H +#define CGAL_DISTANCE_2_POINT_2_TRIANGLE_2_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +void +distance_index(int &ind1, + int &ind2, + const typename K::Point_2 &pt, + const typename K::Triangle_2 &triangle, + const K& k) +{ + typedef typename K::Point_2 Point_2; + + typename K::Left_turn_2 leftturn = k.left_turn_2_object(); + + const Point_2& vt0 = triangle.vertex(0); + const Point_2& vt1 = triangle.vertex(1); + const Point_2& vt2 = triangle.vertex(2); + + if(leftturn(vt0, vt1, vt2)) { + if(leftturn(pt, vt1, vt0)) { + if(!is_acute_angle(vt0, vt1, pt, k)) { + if(leftturn(pt, vt2, vt1)) { + if(!is_acute_angle(vt1, vt2, pt, k)) { + ind1 = 2; ind2 = -1; + return; + } + if(!is_acute_angle(vt2, vt1, pt, k)) { + ind1 = 1; ind2 = -1; + return; + } + ind1 = 1; ind2 = 2; + return; + } + ind1 = 1; ind2 = -1; + return; + } + if(!is_acute_angle(vt1, vt0, pt, k)) { + if(leftturn(pt, vt0, vt2)) { + if(!is_acute_angle(vt0, vt2, pt, k)) { + ind1 = 2; ind2 = -1; + return; + } + if(!is_acute_angle(vt2, vt0, pt, k)) { + ind1 = 0; ind2 = -1; + return; + } + ind1 = 2; ind2 = 0; + return; + } + ind1 = 0; ind2 = -1; + return; + } + ind1 = 0; ind2 = 1; + return; + } else { + if(leftturn(pt, vt2, vt1)) { + if(!is_acute_angle(vt1, vt2, pt, k)) { + if(leftturn(pt, vt0, vt2)) { + if(!is_acute_angle(vt0, vt2, pt, k)) { + ind1 = 2; ind2 = -1; + return; + } + if(!is_acute_angle(vt2, vt0, pt, k)) { + ind1 = 0; ind2 = -1; + return; + } + ind1 = 2; ind2 = 0; + return; + } + ind1 = 0; ind2 = -1; + return; + } + if(!is_acute_angle(vt2, vt1, pt, k)) { + ind1 = 1; ind2 = -1; + return; + } + ind1 = 1; ind2 = 2; + return; + } else { + if(leftturn(pt, vt0, vt2)) { + if(!is_acute_angle(vt2, vt0, pt, k)) { + ind1 = 0; ind2 = -1; + return; + } + if(!is_acute_angle(vt0, vt2, pt, k)) { + ind1 = 2; ind2 = -1; + return; + } + ind1 = 2; ind2 = 0; + return; + } else { + ind1 = -1; ind2 = -1; // point inside or on boundary. + return; + } + } + } + } else { + if(leftturn(pt, vt2, vt0)) { + if(!is_acute_angle(vt0, vt2, pt, k)) { + if(leftturn(pt, vt1, vt2)) { + if(!is_acute_angle(vt2, vt1, pt, k)) { + ind1 = 1; ind2 = -1; + return; + } + if(!is_acute_angle(vt1, vt2, pt, k)) { + ind1 = 2; ind2 = -1; + return; + } + ind1 = 2; ind2 = 1; + return; + } + ind1 = 2; ind2 = -1; + return; + } + if(!is_acute_angle(vt2, vt0, pt, k)) { + if(leftturn(pt, vt0, vt1)) { + if(!is_acute_angle(vt0, vt1, pt, k)) { + ind1 = 1; ind2 = -1; + return; + } + if(!is_acute_angle(vt1, vt0, pt, k)) { + ind1 = 0; ind2 = -1; + return; + } + ind1 = 1; ind2 = 0; + return; + } + ind1 = 0; ind2 = -1; + return; + } + ind1 = 0; ind2 = 2; + return; + } else { + if(leftturn(pt, vt1, vt2)) { + if(!is_acute_angle(vt2, vt1, pt, k)) { + if(leftturn(pt, vt0, vt1)) { + if(!is_acute_angle(vt0, vt1, pt, k)) { + ind1 = 1; ind2 = -1; + return; + } + if(!is_acute_angle(vt1, vt0, pt, k)) { + ind1 = 0; ind2 = -1; + return; + } + ind1 = 1; ind2 = 0; + return; + } + ind1 = 0; ind2 = -1; + return; + } + if(!is_acute_angle(vt1, vt2, pt, k)) { + ind1 = 2; ind2 = -1; + return; + } + ind1 = 2; ind2 = 1; + return; + } else { + if(leftturn(pt, vt0, vt1)) { + if(!is_acute_angle(vt1, vt0, pt, k)) { + ind1 = 0; ind2 = -1; + return; + } + if(!is_acute_angle(vt0, vt1, pt, k)) { + ind1 = 1; ind2 = -1; + return; + } + ind1 = 1; ind2 = 0; + return; + } else { + ind1 = -1; ind2 = -1; // point inside or on boundary. + return; + } + } + } + } +} + +template +typename K::FT +squared_distance_indexed(const typename K::Point_2& pt, + const typename K::Triangle_2& triangle, + int ind1, int ind2, + const K& k) +{ + typedef typename K::FT FT; + typedef typename K::Line_2 Line_2; + + if(ind1 == -1) + return FT(0); + + if(ind2 == -1) + return internal::squared_distance(pt, triangle.vertex(ind1), k); + + return internal::squared_distance(pt, Line_2(triangle.vertex(ind1), triangle.vertex(ind2)), k); +} + +template +typename K::FT +squared_distance(const typename K::Point_2& pt, + const typename K::Triangle_2& triangle, + const K& k) +{ + int ind1, ind2; + distance_index(ind1, ind2, pt, triangle, k); + return squared_distance_indexed(pt, triangle, ind1, ind2, k); +} + +template +inline typename K::FT +squared_distance(const typename K::Triangle_2& triangle, + const typename K::Point_2& pt, + const K& k) +{ + return internal::squared_distance(pt, triangle, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Point_2& pt, + const Triangle_2& triangle) +{ + return internal::squared_distance(pt, triangle, K()); +} + +template +inline typename K::FT +squared_distance(const Triangle_2& triangle, + const Point_2& pt) +{ + return internal::squared_distance(pt, triangle, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_POINT_2_TRIANGLE_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Ray_2_Line_2.h b/Distance_2/include/CGAL/Distance_2/Ray_2_Line_2.h new file mode 100644 index 00000000000..bef607cf383 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Ray_2_Line_2.h @@ -0,0 +1,88 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_RAY_2_LINE_2_H +#define CGAL_DISTANCE_2_RAY_2_LINE_2_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Line_2& line, + const typename K::Ray_2& ray, + const K& k) +{ + typedef typename K::FT FT; + typedef typename K::Vector_2 Vector_2; + + typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object(); + + Vector_2 normalvec(line.a(), line.b()); + Vector_2 diff = construct_vector(line.point(), ray.source()); + + FT sign_dist = k.compute_scalar_product_2_object()(diff, normalvec); + if(sign_dist < FT(0)) + { + if(is_acute_angle(normalvec, ray.direction().vector(), k)) + return FT(0); + } + else + { + if(is_obtuse_angle(normalvec, ray.direction().vector(), k)) + return FT(0); + } + + return (square(sign_dist) / k.compute_squared_length_2_object()(normalvec)); +} + +template +inline typename K::FT +squared_distance(const typename K::Ray_2& ray, + const typename K::Line_2& line, + const K& k) +{ + return internal::squared_distance(line, ray, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Line_2& line, + const Ray_2& ray) +{ + return internal::squared_distance(line, ray, K()); +} + +template +inline typename K::FT +squared_distance(const Ray_2& ray, + const Line_2& line) +{ + return internal::squared_distance(line, ray, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_RAY_2_LINE_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Ray_2_Ray_2.h b/Distance_2/include/CGAL/Distance_2/Ray_2_Ray_2.h new file mode 100644 index 00000000000..87fdf1903f6 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Ray_2_Ray_2.h @@ -0,0 +1,114 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_RAY_2_RAY_2_H +#define CGAL_DISTANCE_2_RAY_2_RAY_2_H + +#include +#include + +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +ray_ray_squared_distance_parallel(const typename K::Vector_2& ray1dir, + const typename K::Vector_2& ray2dir, + const typename K::Vector_2& from1to2, + const K& k) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + + if(!is_acute_angle(ray1dir, from1to2, k)) + { + if(!same_direction(ray1dir, ray2dir, k)) + return k.compute_squared_length_2_object()(from1to2); + } + + RT wcr = wcross(ray1dir, from1to2, k); + RT w = from1to2.hw(); + + return (square(wcr) / FT(wmult((K*)0, RT(wdot(ray1dir, ray1dir, k)), w, w))); +} + +template +typename K::FT +squared_distance(const typename K::Ray_2& ray1, + const typename K::Ray_2& ray2, + const K& k) +{ + typedef typename K::Vector_2 Vector_2; + typedef typename K::FT FT; + + typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object(); + + const Vector_2& ray1dir = ray1.direction().vector(); + const Vector_2& ray2dir = ray2.direction().vector(); + Vector_2 diffvec(construct_vector(ray1.source(),ray2.source())); + + bool crossing1, crossing2; + switch(orientation(ray1dir, ray2dir, k)) + { + case COUNTERCLOCKWISE: + crossing1 = !clockwise(diffvec, ray2dir, k); + crossing2 = !counterclockwise(ray1dir, diffvec, k); + break; + case CLOCKWISE: + crossing1 = !counterclockwise(diffvec, ray2dir, k); + crossing2 = !clockwise(ray1dir, diffvec, k); + break; + default: + return ray_ray_squared_distance_parallel(ray1dir, ray2dir, diffvec,k); + } + + if(crossing1) + { + if(crossing2) + return FT(0); + return internal::squared_distance(ray2.source(), ray1, k); + } + else + { + if(crossing2) + { + return internal::squared_distance(ray1.source(), ray2, k); + } + else + { + FT min1 = internal::squared_distance(ray1.source(), ray2, k); + FT min2 = internal::squared_distance(ray2.source(), ray1, k); + return (min1 < min2) ? min1 : min2; + } + } +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Ray_2 &ray1, const Ray_2 &ray2) +{ + return internal::squared_distance(ray1, ray2, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_RAY_2_RAY_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Ray_2_Triangle_2.h b/Distance_2/include/CGAL/Distance_2/Ray_2_Triangle_2.h new file mode 100644 index 00000000000..f549ce3d880 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Ray_2_Triangle_2.h @@ -0,0 +1,121 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_RAY_2_TRIANGLE_2_H +#define CGAL_DISTANCE_2_RAY_2_TRIANGLE_2_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Ray_2& ray, + const typename K::Triangle_2& triangle, + const K& k) +{ + typedef typename K::FT FT; + typedef typename K::Point_2 Point_2; + typedef typename K::Line_2 Line_2; + + int ind_tr1, ind_tr2, ind_ray = 0, ind1; + + distance_index(ind_tr1, ind_tr2, ray.source(), triangle, k); + FT mindist = squared_distance_indexed(ray.source(), triangle, ind_tr1, ind_tr2, k); + + for(int i=0; i<3; ++i) + { + const Point_2& pt = triangle.vertex(i); + distance_index(ind1, pt, ray, k); + FT dist = squared_distance_indexed(pt, ray, ind1, k); + if(dist < mindist) + { + ind_ray = ind1; + ind_tr1 = i; ind_tr2 = -1; + mindist = dist; + } + } + + // now check if all vertices are on the right side of the separating line. + // In case of vertex-vertex smallest distance this is the case. + if(ind_tr2 == -1 && ind_ray != -1) + return mindist; + + if(ind_tr2 != -1) + { + // Check if all the segment vertices lie at the same side of + // the triangle segment. + const Point_2 &vt1 = triangle.vertex(ind_tr1); + const Point_2 &vt2 = triangle.vertex(ind_tr2); + if(clockwise(ray.direction().vector(), vt2-vt1, k)) + mindist = FT(0); + + } + else + { + // Check if all the triangle vertices lie + // at the same side of the segment. + const Line_2& sl = ray.supporting_line(); + Oriented_side or_s = sl.oriented_side(triangle.vertex(0)); + for(int i=1; i<3; ++i) + { + if(sl.oriented_side(triangle.vertex(i)) != or_s) + { + mindist = FT(0); + break; + } + } + } + + return mindist; +} + +template +inline typename K::FT +squared_distance(const typename K::Triangle_2& triangle, + const typename K::Ray_2& ray, + const K& k) +{ + return internal::squared_distance(ray, triangle, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Ray_2& ray, + const Triangle_2& triangle) +{ + return internal::squared_distance(ray, triangle, K()); +} + +template +inline typename K::FT +squared_distance(const Triangle_2& triangle, + const Ray_2& ray) +{ + return internal::squared_distance(ray, triangle, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_RAY_2_TRIANGLE_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Segment_2_Line_2.h b/Distance_2/include/CGAL/Distance_2/Segment_2_Line_2.h new file mode 100644 index 00000000000..b5ba324207f --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Segment_2_Line_2.h @@ -0,0 +1,129 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_SEGMENT_2_LINE_2_H +#define CGAL_DISTANCE_2_SEGMENT_2_LINE_2_H + +#include +#include + +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +_sqd_to_line(const typename K::Vector_2& diff, + const typename K::RT& wcross, + const typename K::Vector_2& dir) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + + RT numerator = CGAL_NTS square(wcross); + RT denominator = wmult((K*)0, RT(wdot(dir,dir, K())), diff.hw(), diff.hw()); + return Rational_traits().make_rational(numerator, denominator); +} + +template +typename K::FT +squared_distance(const typename K::Segment_2& seg, + const typename K::Line_2& line, + const K& k) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + typedef typename K::Vector_2 Vector_2; + typedef typename K::Point_2 Point_2; + + typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object(); + + const Vector_2 &linedir = line.direction().vector(); + const Point_2 &linepoint = line.point(); + Vector_2 startvec(construct_vector(linepoint, seg.source())); + Vector_2 endvec(construct_vector(linepoint, seg.target())); + + bool crossing1; + RT c1s, c1e; + if(seg.source() == seg.target()) + return internal::squared_distance(seg.source(), line, k); + + c1s = wcross(linedir, startvec, k); + c1e = wcross(linedir, endvec, k); + if(c1s < RT(0)) + { + crossing1 = (c1e >= RT(0)); + } + else + { + if(c1e <= RT(0)) + crossing1 = true; + else + crossing1 = (c1s == RT(0)); + } + + if(crossing1) + { + return FT(0); + } + else + { + RT dm; + dm = _distance_measure_sub(c1s, c1e, startvec, endvec); + if(dm <= RT(0)) + return _sqd_to_line(startvec, c1s, linedir); + else + return _sqd_to_line(endvec, c1e, linedir); + } +} + +template +inline typename K::FT +squared_distance(const typename K::Line_2& line, + const typename K::Segment_2& seg, + const K& k) +{ + return internal::squared_distance(seg, line, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Segment_2& seg, + const Line_2& line) +{ + return internal::squared_distance(seg, line, K()); +} + +template +inline typename K::FT +squared_distance(const Line_2& line, + const Segment_2& seg) +{ + return internal::squared_distance(seg, line, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_SEGMENT_2_LINE_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Segment_2_Ray_2.h b/Distance_2/include/CGAL/Distance_2/Segment_2_Ray_2.h new file mode 100644 index 00000000000..1c5c300648d --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Segment_2_Ray_2.h @@ -0,0 +1,197 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_SEGMENT_2_RAY_2_H +#define CGAL_DISTANCE_2_SEGMENT_2_RAY_2_H + +#include + +#include +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +inline typename K::RT +_distance_measure_sub(const typename K::RT& startwcross, + const typename K::RT& endwcross, + const typename K::Vector_2& start, + const typename K::Vector_2& end) +{ + return CGAL_NTS abs(wmult((K*)0, startwcross, end.hw())) - + CGAL_NTS abs(wmult((K*)0, endwcross, start.hw())); +} + +template +typename K::FT +squared_distance_parallel(const typename K::Segment_2& seg, + const typename K::Ray_2& ray, + const K& k) +{ + typedef typename K::Vector_2 Vector_2; + + const Vector_2& dir1 = seg.direction().vector(); + const Vector_2& dir2 = ray.direction().vector(); + + if(same_direction(dir1, dir2, k)) + { + if(!is_acute_angle(seg.source(), seg.target(), ray.source(), k)) + return internal::squared_distance(seg.target(), ray.source(), k); + } + else + { + if(!is_acute_angle(seg.target(), seg.source(), ray.source(), k)) + return internal::squared_distance(seg.source(), ray.source(), k); + } + + return internal::squared_distance(ray.source(), seg.supporting_line(), k); +} + +template +typename K::FT +squared_distance(const typename K::Segment_2 &seg, + const typename K::Ray_2 &ray, + const K& k) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + typedef typename K::Vector_2 Vector_2; + + typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object(); + typename K::Orientation_2 orientation = k.orientation_2_object(); + + const Vector_2& raydir = ray.direction().vector(); + Vector_2 startvec(construct_vector(ray.source(), seg.source())); + Vector_2 endvec(construct_vector(ray.source(), seg.target())); + + bool crossing1, crossing2; + RT c1s, c1e; + + if(seg.source() == seg.target()) + return internal::squared_distance(seg.source(), ray, k); + + c1s = wcross(raydir, startvec, k); + c1e = wcross(raydir, endvec, k); + if(c1s < RT(0)) + { + crossing1 = (c1e >= RT(0)); + } + else + { + if(c1e <= RT(0)) + { + if(c1s == RT(0) && c1e == RT(0)) + return internal::squared_distance_parallel(seg, ray, k); + + crossing1 = true; + } + else + { + crossing1 = (c1s == RT(0)); + } + } + + switch (orientation(seg.source(), seg.target(), ray.source())) + { + case LEFT_TURN: + crossing2 = right_turn(construct_vector(seg.source(), seg.target()), raydir, k); + break; + case RIGHT_TURN: + crossing2 = left_turn(construct_vector(seg.source(), seg.target()), raydir, k); + break; + default: + crossing2 = true; + break; + } + + if(crossing1) + { + if(crossing2) + return FT(0); + + return internal::squared_distance(ray.source(), seg, k); + } + else + { + if(crossing2) + { + RT dm; + dm = _distance_measure_sub(c1s, c1e, startvec, endvec); + if(dm < RT(0)) + { + return internal::squared_distance(seg.source(), ray, k); + } + else + { + if(dm > RT(0)) + return internal::squared_distance(seg.target(), ray, k); + else // parallel, should not happen (no crossing) + return internal::squared_distance_parallel(seg, ray, k); + } + } + else + { + FT min1, min2; + RT dm = _distance_measure_sub(c1s, c1e, startvec, endvec); + if(dm == RT(0)) + return internal::squared_distance_parallel(seg, ray, k); + + min1 = (dm < RT(0)) ? internal::squared_distance(seg.source(), ray, k) + : internal::squared_distance(seg.target(), ray, k); + min2 = internal::squared_distance(ray.source(), seg, k); + + return (min1 < min2) ? min1 : min2; + } + } +} + +template +inline typename K::FT +squared_distance(const typename K::Ray_2& ray, + const typename K::Segment_2& seg, + const K& k) +{ + return internal::squared_distance(seg, ray, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Segment_2& seg, + const Ray_2& ray) +{ + return internal::squared_distance(seg, ray, K()); +} + +template +inline typename K::FT +squared_distance(const Ray_2& ray, + const Segment_2& seg) +{ + return internal::squared_distance(seg, ray, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_SEGMENT_2_RAY_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Segment_2_Segment_2.h b/Distance_2/include/CGAL/Distance_2/Segment_2_Segment_2.h new file mode 100644 index 00000000000..5757e39e637 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Segment_2_Segment_2.h @@ -0,0 +1,341 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_SEGMENT_2_SEGMENT_2_H +#define CGAL_DISTANCE_2_SEGMENT_2_SEGMENT_2_H + +#include +#include +#include +#include + +#include +#include + +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance_parallel(const typename K::Segment_2& seg1, + const typename K::Segment_2& seg2, + const K& k) +{ + typedef typename K::Vector_2 Vector_2; + + const Vector_2 &dir1 = seg1.direction().vector(); + const Vector_2 &dir2 = seg2.direction().vector(); + + if(same_direction(dir1, dir2, k)) + { + if(!is_acute_angle(seg1.source(), seg1.target(), seg2.source(), k)) + return internal::squared_distance(seg1.target(), seg2.source(), k); + + if(!is_acute_angle(seg1.target(), seg1.source(), seg2.target(), k)) + return internal::squared_distance(seg1.source(), seg2.target(), k); + } + else + { + if(!is_acute_angle(seg1.source(), seg1.target(), seg2.target(), k)) + return internal::squared_distance(seg1.target(), seg2.target(), k); + + if(!is_acute_angle(seg1.target(), seg1.source(), seg2.source(), k)) + return internal::squared_distance(seg1.source(), seg2.source(), k); + } + + return internal::squared_distance(seg2.source(), seg1.supporting_line(), k); +} + +template +inline typename K::RT +_distance_measure_sub(const typename K::RT& startwcross, + const typename K::RT& endwcross, + const typename K::Point_2& start, + const typename K::Point_2& end) +{ + return CGAL_NTS abs(wmult((K*)0, startwcross, end.hw())) - + CGAL_NTS abs(wmult((K*)0, endwcross, start.hw())); +} + +template +typename K::FT +squared_distance(const typename K::Segment_2& seg1, + const typename K::Segment_2& seg2, + const K& k, + const Cartesian_tag&) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + + bool crossing1, crossing2; + RT c1s, c1e, c2s, c2e; + + if(seg1.source() == seg1.target()) + return internal::squared_distance(seg1.source(), seg2, k); + + if(seg2.source() == seg2.target()) + return internal::squared_distance(seg2.source(), seg1, k); + + Orientation o1s = orientation(seg2.source(), seg2.target(), seg1.source()); + Orientation o1e = orientation(seg2.source(), seg2.target(), seg1.target()); + if(o1s == RIGHT_TURN) + { + crossing1 = (o1e != RIGHT_TURN); + } + else + { + if(o1e != LEFT_TURN) + { + if(o1s == COLLINEAR && o1e == COLLINEAR) + return internal::squared_distance_parallel(seg1, seg2, k); + + crossing1 = true; + } + else + { + crossing1 = (o1s == COLLINEAR); + } + } + + Orientation o2s = orientation(seg1.source(), seg1.target(), seg2.source()); + Orientation o2e = orientation(seg1.source(), seg1.target(), seg2.target()); + if(o2s == RIGHT_TURN) + { + crossing2 = (o2e != RIGHT_TURN); + } + else + { + if(o2e != LEFT_TURN) + { + if(o2s == COLLINEAR && o2e == COLLINEAR) + return internal::squared_distance_parallel(seg1, seg2, k); + + crossing2 = true; + } + else + { + crossing2 = (o2s == COLLINEAR); + } + } + + if(crossing1) + { + if(crossing2) + return (FT)0; + + c2s = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.source(), k)); + c2e = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.target(), k)); + Comparison_result dm = CGAL_NTS compare(c2s,c2e); + + if(dm == SMALLER) + { + return internal::squared_distance(seg2.source(), seg1, k); + } + else + { + if(dm == LARGER) + { + return internal::squared_distance(seg2.target(), seg1, k); + } + else + { + // parallel, should not happen (no crossing) + return internal::squared_distance_parallel(seg1, seg2, k); + } + } + } + else + { + c1s = CGAL_NTS abs(wcross(seg2.source(), seg2.target(), seg1.source(), k)); + c1e = CGAL_NTS abs(wcross(seg2.source(), seg2.target(), seg1.target(), k)); + Comparison_result dm = CGAL_NTS compare(c1s,c1e); + if(crossing2) + { + if(dm == SMALLER) + { + return internal::squared_distance(seg1.source(), seg2, k); + } + else + { + if(dm == LARGER) + return internal::squared_distance(seg1.target(), seg2, k); + else // parallel, should not happen (no crossing) + return internal::squared_distance_parallel(seg1, seg2, k); + } + } + else + { + FT min1, min2; + + if(dm == EQUAL) + return internal::squared_distance_parallel(seg1, seg2, k); + + min1 = (dm == SMALLER) ? internal::squared_distance(seg1.source(), seg2, k): + internal::squared_distance(seg1.target(), seg2, k); + + c2s = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.source(), k)); + c2e = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.target(), k)); + dm = CGAL_NTS compare(c2s,c2e); + + if(dm == EQUAL) // should not happen. + return internal::squared_distance_parallel(seg1, seg2, k); + + min2 = (dm == SMALLER) ? internal::squared_distance(seg2.source(), seg1, k): + internal::squared_distance(seg2.target(), seg1, k); + + return (min1 < min2) ? min1 : min2; + } + } +} + +template +typename K::FT +squared_distance(const typename K::Segment_2 &seg1, + const typename K::Segment_2 &seg2, + const K& k, + const Homogeneous_tag&) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + + bool crossing1, crossing2; + RT c1s, c1e, c2s, c2e; + + if(seg1.source() == seg1.target()) + return internal::squared_distance(seg1.source(), seg2, k); + + if(seg2.source() == seg2.target()) + return internal::squared_distance(seg2.source(), seg1, k); + + c1s = wcross(seg2.source(), seg2.target(), seg1.source(), k); + c1e = wcross(seg2.source(), seg2.target(), seg1.target(), k); + c2s = wcross(seg1.source(), seg1.target(), seg2.source(), k); + c2e = wcross(seg1.source(), seg1.target(), seg2.target(), k); + + if(c1s < RT(0)) + { + crossing1 = (c1e >= RT(0)); + } + else + { + if(c1e <= RT(0)) + { + if(c1s == RT(0) && c1e == RT(0)) + return internal::squared_distance_parallel(seg1, seg2, k); + + crossing1 = true; + } + else + { + crossing1 = (c1s == RT(0)); + } + } + + if(c2s < RT(0)) + { + crossing2 = (c2e >= RT(0)); + } + else + { + if(c2e <= RT(0)) + { + if(c2s == RT(0) && c2e == RT(0)) + return internal::squared_distance_parallel(seg1, seg2, k); + + crossing2 = true; + } + else + { + crossing2 = (c2s == RT(0)); + } + } + + if(crossing1) + { + if(crossing2) + return (FT)0; + + RT dm; + dm = _distance_measure_sub(c2s,c2e, seg2.source(), seg2.target()); + if(dm < RT(0)) + { + return internal::squared_distance(seg2.source(), seg1, k); + } + else + { + if(dm > RT(0)) + return internal::squared_distance(seg2.target(), seg1, k); + else // parallel, should not happen (no crossing) + return internal::squared_distance_parallel(seg1, seg2, k); + } + } + else + { + if(crossing2) + { + RT dm = _distance_measure_sub(c1s, c1e,seg1.source(),seg1.target()); + if(dm < RT(0)) + { + return internal::squared_distance(seg1.source(), seg2, k); + } + else + { + if(dm > RT(0)) + return internal::squared_distance(seg1.target(), seg2, k); + else // parallel, should not happen (no crossing) + return internal::squared_distance_parallel(seg1, seg2, k); + } + } + else + { + FT min1, min2; + RT dm = _distance_measure_sub(c1s, c1e, seg1.source(), seg1.target()); + if(dm == RT(0)) + return internal::squared_distance_parallel(seg1, seg2, k); + + min1 = (dm < RT(0)) ? internal::squared_distance(seg1.source(), seg2, k): + internal::squared_distance(seg1.target(), seg2, k); + dm = _distance_measure_sub(c2s, c2e, seg2.source(), seg2.target()); + + if(dm == RT(0)) // should not happen. + return internal::squared_distance_parallel(seg1, seg2, k); + + min2 = (dm < RT(0)) ? internal::squared_distance(seg2.source(), seg1, k): + internal::squared_distance(seg2.target(), seg1, k); + + return (min1 < min2) ? min1 : min2; + } + } +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Segment_2& seg1, + const Segment_2& seg2) +{ + typedef typename K::Kernel_tag Tag; + return internal::squared_distance(seg1, seg2, K(), Tag()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_SEGMENT_2_SEGMENT_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Segment_2_Triangle_2.h b/Distance_2/include/CGAL/Distance_2/Segment_2_Triangle_2.h new file mode 100644 index 00000000000..c8234370526 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Segment_2_Triangle_2.h @@ -0,0 +1,135 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_SEGMENT_2_TRIANGLE_2_H +#define CGAL_DISTANCE_2_SEGMENT_2_TRIANGLE_2_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Segment_2& seg, + const typename K::Triangle_2& triangle, + const K& k) +{ + typedef typename K::FT FT; + typedef typename K::Point_2 Point_2; + + typename K::Orientation_2 orientation = k.orientation_2_object(); + + int i, ind_tr1 = 0, ind_tr2 = -1, ind_seg = 0, ind1, ind2; + FT dist; + + FT mindist = internal::squared_distance(seg.source(), triangle.vertex(0), k); + for(i=0; i<2; ++i) + { + const Point_2& pt = seg.vertex(i); + distance_index(ind1, ind2, pt, triangle, k); + dist = internal::squared_distance_indexed(pt, triangle, ind1, ind2, k); + if(dist < mindist) + { + ind_seg = i; + ind_tr1 = ind1; ind_tr2 = ind2; + mindist = dist; + } + } + + for(i=0; i<3; ++i) + { + const Point_2& pt = triangle.vertex(i); + distance_index(ind1, pt, seg, k); + dist = internal::squared_distance_indexed(pt, seg, ind1, k); + if(dist < mindist) + { + ind_seg = ind1; + ind_tr1 = i; ind_tr2 = -1; + mindist = dist; + } + } + + // now check if all vertices are on the right side of the separating line. + // In case of vertex-vertex smallest distance this is the case. + if(ind_tr2 == -1 && ind_seg != -1) + return mindist; + + if(ind_tr2 != -1) + { + // Check if all the segment vertices lie at the same side of + // the triangle segment. + const Point_2 &vt1 = triangle.vertex(ind_tr1); + const Point_2 &vt2 = triangle.vertex(ind_tr2); + Orientation or_s = orientation(vt1, vt2, seg.source()); + if(orientation(vt1, vt2, seg.target()) != or_s) + mindist = FT(0); + } + else + { + // Check if all the triangle vertices lie + // at the same side of the segment. + const Point_2 &vt1 = seg.source(); + const Point_2 &vt2 = seg.target(); + Orientation or_s = orientation(vt1, vt2, triangle.vertex(0)); + for(i=1; i<3; ++i) + { + if(orientation(vt1, vt2, triangle.vertex(i)) != or_s) + { + mindist = FT(0); + break; + } + } + } + + return mindist; +} + +template +inline typename K::FT +squared_distance(const typename K::Triangle_2 & triangle, + const typename K::Segment_2 & seg, + const K& k) +{ + return internal::squared_distance(seg, triangle, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Segment_2& seg, + const Triangle_2& triangle) +{ + return internal::squared_distance(seg, triangle, K()); +} + +template +inline typename K::FT +squared_distance(const Triangle_2& triangle, + const Segment_2& seg) +{ + return internal::squared_distance(seg, triangle, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_SEGMENT_2_TRIANGLE_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Triangle_2_Triangle_2.h b/Distance_2/include/CGAL/Distance_2/Triangle_2_Triangle_2.h new file mode 100644 index 00000000000..67cb787b215 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Triangle_2_Triangle_2.h @@ -0,0 +1,123 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_TRIANGLE_2_TRIANGLE_2_H +#define CGAL_DISTANCE_2_TRIANGLE_2_TRIANGLE_2_H + +#include +#include + +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Triangle_2& triangle1, + const typename K::Triangle_2& triangle2, + const K& k) +{ + typedef typename K::FT FT; + typedef typename K::Point_2 Point_2; + + typename K::Orientation_2 orientation = k.orientation_2_object(); + + int ind1_1 = 0, ind1_2 = -1, ind2_1 = 0, ind2_2 = -1, ind1, ind2; + FT dist; + + FT mindist = internal::squared_distance(triangle1.vertex(0), triangle2.vertex(0), k); + for(int i=0; i<3; ++i) + { + const Point_2& pt = triangle1.vertex(i); + distance_index(ind1, ind2, pt, triangle2, k); + dist = squared_distance_indexed(pt, triangle2, ind1, ind2, k); + if(dist < mindist) + { + ind1_1 = i; ind1_2 = -1; + ind2_1 = ind1; ind2_2 = ind2; + mindist = dist; + } + } + + for(int i=0; i<3; ++i) + { + const Point_2& pt = triangle2.vertex(i); + distance_index(ind1, ind2, pt, triangle1, k); + dist = squared_distance_indexed(pt, triangle1, ind1, ind2, k); + if(dist < mindist) + { + ind1_1 = ind1; ind1_2 = ind2; + ind2_1 = i; ind2_2 = -1; + mindist = dist; + } + } + + // now check if all vertices are on the right side of the + // separating line. + if(ind1_2 == -1 && ind2_2 == -1) + return mindist; + + // In case of point-segment closest distance, there is still the + // possibility of overlapping triangles. Check if all the + // vertices lie at the same side of the segment. + if(ind1_2 != -1) + { + const Point_2& vt1 = triangle1.vertex(ind1_1); + const Point_2& vt2 = triangle1.vertex(ind1_2); + Orientation or_s = orientation(vt1, vt2, triangle2.vertex(0)); + for(int i=1; i<3; ++i) + { + if(orientation(vt1, vt2, triangle2.vertex(i)) != or_s) + { + mindist = FT(0); + break; + } + } + } + else + { + const Point_2& vt1 = triangle2.vertex(ind2_1); + const Point_2& vt2 = triangle2.vertex(ind2_2); + Orientation or_s = orientation(vt1, vt2, triangle1.vertex(0)); + for(int i=1; i<3; ++i) + { + if(orientation(vt1, vt2, triangle1.vertex(i)) != or_s) + { + mindist = FT(0); + break; + } + } + } + + return mindist; +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Triangle_2& triangle1, + const Triangle_2& triangle2) +{ + return internal::squared_distance(triangle1, triangle2, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_TRIANGLE_2_TRIANGLE_2_H diff --git a/Distance_2/include/CGAL/squared_distance_utils.h b/Distance_2/include/CGAL/Distance_2/internal/squared_distance_utils_2.h similarity index 99% rename from Distance_2/include/CGAL/squared_distance_utils.h rename to Distance_2/include/CGAL/Distance_2/internal/squared_distance_utils_2.h index 7a29ee4f664..b9d48d180fe 100644 --- a/Distance_2/include/CGAL/squared_distance_utils.h +++ b/Distance_2/include/CGAL/Distance_2/internal/squared_distance_utils_2.h @@ -294,7 +294,6 @@ same_direction(const typename K::Vector_2 &u, return same_direction_tag(u,v, k, tag); } - } // namespace internal } //namespace CGAL diff --git a/Distance_2/include/CGAL/squared_distance_2.h b/Distance_2/include/CGAL/squared_distance_2.h index 035d03f703e..115d6910fb9 100644 --- a/Distance_2/include/CGAL/squared_distance_2.h +++ b/Distance_2/include/CGAL/squared_distance_2.h @@ -14,11 +14,27 @@ // // Author(s) : Geert-Jan Giezeman - #ifndef CGAL_SQUARED_DISTANCE_2_H #define CGAL_SQUARED_DISTANCE_2_H -#include -#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include #endif diff --git a/Distance_2/include/CGAL/squared_distance_2_1.h b/Distance_2/include/CGAL/squared_distance_2_1.h deleted file mode 100644 index 171b8fd1e81..00000000000 --- a/Distance_2/include/CGAL/squared_distance_2_1.h +++ /dev/null @@ -1,857 +0,0 @@ -// Copyright (c) 1998-2004 -// Utrecht University (The Netherlands), -// ETH Zurich (Switzerland), -// INRIA Sophia-Antipolis (France), -// Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. -// -// This file is part of CGAL (www.cgal.org) -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Geert-Jan Giezeman -// Michel Hoffmann -// Andreas Fabri - - -#ifndef CGAL_SQUARED_DISTANCE_2_1_H -#define CGAL_SQUARED_DISTANCE_2_1_H - -#include - - -#include -#include -#include -#include -#include - -namespace CGAL { - -namespace internal { - - template - inline typename K::FT - squared_distance(const typename K::Point_2 & pt1, - const typename K::Point_2 & pt2, - const K& k) - { - typename K::Vector_2 vec = k.construct_vector_2_object()(pt2, pt1); - return (typename K::FT)k.compute_squared_length_2_object()(vec); - } - - template - typename K::FT - squared_distance(const typename K::Point_2 &pt, - const typename K::Line_2 &line, - const K&, - const Homogeneous_tag&) - { - typedef typename K::RT RT; - typedef typename K::FT FT; - const RT & a = line.a(); - const RT & b = line.b(); - const RT & w = pt.hw(); - RT n = a*pt.hx() + b*pt.hy() + w * line.c(); - RT d = (CGAL_NTS square(a) + CGAL_NTS square(b)) * CGAL_NTS square(w); - return Rational_traits().make_rational(CGAL_NTS square(n), d); - } - - template - typename K::FT - squared_distance(const typename K::Point_2 &pt, - const typename K::Line_2 &line, - const K&, - const Cartesian_tag&) - { - typedef typename K::FT FT; - const FT & a = line.a(); - const FT & b = line.b(); - FT n = a*pt.x() + b*pt.y() + line.c(); - FT d = CGAL_NTS square(a) + CGAL_NTS square(b); - return CGAL_NTS square(n)/d; - } - - - template - typename K::FT - squared_distance(const typename K::Point_2 &pt, - const typename K::Line_2 &line, - const K& k) - { - typedef typename K::Kernel_tag Tag; - Tag tag; - return squared_distance(pt, line, k, tag); - } - - template - inline typename K::FT - squared_distance(const typename K::Line_2 &line, - const typename K::Point_2 &pt, - const K& k) - { - return internal::squared_distance(pt, line, k); - } - - template - typename K::FT - squared_distance(const typename K::Point_2 &pt, - const typename K::Ray_2 &ray, - const K& k) - { - typedef typename K::Vector_2 Vector_2; - typename K::Construct_vector_2 construct_vector; - Vector_2 diff = construct_vector(ray.source(), pt); - const Vector_2 &dir = ray.direction().vector(); - if (!is_acute_angle(dir,diff, k) ) - return (typename K::FT)k.compute_squared_length_2_object()(diff); - return internal::squared_distance(pt, ray.supporting_line(), k); - } - - template - inline typename K::FT - squared_distance(const typename K::Ray_2 &ray, - const typename K::Point_2 &pt, - const K& k) - { - return internal::squared_distance(pt, ray, k); - } - - template - typename K::FT - squared_distance(const typename K::Point_2 &pt, - const typename K::Segment_2 &seg, - const K& k) - { - typename K::Construct_vector_2 construct_vector; - typedef typename K::Vector_2 Vector_2; - typedef typename K::RT RT; - // assert that the segment is valid (non zero length). - Vector_2 diff = construct_vector(seg.source(), pt); - Vector_2 segvec = construct_vector(seg.source(), seg.target()); - RT d = wdot(diff,segvec, k); - if (d <= (RT)0) - return (typename K::FT)k.compute_squared_length_2_object()(diff); - RT e = wdot(segvec,segvec, k); - if (wmult((K*)0 ,d, segvec.hw()) > wmult((K*)0, e, diff.hw())) - return internal::squared_distance(pt, seg.target(), k); - return internal::squared_distance(pt, seg.supporting_line(), k); - } - - template - inline typename K::FT - squared_distance(const typename K::Segment_2 &seg, - const typename K::Point_2 &pt, - const K& k) - { - return internal::squared_distance(pt, seg, k); - } - - template - typename K::FT - squared_distance_parallel(const typename K::Segment_2 &seg1, - const typename K::Segment_2 &seg2, - const K& k) - { - typedef typename K::Vector_2 Vector_2; - const Vector_2 &dir1 = seg1.direction().vector(); - const Vector_2 &dir2 = seg2.direction().vector(); - if (same_direction(dir1, dir2, k)) { - if (!is_acute_angle(seg1.source(), seg1.target(), seg2.source(), k)) - return internal::squared_distance(seg1.target(), seg2.source(), k); - if (!is_acute_angle(seg1.target(), seg1.source(), seg2.target(), k)) - return internal::squared_distance(seg1.source(), seg2.target(), k); - } else { - if (!is_acute_angle(seg1.source(), seg1.target(), seg2.target(), k)) - return internal::squared_distance(seg1.target(), seg2.target(), k); - if (!is_acute_angle(seg1.target(), seg1.source(), seg2.source(), k)) - return internal::squared_distance(seg1.source(), seg2.source(), k); - } - return internal::squared_distance(seg2.source(), seg1.supporting_line(), k); - } - - template - inline typename K::RT - _distance_measure_sub(const typename K::RT &startwcross, - const typename K::RT &endwcross, - const typename K::Point_2 &start, - const typename K::Point_2 &end) - { - return CGAL_NTS abs(wmult((K*)0, startwcross, end.hw())) - - CGAL_NTS abs(wmult((K*)0, endwcross, start.hw())); - } - - template - typename K::FT - squared_distance(const typename K::Segment_2 &seg1, - const typename K::Segment_2 &seg2, - const K& k, - const Cartesian_tag&) - { - typedef typename K::RT RT; - typedef typename K::FT FT; - bool crossing1, crossing2; - RT c1s, c1e, c2s, c2e; - if (seg1.source() == seg1.target()) - return internal::squared_distance(seg1.source(), seg2, k); - if (seg2.source() == seg2.target()) - return internal::squared_distance(seg2.source(), seg1, k); - - Orientation o1s = orientation(seg2.source(), seg2.target(), seg1.source()); - Orientation o1e = orientation(seg2.source(), seg2.target(), seg1.target()); - if (o1s == RIGHT_TURN) { - crossing1 = (o1e != RIGHT_TURN); - } else { - if (o1e != LEFT_TURN) { - if (o1s == COLLINEAR && o1e == COLLINEAR) - return internal::squared_distance_parallel(seg1, seg2, k); - crossing1 = true; - } else { - crossing1 = (o1s == COLLINEAR); - } - } - - Orientation o2s = orientation(seg1.source(), seg1.target(), seg2.source()); - Orientation o2e = orientation(seg1.source(), seg1.target(), seg2.target()); - if (o2s == RIGHT_TURN) { - crossing2 = (o2e != RIGHT_TURN); - } else { - if (o2e != LEFT_TURN) { - if (o2s == COLLINEAR && o2e == COLLINEAR) - return internal::squared_distance_parallel(seg1, seg2, k); - crossing2 = true; - } else { - crossing2 = (o2s == COLLINEAR); - } - } - - if (crossing1) { - if (crossing2) - return (FT)0; - - c2s = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.source(), k)); - c2e = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.target(), k)); - Comparison_result dm = CGAL::compare(c2s,c2e); - - if (dm == SMALLER) { - return internal::squared_distance(seg2.source(), seg1, k); - } else { - if (dm == LARGER) { - return internal::squared_distance(seg2.target(), seg1, k); - } else { - // parallel, should not happen (no crossing) - return internal::squared_distance_parallel(seg1, seg2, k); - } - } - } else { - c1s = CGAL::abs(wcross(seg2.source(), seg2.target(), seg1.source(), k)); - c1e = CGAL::abs(wcross(seg2.source(), seg2.target(), seg1.target(), k)); - Comparison_result dm = CGAL::compare(c1s,c1e); - if (crossing2) { - if (dm == SMALLER) { - return internal::squared_distance(seg1.source(), seg2, k); - } else { - if (dm == LARGER) { - return internal::squared_distance(seg1.target(), seg2, k); - } else { - // parallel, should not happen (no crossing) - return internal::squared_distance_parallel(seg1, seg2, k); - } - } - } else { - FT min1, min2; - - if (dm == EQUAL) - return internal::squared_distance_parallel(seg1, seg2, k); - min1 = (dm == SMALLER) ? - internal::squared_distance(seg1.source(), seg2, k): - internal::squared_distance(seg1.target(), seg2, k); - - c2s = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.source(), k)); - c2e = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.target(), k)); - dm = CGAL::compare(c2s,c2e); - - if (dm == EQUAL) // should not happen. - return internal::squared_distance_parallel(seg1, seg2, k); - min2 = (dm == SMALLER) ? - internal::squared_distance(seg2.source(), seg1, k): - internal::squared_distance(seg2.target(), seg1, k); - return (min1 < min2) ? min1 : min2; - } - } - } - - template - typename K::FT - squared_distance(const typename K::Segment_2 &seg1, - const typename K::Segment_2 &seg2, - const K& k, - const Homogeneous_tag&) - { - typedef typename K::RT RT; - typedef typename K::FT FT; - bool crossing1, crossing2; - RT c1s, c1e, c2s, c2e; - if (seg1.source() == seg1.target()) - return internal::squared_distance(seg1.source(), seg2, k); - if (seg2.source() == seg2.target()) - return internal::squared_distance(seg2.source(), seg1, k); - c1s = wcross(seg2.source(), seg2.target(), seg1.source(), k); - c1e = wcross(seg2.source(), seg2.target(), seg1.target(), k); - c2s = wcross(seg1.source(), seg1.target(), seg2.source(), k); - c2e = wcross(seg1.source(), seg1.target(), seg2.target(), k); - if (c1s < RT(0)) { - crossing1 = (c1e >= RT(0)); - } else { - if (c1e <= RT(0)) { - if (c1s == RT(0) && c1e == RT(0)) - return internal::squared_distance_parallel(seg1, seg2, k); - crossing1 = true; - } else { - crossing1 = (c1s == RT(0)); - } - } - if (c2s < RT(0)) { - crossing2 = (c2e >= RT(0)); - } else { - if (c2e <= RT(0)) { - if (c2s == RT(0) && c2e == RT(0)) - return internal::squared_distance_parallel(seg1, seg2, k); - crossing2 = true; - } else { - crossing2 = (c2s == RT(0)); - } - } - - if (crossing1) { - if (crossing2) - return (FT)0; - RT dm; - dm = _distance_measure_sub(c2s,c2e, seg2.source(), seg2.target()); - if (dm < RT(0)) { - return internal::squared_distance(seg2.source(), seg1, k); - } else { - if (dm > RT(0)) { - return internal::squared_distance(seg2.target(), seg1, k); - } else { - // parallel, should not happen (no crossing) - return internal::squared_distance_parallel(seg1, seg2, k); - } - } - } else { - if (crossing2) { - RT dm; - dm = - _distance_measure_sub(c1s, c1e,seg1.source(),seg1.target()); - if (dm < RT(0)) { - return internal::squared_distance(seg1.source(), seg2, k); - } else { - if (dm > RT(0)) { - return internal::squared_distance(seg1.target(), seg2, k); - } else { - // parallel, should not happen (no crossing) - return internal::squared_distance_parallel(seg1, seg2, k); - } - } - } else { - - FT min1, min2; - RT dm = _distance_measure_sub( - c1s, c1e, seg1.source(), seg1.target()); - if (dm == RT(0)) - return internal::squared_distance_parallel(seg1, seg2, k); - min1 = (dm < RT(0)) ? - internal::squared_distance(seg1.source(), seg2, k): - internal::squared_distance(seg1.target(), seg2, k); - dm = _distance_measure_sub( - c2s, c2e, seg2.source(), seg2.target()); - if (dm == RT(0)) // should not happen. - return internal::squared_distance_parallel(seg1, seg2, k); - min2 = (dm < RT(0)) ? - internal::squared_distance(seg2.source(), seg1, k): - internal::squared_distance(seg2.target(), seg1, k); - return (min1 < min2) ? min1 : min2; - } - } - } - - - template - inline typename K::RT - _distance_measure_sub(const typename K::RT &startwcross, - const typename K::RT &endwcross, - const typename K::Vector_2 &start, - const typename K::Vector_2 &end) - { - return CGAL_NTS abs(wmult((K*)0, startwcross, end.hw())) - - CGAL_NTS abs(wmult((K*)0, endwcross, start.hw())); - } - - template - typename K::FT - squared_distance_parallel(const typename K::Segment_2 &seg, - const typename K::Ray_2 &ray, - const K& k) - { - typedef typename K::Vector_2 Vector_2; - const Vector_2 &dir1 = seg.direction().vector(); - const Vector_2 &dir2 = ray.direction().vector(); - - if (same_direction(dir1, dir2, k)) { - if (!is_acute_angle(seg.source(), seg.target(), ray.source(), k)) - return internal::squared_distance(seg.target(), ray.source(), k); - } else { - if (!is_acute_angle(seg.target(), seg.source(), ray.source(), k)) - return internal::squared_distance(seg.source(), ray.source(), k); - } - return internal::squared_distance(ray.source(), seg.supporting_line(), k); - } - - template - typename K::FT - squared_distance(const typename K::Segment_2 &seg, - const typename K::Ray_2 &ray, - const K& k) - { - typename K::Construct_vector_2 construct_vector; - typedef typename K::RT RT; - typedef typename K::FT FT; - typedef typename K::Vector_2 Vector_2; - const Vector_2 &raydir = ray.direction().vector(); - Vector_2 startvec(construct_vector(ray.source(), seg.source())); - Vector_2 endvec(construct_vector(ray.source(), seg.target())); - typename K::Orientation_2 orientation; - - bool crossing1, crossing2; - RT c1s, c1e; - if (seg.source() == seg.target()) - return internal::squared_distance(seg.source(), ray, k); - c1s = wcross(raydir, startvec, k); - c1e = wcross(raydir, endvec, k); - if (c1s < RT(0)) { - crossing1 = (c1e >= RT(0)); - } else { - if (c1e <= RT(0)) { - if (c1s == RT(0) && c1e == RT(0)) - return internal::squared_distance_parallel(seg, ray, k); - crossing1 = true; - } else { - crossing1 = (c1s == RT(0)); - } - } - switch (orientation(seg.source(), seg.target(), ray.source())) { - case LEFT_TURN: - crossing2 = right_turn(construct_vector(seg.source(), seg.target()), raydir, k); - break; - case RIGHT_TURN: - crossing2 = left_turn(construct_vector(seg.source(), seg.target()), raydir, k); - break; - default: - crossing2 = true; - break; - } - - if (crossing1) { - if (crossing2) - return FT(0); - return internal::squared_distance(ray.source(), seg, k); - } else { - if (crossing2) { - RT dm; - dm = _distance_measure_sub(c1s, c1e, startvec, endvec); - if (dm < RT(0)) { - return internal::squared_distance(seg.source(), ray, k); - } else { - if (dm > RT(0)) { - return internal::squared_distance(seg.target(), ray, k); - } else { - // parallel, should not happen (no crossing) - return internal::squared_distance_parallel(seg, ray, k); - } - } - } else { - FT min1, min2; - RT dm = _distance_measure_sub(c1s, c1e, startvec, endvec); - if (dm == RT(0)) - return internal::squared_distance_parallel(seg, ray, k); - min1 = (dm < RT(0)) - ? internal::squared_distance(seg.source(), ray, k) - : internal::squared_distance(seg.target(), ray, k); - min2 = internal::squared_distance(ray.source(), seg, k); - return (min1 < min2) ? min1 : min2; - } - } - } - - template - inline typename K::FT - squared_distance(const typename K::Ray_2 &ray, - const typename K::Segment_2 &seg, - const K& k) - { - return internal::squared_distance(seg, ray, k); - } - - template - typename K::FT - _sqd_to_line(const typename K::Vector_2 &diff, - const typename K::RT & wcross, - const typename K::Vector_2 &dir ) - { - typedef typename K::RT RT; - typedef typename K::FT FT; - RT numerator = CGAL_NTS square(wcross); - RT denominator = wmult((K*)0, RT(wdot(dir,dir, K())), - diff.hw(), diff.hw()); - return Rational_traits().make_rational(numerator, denominator); - } - - template - typename K::FT - squared_distance(const typename K::Segment_2 &seg, - const typename K::Line_2 &line, - const K& k) - { - typename K::Construct_vector_2 construct_vector; - typedef typename K::RT RT; - typedef typename K::FT FT; - typedef typename K::Vector_2 Vector_2; - typedef typename K::Point_2 Point_2; - const Vector_2 &linedir = line.direction().vector(); - const Point_2 &linepoint = line.point(); - Vector_2 startvec(construct_vector(linepoint, seg.source())); - Vector_2 endvec(construct_vector(linepoint, seg.target())); - - bool crossing1; - RT c1s, c1e; - if (seg.source() == seg.target()) - return internal::squared_distance(seg.source(), line, k); - c1s = wcross(linedir, startvec, k); - c1e = wcross(linedir, endvec, k); - if (c1s < RT(0)) { - crossing1 = (c1e >= RT(0)); - } else { - if (c1e <= RT(0)) { - crossing1 = true; - } else { - crossing1 = (c1s == RT(0)); - } - } - - if (crossing1) { - return (FT)0; - } else { - RT dm; - dm = _distance_measure_sub(c1s, c1e, startvec, endvec); - if (dm <= RT(0)) { - return _sqd_to_line(startvec, c1s, linedir); - } else { - return _sqd_to_line(endvec, c1e, linedir); - } - } - } - - template - inline typename K::FT - squared_distance(const typename K::Line_2 &line, - const typename K::Segment_2 &seg, - const K& k) - { - return internal::squared_distance(seg, line, k); - } - - template - typename K::FT - ray_ray_squared_distance_parallel( - const typename K::Vector_2 &ray1dir, - const typename K::Vector_2 &ray2dir, - const typename K::Vector_2 &from1to2, - const K& k) - { - typedef typename K::RT RT; - typedef typename K::FT FT; - if (!is_acute_angle(ray1dir, from1to2, k)) { - if (!same_direction(ray1dir, ray2dir, k)) - return (typename K::FT)k.compute_squared_length_2_object()(from1to2); - } - RT wcr, w; - wcr = wcross(ray1dir, from1to2, k); - w = from1to2.hw(); - return (typename K::FT)(FT(wcr*wcr) - / FT(wmult((K*)0, RT(wdot(ray1dir, ray1dir, k)), w, w))); - } - - template - typename K::FT - squared_distance(const typename K::Ray_2 &ray1, - const typename K::Ray_2 &ray2, - const K& k) - { - typename K::Construct_vector_2 construct_vector; - typedef typename K::Vector_2 Vector_2; - typedef typename K::FT FT; - const Vector_2 &ray1dir = ray1.direction().vector(); - const Vector_2 &ray2dir = ray2.direction().vector(); - Vector_2 diffvec(construct_vector(ray1.source(),ray2.source())); - - bool crossing1, crossing2; - switch (orientation(ray1dir, ray2dir, k)) { - case COUNTERCLOCKWISE: - crossing1 = !clockwise(diffvec, ray2dir, k); - crossing2 = !counterclockwise(ray1dir, diffvec, k); - break; - case CLOCKWISE: - crossing1 = !counterclockwise(diffvec, ray2dir, k); - crossing2 = !clockwise(ray1dir, diffvec, k); - break; - default: - return ray_ray_squared_distance_parallel(ray1dir,ray2dir,diffvec,k); - } - - if (crossing1) { - if (crossing2) - return (FT)0; - return internal::squared_distance(ray2.source(), ray1, k); - } else { - if (crossing2) { - return internal::squared_distance(ray1.source(), ray2, k); - } else { - - FT min1, min2; - min1 = internal::squared_distance(ray1.source(), ray2, k); - min2 = internal::squared_distance(ray2.source(), ray1, k); - return (min1 < min2) ? min1 : min2; - } - } - } - - template - typename K::FT - squared_distance(const typename K::Line_2 &line, - const typename K::Ray_2 &ray, - const K& k) - { - typename K::Construct_vector_2 construct_vector; - typedef typename K::FT FT; - typedef typename K::Vector_2 Vector_2; - Vector_2 normalvec(line.a(), line.b()); - Vector_2 diff = construct_vector(line.point(), ray.source()); - FT sign_dist = k.compute_scalar_product_2_object()(diff,normalvec); - if (sign_dist < FT(0)) { - if (is_acute_angle(normalvec, ray.direction().vector(), k) ) - return (FT)0; - } else { - if (is_obtuse_angle(normalvec, ray.direction().vector(), k) ) - return (FT)0; - } - return (typename K::FT)((sign_dist*sign_dist)/k.compute_squared_length_2_object()(normalvec)); - } - - template - inline typename K::FT - squared_distance(const typename K::Ray_2 &ray, - const typename K::Line_2 &line, - const K& k) - { - return internal::squared_distance(line, ray, k); - } - - template - inline typename K::FT - squared_distance(const typename K::Line_2 &line1, - const typename K::Line_2 &line2, - const K& k) - { - typedef typename K::FT FT; - if (internal::parallel(line1, line2, k)) - return internal::squared_distance(line1.point(), line2, k); - else - return (FT)0; - } - - template - void - distance_index(int &ind, - const typename K::Point_2 &pt, - const typename K::Ray_2 &ray, - const K& k) - { - typename K::Construct_vector_2 construct_vector; - if (!is_acute_angle(ray.direction().vector(), construct_vector(ray.source(), pt), k)) { - ind = 0; - return; - } - ind = -1; - } - - template - void - distance_index(int &ind, - const typename K::Point_2 &pt, - const typename K::Segment_2 &seg, - const K& k) - { - if (!is_acute_angle(seg.target(),seg.source(),pt, k)) { - ind = 0; - return; - } - if (!is_acute_angle(seg.source(),seg.target(),pt, k)) { - ind = 1; - return; - } - ind = -1; - } - - template - inline typename K::FT - squared_distance_indexed(const typename K::Point_2 &pt, - const typename K::Ray_2 &ray, - int ind, - const K& k) - { - if (ind == 0) - return internal::squared_distance(pt, ray.source(), k); - return internal::squared_distance(pt, ray.supporting_line(), k); - } - - template - inline typename K::FT - squared_distance_indexed(const typename K::Point_2 &pt, - const typename K::Segment_2 &seg, - int ind, - const K& k) - { - if (ind == 0) - return internal::squared_distance(pt, seg.source(), k); - if (ind == 1) - return internal::squared_distance(pt, seg.target(), k); - return internal::squared_distance(pt, seg.supporting_line(), k); - } - -} // namespace internal - -template -inline typename K::FT -squared_distance(const Point_2 & pt1, const Point_2 & pt2) -{ - return internal::squared_distance(pt1, pt2, K()); -} - - -template -inline typename K::FT -squared_distance(const Point_2 &pt, const Line_2 &line) -{ - return internal::squared_distance(pt, line, K()); -} - - -template -inline typename K::FT -squared_distance(const Line_2 & line, const Point_2 & pt) -{ - return squared_distance(pt, line); -} - - -template -inline typename K::FT -squared_distance(const Point_2 &pt, const Ray_2 &ray) -{ - return internal::squared_distance(pt, ray, K()); -} - -template -inline typename K::FT -squared_distance(const Ray_2 & ray, const Point_2 & pt) -{ - return squared_distance(pt, ray); -} - - -template -inline typename K::FT -squared_distance(const Point_2 &pt, const Segment_2 &seg) -{ - return internal::squared_distance(pt, seg, K()); -} - - -template -inline typename K::FT -squared_distance(const Segment_2 & seg, const Point_2 & pt) -{ - return internal::squared_distance(pt, seg, K()); -} - - -template -inline typename K::FT -squared_distance(const Segment_2 &seg1, const Segment_2 &seg2) -{ - typedef typename K::Kernel_tag Tag; - return internal::squared_distance(seg1, seg2, K(), Tag()); -} - -template -inline typename K::FT -squared_distance(const Segment_2 &seg, const Ray_2 &ray) -{ - return internal::squared_distance(seg, ray, K()); -} - -template -inline typename K::FT -squared_distance(const Ray_2 & ray, const Segment_2 & seg) -{ - return internal::squared_distance(seg, ray, K()); -} - -template -inline typename K::FT -squared_distance(const Segment_2 &seg, const Line_2 &line) -{ - return internal::squared_distance(seg, line, K()); -} - -template -inline typename K::FT -squared_distance(const Line_2 & line, const Segment_2 & seg) -{ - return internal::squared_distance(seg, line, K()); -} - -template -inline typename K::FT -squared_distance(const Ray_2 &ray1, const Ray_2 &ray2) -{ - return internal::squared_distance(ray1, ray2, K()); -} - -template -inline typename K::FT -squared_distance(const Line_2 &line, const Ray_2 &ray) -{ - return internal::squared_distance(line, ray, K()); -} - -template -inline typename K::FT -squared_distance(const Ray_2 & ray, const Line_2 & line) -{ - return internal::squared_distance(line, ray, K()); -} - -template -inline typename K::FT -squared_distance(const Line_2 &line1, const Line_2 &line2) -{ - return internal::squared_distance(line1, line2, K()); -} - -} //namespace CGAL - -#endif diff --git a/Distance_2/include/CGAL/squared_distance_2_2.h b/Distance_2/include/CGAL/squared_distance_2_2.h deleted file mode 100644 index f36f9ebc34c..00000000000 --- a/Distance_2/include/CGAL/squared_distance_2_2.h +++ /dev/null @@ -1,566 +0,0 @@ -// Copyright (c) 1998-2004 -// Utrecht University (The Netherlands), -// ETH Zurich (Switzerland), -// INRIA Sophia-Antipolis (France), -// Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. -// -// This file is part of CGAL (www.cgal.org) -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Geert-Jan Giezeman - - -#ifndef CGAL_SQUARED_DISTANCE_2_2_H -#define CGAL_SQUARED_DISTANCE_2_2_H - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace CGAL { - -namespace internal { - - template - void - distance_index(int &ind1, - int &ind2, - const typename K::Point_2 &pt, - const typename K::Triangle_2 &triangle, - const K& k ) - { - typename K::Left_turn_2 leftturn = k.left_turn_2_object(); - typedef typename K::Point_2 Point_2; - const Point_2 &vt0 = triangle.vertex(0); - const Point_2 &vt1 = triangle.vertex(1); - const Point_2 &vt2 = triangle.vertex(2); - if (leftturn(vt0, vt1, vt2)) { - if (leftturn(pt, vt1, vt0)) { - if (!is_acute_angle(vt0, vt1, pt, k)) { - if (leftturn(pt, vt2, vt1)) { - if (!is_acute_angle(vt1, vt2, pt, k)) { - ind1 = 2; ind2 = -1; - return; - } - if (!is_acute_angle(vt2, vt1, pt, k)) { - ind1 = 1; ind2 = -1; - return; - } - ind1 = 1; ind2 = 2; - return; - } - ind1 = 1; ind2 = -1; - return; - } - if (!is_acute_angle(vt1, vt0, pt, k)) { - if (leftturn(pt, vt0, vt2)) { - if (!is_acute_angle(vt0, vt2, pt, k)) { - ind1 = 2; ind2 = -1; - return; - } - if (!is_acute_angle(vt2, vt0, pt, k)) { - ind1 = 0; ind2 = -1; - return; - } - ind1 = 2; ind2 = 0; - return; - } - ind1 = 0; ind2 = -1; - return; - } - ind1 = 0; ind2 = 1; - return; - } else { - if (leftturn(pt, vt2, vt1)) { - if (!is_acute_angle(vt1, vt2, pt, k)) { - if (leftturn(pt, vt0, vt2)) { - if (!is_acute_angle(vt0, vt2, pt, k)) { - ind1 = 2; ind2 = -1; - return; - } - if (!is_acute_angle(vt2, vt0, pt, k)) { - ind1 = 0; ind2 = -1; - return; - } - ind1 = 2; ind2 = 0; - return; - } - ind1 = 0; ind2 = -1; - return; - } - if (!is_acute_angle(vt2, vt1, pt, k)) { - ind1 = 1; ind2 = -1; - return; - } - ind1 = 1; ind2 = 2; - return; - } else { - if (leftturn(pt, vt0, vt2)) { - if (!is_acute_angle(vt2, vt0, pt, k)) { - ind1 = 0; ind2 = -1; - return; - } - if (!is_acute_angle(vt0, vt2, pt, k)) { - ind1 = 2; ind2 = -1; - return; - } - ind1 = 2; ind2 = 0; - return; - } else { - ind1 = -1; ind2 = -1; // point inside or on boundary. - return; - } - } - } - } else { - if (leftturn(pt, vt2, vt0)) { - if (!is_acute_angle(vt0, vt2, pt, k)) { - if (leftturn(pt, vt1, vt2)) { - if (!is_acute_angle(vt2, vt1, pt, k)) { - ind1 = 1; ind2 = -1; - return; - } - if (!is_acute_angle(vt1, vt2, pt, k)) { - ind1 = 2; ind2 = -1; - return; - } - ind1 = 2; ind2 = 1; - return; - } - ind1 = 2; ind2 = -1; - return; - } - if (!is_acute_angle(vt2, vt0, pt, k)) { - if (leftturn(pt, vt0, vt1)) { - if (!is_acute_angle(vt0, vt1, pt, k)) { - ind1 = 1; ind2 = -1; - return; - } - if (!is_acute_angle(vt1, vt0, pt, k)) { - ind1 = 0; ind2 = -1; - return; - } - ind1 = 1; ind2 = 0; - return; - } - ind1 = 0; ind2 = -1; - return; - } - ind1 = 0; ind2 = 2; - return; - } else { - if (leftturn(pt, vt1, vt2)) { - if (!is_acute_angle(vt2, vt1, pt, k)) { - if (leftturn(pt, vt0, vt1)) { - if (!is_acute_angle(vt0, vt1, pt, k)) { - ind1 = 1; ind2 = -1; - return; - } - if (!is_acute_angle(vt1, vt0, pt, k)) { - ind1 = 0; ind2 = -1; - return; - } - ind1 = 1; ind2 = 0; - return; - } - ind1 = 0; ind2 = -1; - return; - } - if (!is_acute_angle(vt1, vt2, pt, k)) { - ind1 = 2; ind2 = -1; - return; - } - ind1 = 2; ind2 = 1; - return; - } else { - if (leftturn(pt, vt0, vt1)) { - if (!is_acute_angle(vt1, vt0, pt, k)) { - ind1 = 0; ind2 = -1; - return; - } - if (!is_acute_angle(vt0, vt1, pt, k)) { - ind1 = 1; ind2 = -1; - return; - } - ind1 = 1; ind2 = 0; - return; - } else { - ind1 = -1; ind2 = -1; // point inside or on boundary. - return; - } - } - } - } - } - - - - - template - typename K::FT - squared_distance_indexed(const typename K::Point_2 &pt, - const typename K::Triangle_2 &triangle, - int ind1, int ind2, - const K& k) - { - typedef typename K::FT FT; - typedef typename K::Line_2 Line_2; - if (ind1 == -1) - return FT(0); - if (ind2 == -1) - return internal::squared_distance(pt, triangle.vertex(ind1), k); - return internal::squared_distance(pt, - Line_2(triangle.vertex(ind1), triangle.vertex(ind2)), - k); - } - - - - template - typename K::FT - squared_distance(const typename K::Point_2 &pt, - const typename K::Triangle_2 &triangle, - const K& k) - { - int ind1,ind2; - distance_index(ind1, ind2, pt, triangle, k); - return squared_distance_indexed(pt, triangle, ind1, ind2, k); - } - - - template - inline typename K::FT - squared_distance(const typename K::Triangle_2 & triangle, - const typename K::Point_2 & pt, - const K& k) - { - return internal::squared_distance(pt, triangle, k); - } - - - template - typename K::FT - squared_distance(const typename K::Line_2 &line, - const typename K::Triangle_2 &triangle, - const K& k) - { - typedef typename K::FT FT; - Oriented_side side0; - side0 = line.oriented_side(triangle.vertex(0)); - if (line.oriented_side(triangle.vertex(1)) != side0) - return FT(0); - if (line.oriented_side(triangle.vertex(2)) != side0) - return FT(0); - FT mindist, dist; - int i; - mindist = internal::squared_distance(triangle.vertex(0),line,k); - for (i=1; i<3; i++) { - dist = internal::squared_distance(triangle.vertex(i),line,k); - if (dist < mindist) - mindist = dist; - } - return mindist; - } - - - template - inline typename K::FT - squared_distance(const typename K::Triangle_2 & triangle, - const typename K::Line_2 & line, - const K& k) - { - return internal::squared_distance(line, triangle, k); - } - - - template - typename K::FT - squared_distance(const typename K::Ray_2 &ray, - const typename K::Triangle_2 &triangle, - const K& k) - { - typedef typename K::FT FT; - typedef typename K::Point_2 Point_2; - typedef typename K::Line_2 Line_2; - int i, ind_tr1, ind_tr2, ind_ray = 0, ind1; - FT mindist, dist; - distance_index(ind_tr1, ind_tr2, ray.source(), triangle, k); - mindist = - squared_distance_indexed(ray.source(), triangle, ind_tr1, ind_tr2, k); - for (i=0; i<3; i++) { - const Point_2& pt = triangle.vertex(i); - distance_index(ind1, pt, ray, k); - dist = squared_distance_indexed(pt, ray, ind1, k); - if (dist < mindist) { - ind_ray = ind1; - ind_tr1 = i; ind_tr2 = -1; - mindist = dist; - } - } - // now check if all vertices are on the right side of the separating line. - // In case of vertex-vertex smallest distance this is the case. - if (ind_tr2 == -1 && ind_ray != -1) - return mindist; - if (ind_tr2 != -1) { - // Check if all the segment vertices lie at the same side of - // the triangle segment. - const Point_2 &vt1 = triangle.vertex(ind_tr1); - const Point_2 &vt2 = triangle.vertex(ind_tr2); - if (clockwise(ray.direction().vector(), vt2-vt1, k)) { - mindist = FT(0); - } - } else { - // Check if all the triangle vertices lie - // at the same side of the segment. - const Line_2 &sl = ray.supporting_line(); - Oriented_side or_s = sl.oriented_side(triangle.vertex(0)); - for (i=1; i<3; i++) { - if (sl.oriented_side(triangle.vertex(i)) != or_s) { - mindist = FT(0); - break; - } - } - } - return mindist; - } - - - template - inline typename K::FT - squared_distance(const typename K::Triangle_2 & triangle, - const typename K::Ray_2 & ray, - const K& k) - { - return internal::squared_distance(ray, triangle, k); - } - - - template - typename K::FT - squared_distance(const typename K::Segment_2 &seg, - const typename K::Triangle_2 &triangle, - const K& k) - { - typedef typename K::FT FT; - typedef typename K::Point_2 Point_2; - typename K::Orientation_2 orientation; - int i, ind_tr1 = 0, ind_tr2 = -1, ind_seg = 0, ind1, ind2; - FT mindist, dist; - mindist = internal::squared_distance(seg.source(), triangle.vertex(0), k); - for (i=0; i<2; i++) { - const Point_2 &pt = seg.vertex(i); - distance_index(ind1, ind2, pt, triangle, k); - dist = internal::squared_distance_indexed(pt, triangle, ind1, ind2, k); - if (dist < mindist) { - ind_seg = i; - ind_tr1 = ind1; ind_tr2 = ind2; - mindist = dist; - } - } - for (i=0; i<3; i++) { - const Point_2& pt = triangle.vertex(i); - distance_index(ind1, pt, seg, k); - dist = internal::squared_distance_indexed(pt, seg, ind1, k); - if (dist < mindist) { - ind_seg = ind1; - ind_tr1 = i; ind_tr2 = -1; - mindist = dist; - } - } - // now check if all vertices are on the right side of the separating line. - // In case of vertex-vertex smallest distance this is the case. - if (ind_tr2 == -1 && ind_seg != -1) - return mindist; - - if (ind_tr2 != -1) { - // Check if all the segment vertices lie at the same side of - // the triangle segment. - const Point_2 &vt1 = triangle.vertex(ind_tr1); - const Point_2 &vt2 = triangle.vertex(ind_tr2); - Orientation or_s = orientation(vt1, vt2, seg.source()); - if (orientation(vt1, vt2, seg.target()) != or_s) { - mindist = FT(0); - } - } else { - // Check if all the triangle vertices lie - // at the same side of the segment. - const Point_2 &vt1 = seg.source(); - const Point_2 &vt2 = seg.target(); - Orientation or_s = orientation(vt1, vt2, triangle.vertex(0)); - for (i=1; i<3; i++) { - if (orientation(vt1, vt2, triangle.vertex(i)) != or_s) { - mindist = FT(0); - break; - } - } - } - return mindist; - } - - - template - inline typename K::FT - squared_distance(const typename K::Triangle_2 & triangle, - const typename K::Segment_2 & seg, - const K& k) - { - return internal::squared_distance(seg, triangle, k); - } - - - - template - typename K::FT - squared_distance(const typename K::Triangle_2 &triangle1, - const typename K::Triangle_2 &triangle2, - const K& k) - { - typedef typename K::FT FT; - typedef typename K::Point_2 Point_2; - typename K::Orientation_2 orientation; - int i, ind1_1 = 0,ind1_2 = -1, ind2_1 = 0, ind2_2 = -1, ind1, ind2; - FT mindist, dist; - mindist = - internal::squared_distance(triangle1.vertex(0), triangle2.vertex(0), k); - for (i=0; i<3; i++) { - const Point_2& pt = triangle1.vertex(i); - distance_index(ind1, ind2, pt, triangle2, k); - dist = squared_distance_indexed(pt, triangle2, ind1, ind2, k); - if (dist < mindist) { - ind1_1 = i; ind1_2 = -1; - ind2_1 = ind1; ind2_2 = ind2; - mindist = dist; - } - } - for (i=0; i<3; i++) { - const Point_2& pt = triangle2.vertex(i); - distance_index(ind1, ind2, pt, triangle1, k); - dist = squared_distance_indexed(pt, triangle1, ind1, ind2, k); - if (dist < mindist) { - ind1_1 = ind1; ind1_2 = ind2; - ind2_1 = i; ind2_2 = -1; - mindist = dist; - } - } - // now check if all vertices are on the right side of the - // separating line. - if (ind1_2 == -1 && ind2_2 == -1) - return mindist; - // In case of point-segment closest distance, there is still the - // possibility of overlapping triangles. Check if all the - // vertices lie at the same side of the segment. - if (ind1_2 != -1) { - const Point_2 &vt1 = triangle1.vertex(ind1_1); - const Point_2 &vt2 = triangle1.vertex(ind1_2); - Orientation or_s = orientation(vt1, vt2, triangle2.vertex(0)); - for (i=1; i<3; i++) { - if (orientation(vt1, vt2, triangle2.vertex(i)) != or_s) { - mindist = FT(0); - break; - } - } - } else { - const Point_2 &vt1 = triangle2.vertex(ind2_1); - const Point_2 &vt2 = triangle2.vertex(ind2_2); - Orientation or_s = orientation(vt1, vt2, triangle1.vertex(0)); - for (i=1; i<3; i++) { - if (orientation(vt1, vt2, triangle1.vertex(i)) != or_s) { - mindist = FT(0); - break; - } - } - } - return mindist; - } - -} // namespace internal - -template -inline typename K::FT -squared_distance(const Point_2 &pt, - const Triangle_2 &triangle) -{ - return internal::squared_distance(pt, triangle, K()); -} - -template -inline typename K::FT -squared_distance(const Triangle_2 &triangle, - const Point_2 &pt) -{ - return internal::squared_distance(pt, triangle, K()); -} - -template -inline typename K::FT -squared_distance(const Line_2 &line, - const Triangle_2 &triangle) -{ - return internal::squared_distance(line, triangle, K()); -} - -template -inline typename K::FT -squared_distance(const Triangle_2 &triangle, - const Line_2 &line) -{ - return internal::squared_distance(line, triangle, K()); -} - -template -inline typename K::FT -squared_distance(const Ray_2 &ray, - const Triangle_2 &triangle) -{ - return internal::squared_distance(ray, triangle, K()); -} - -template -inline typename K::FT -squared_distance(const Triangle_2 &triangle, - const Ray_2 &ray) -{ - return internal::squared_distance(ray, triangle, K()); -} - -template -inline typename K::FT -squared_distance(const Segment_2 &seg, - const Triangle_2 &triangle) -{ - return internal::squared_distance(seg, triangle, K()); -} - -template -inline typename K::FT -squared_distance(const Triangle_2 &triangle, - const Segment_2 &seg) -{ - return internal::squared_distance(seg, triangle, K()); -} - -template -inline typename K::FT -squared_distance(const Triangle_2 &triangle1, - const Triangle_2 &triangle2) -{ - return internal::squared_distance(triangle1, triangle2, K()); -} - -} //namespace CGAL - -#endif diff --git a/Distance_2/test/Distance_2/test_distance_2.cpp b/Distance_2/test/Distance_2/test_distance_2.cpp index 0268e606295..371086c6185 100644 --- a/Distance_2/test/Distance_2/test_distance_2.cpp +++ b/Distance_2/test/Distance_2/test_distance_2.cpp @@ -167,7 +167,7 @@ struct Test { check_squared_distance (R(p( 4, 0), p(-3, -1)), R(p( 1, 1), p( 2, 11)), 2); } - void R_S() + void S_R() { std::cout << "Ray - Segment\n"; check_squared_distance (R(p(2, 0), p( 0, 2)), S(p( 1, 1), p( 4, 0)), 0); @@ -216,7 +216,7 @@ struct Test { check_squared_distance (p( 1, 1), L(p( 4, 0), p( -3, -1)), 2); } - void L_S() + void S_L() { std::cout << "Line - Segment\n"; check_squared_distance (L(p( 0, 0), p( 1, 0)), S(p( 2, 2), p( 3, 3)), 4); @@ -271,26 +271,30 @@ struct Test { std::cout << "2D Distance tests\n"; P_P(); P_S(); - S_S(); P_R(); - R_R(); - R_S(); - R_L(); P_L(); - L_S(); - L_L(); P_T(); - L_T(); - R_T(); + + S_S(); S_T(); + S_R(); + S_L(); + + R_R(); + R_L(); + R_T(); + + L_L(); + L_T(); + T_T(); } - }; int main() { - Test< CGAL::Simple_cartesian >().run(); - Test< CGAL::Simple_homogeneous >().run(); - // TODO : test more kernels. + Test< CGAL::Simple_cartesian >().run(); + Test< CGAL::Simple_homogeneous >().run(); + + // TODO : test more kernels. } diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Circle_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Circle_2.h index 4b05ffa7a34..4f24b27c2de 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Circle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Circle_2.h @@ -17,11 +17,11 @@ #ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_CIRCLE_2_H #define CGAL_INTERSECTIONS_2_CIRCLE_2_CIRCLE_2_H -#include -#include - +#include #include +#include + namespace CGAL { namespace Intersections { namespace internal { diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h index 2ff82e64475..a850baa2253 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h @@ -18,10 +18,11 @@ #ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_LINE_2_H #define CGAL_INTERSECTIONS_2_CIRCLE_2_LINE_2_H +#include +#include + #include #include -#include -#include namespace CGAL { namespace Intersections { diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h index 6a4c9d8b25d..18c19fd8466 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h @@ -13,10 +13,11 @@ #ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_RAY_2_H #define CGAL_INTERSECTIONS_2_CIRCLE_2_RAY_2_H +#include +#include + #include #include -#include -#include namespace CGAL { namespace Intersections { diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h index efed12af6e3..71384fcc4e6 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h @@ -13,10 +13,11 @@ #ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_SEGMENT_2_H #define CGAL_INTERSECTIONS_2_CIRCLE_2_SEGMENT_2_H +#include +#include + #include #include -#include -#include namespace CGAL { namespace Intersections { diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h index 35cfdd3ac01..9353da936ba 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h @@ -13,10 +13,12 @@ #ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_TRIANGLE_2_H #define CGAL_INTERSECTIONS_2_CIRCLE_2_TRIANGLE_2_H +#include +#include +#include + #include #include -#include -#include namespace CGAL { namespace Intersections { diff --git a/Intersections_2/include/CGAL/Intersections_2/internal/Straight_2.h b/Intersections_2/include/CGAL/Intersections_2/internal/Straight_2.h index fa63e699475..36cc7e06486 100644 --- a/Intersections_2/include/CGAL/Intersections_2/internal/Straight_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/internal/Straight_2.h @@ -18,8 +18,8 @@ #ifndef CGAL_INTERSECTIONS_2_INTERNAL_STRAIGHT_2_H #define CGAL_INTERSECTIONS_2_INTERNAL_STRAIGHT_2_H +#include #include -#include #include namespace CGAL { diff --git a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h index 896c6bf5748..3a22168af8e 100644 --- a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h +++ b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h @@ -22,6 +22,7 @@ #include #include #include +#include namespace CGAL { diff --git a/Nef_2/include/CGAL/Extended_homogeneous.h b/Nef_2/include/CGAL/Extended_homogeneous.h index 83c64b7c888..704db06ca6f 100644 --- a/Nef_2/include/CGAL/Extended_homogeneous.h +++ b/Nef_2/include/CGAL/Extended_homogeneous.h @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #undef CGAL_NEF_DEBUG diff --git a/Point_set_2/include/CGAL/Point_set_2.h b/Point_set_2/include/CGAL/Point_set_2.h index 25e3845d922..c9ac5efe759 100644 --- a/Point_set_2/include/CGAL/Point_set_2.h +++ b/Point_set_2/include/CGAL/Point_set_2.h @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/Point_set_2/include/CGAL/nearest_neighbor_delaunay_2.h b/Point_set_2/include/CGAL/nearest_neighbor_delaunay_2.h index 365a9364dff..002b18d819b 100644 --- a/Point_set_2/include/CGAL/nearest_neighbor_delaunay_2.h +++ b/Point_set_2/include/CGAL/nearest_neighbor_delaunay_2.h @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/Polyhedron/include/CGAL/boost/graph/properties_Polyhedron_3.h b/Polyhedron/include/CGAL/boost/graph/properties_Polyhedron_3.h index a53bde8e724..b4aa673adaf 100644 --- a/Polyhedron/include/CGAL/boost/graph/properties_Polyhedron_3.h +++ b/Polyhedron/include/CGAL/boost/graph/properties_Polyhedron_3.h @@ -15,10 +15,10 @@ #include #include #include -#include #include #include #include +#include #define CGAL_HDS_PARAM_ template < class Traits, class Items, class Alloc> class HDS From 518aad8b78ec760bfac7805ccbac820f3367f600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 12 Apr 2021 17:42:12 +0200 Subject: [PATCH 19/23] Add missing include --- .../include/CGAL/Distance_2/internal/squared_distance_utils_2.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Distance_2/include/CGAL/Distance_2/internal/squared_distance_utils_2.h b/Distance_2/include/CGAL/Distance_2/internal/squared_distance_utils_2.h index b9d48d180fe..6a852577f5c 100644 --- a/Distance_2/include/CGAL/Distance_2/internal/squared_distance_utils_2.h +++ b/Distance_2/include/CGAL/Distance_2/internal/squared_distance_utils_2.h @@ -19,6 +19,7 @@ #define CGAL_SQUARED_DISTANCE_UTILS_H #include +#include #include namespace CGAL { From 8b77c7139eea394dea180babf457911b5dcb422e Mon Sep 17 00:00:00 2001 From: Mael Date: Mon, 12 Apr 2021 22:37:15 +0200 Subject: [PATCH 20/23] Update dependencies of PS2 --- Point_set_2/package_info/Point_set_2/dependencies | 1 - 1 file changed, 1 deletion(-) diff --git a/Point_set_2/package_info/Point_set_2/dependencies b/Point_set_2/package_info/Point_set_2/dependencies index 8978ceba4bf..22b6e1e57b7 100644 --- a/Point_set_2/package_info/Point_set_2/dependencies +++ b/Point_set_2/package_info/Point_set_2/dependencies @@ -1,6 +1,5 @@ Algebraic_foundations Circulator -Distance_2 Filtered_kernel Hash_map Installation From b95c60fc9fe671eb42a6811e137ab48167657db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 27 Apr 2021 22:40:22 +0200 Subject: [PATCH 21/23] Avoid needless orientation checks / distance computations If we are right of the edge, the distance is minimum over the edge... ...and that's it. Computing the distance to a segment is about as expensive as the orientation check, so no point pinpointing to check if the min is at a vertex. --- .../CGAL/Distance_3/Point_3_Triangle_3.h | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) 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 7f1c4d5acdd..4231977b22d 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 @@ -64,26 +64,38 @@ squared_distance_to_triangle(const typename K::Point_3& pt, const Vector_3 oe3 = vector(t0, t2); const Vector_3 normal = wcross(e1, oe3, k); - if(normal != NULL_VECTOR && - on_left_of_triangle_edge(pt, normal, t0, t1, k) && - on_left_of_triangle_edge(pt, normal, t1, t2, k) && - on_left_of_triangle_edge(pt, normal, t2, t0, k)) - { - // the projection of pt is inside the triangle - inside = true; - return squared_distance_to_plane(normal, vector(t0, pt), k); - } - else + 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 = internal::squared_distance(pt, segment(t2, t0), k); typename K::FT d2 = internal::squared_distance(pt, segment(t1, t2), k); typename K::FT d3 = internal::squared_distance(pt, segment(t0, t1), k); return (std::min)( (std::min)(d1, d2), d3); } + + const bool b01 = on_left_of_triangle_edge(pt, normal, t0, t1, k); + if(!b01) + return internal::squared_distance(pt, segment(t0, t1), k); + + const bool b12 = on_left_of_triangle_edge(pt, normal, t1, t2, k); + if(!b12) + return internal::squared_distance(pt, segment(t1, t2), k); + + const bool b20 = on_left_of_triangle_edge(pt, normal, t2, t0, k); + if(!b20) + return internal::squared_distance(pt, segment(t2, t0), k); + + // The projection of pt is inside the triangle + inside = true; + return squared_distance_to_plane(normal, vector(t0, pt), k); } template From cf15bbe80eaa35b9292e8cee81a9d24edffb93bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 7 May 2021 19:22:00 +0200 Subject: [PATCH 22/23] Fix functor usage in Distance_23 + various code improvements along the way --- .../include/CGAL/Distance_2/Line_2_Line_2.h | 8 +- .../CGAL/Distance_2/Line_2_Triangle_2.h | 13 +- .../include/CGAL/Distance_2/Point_2_Line_2.h | 4 +- .../include/CGAL/Distance_2/Point_2_Point_2.h | 2 +- .../CGAL/Distance_2/Point_2_Segment_2.h | 34 ++-- .../CGAL/Distance_2/Point_2_Triangle_2.h | 10 +- .../include/CGAL/Distance_2/Ray_2_Line_2.h | 4 +- .../include/CGAL/Distance_2/Ray_2_Ray_2.h | 21 +-- .../CGAL/Distance_2/Ray_2_Triangle_2.h | 10 +- .../CGAL/Distance_2/Segment_2_Line_2.h | 30 ++-- .../include/CGAL/Distance_2/Segment_2_Ray_2.h | 57 ++++--- .../CGAL/Distance_2/Segment_2_Segment_2.h | 128 ++++++++------- .../CGAL/Distance_2/Segment_2_Triangle_2.h | 13 +- .../CGAL/Distance_2/Triangle_2_Triangle_2.h | 10 +- .../test/Distance_2/test_distance_2.cpp | 19 ++- .../include/CGAL/Distance_3/Line_3_Line_3.h | 12 +- .../include/CGAL/Distance_3/Line_3_Plane_3.h | 11 +- .../include/CGAL/Distance_3/Plane_3_Plane_3.h | 27 +++- .../include/CGAL/Distance_3/Point_3_Line_3.h | 11 +- .../include/CGAL/Distance_3/Point_3_Plane_3.h | 4 +- .../include/CGAL/Distance_3/Point_3_Ray_3.h | 12 +- .../CGAL/Distance_3/Point_3_Segment_3.h | 28 ++-- .../CGAL/Distance_3/Point_3_Tetrahedron_3.h | 4 +- .../CGAL/Distance_3/Point_3_Triangle_3.h | 38 +++-- .../Distance_3/Point_3_Weighted_point_3.h | 4 +- .../include/CGAL/Distance_3/Ray_3_Line_3.h | 49 +++--- .../include/CGAL/Distance_3/Ray_3_Plane_3.h | 30 ++-- .../include/CGAL/Distance_3/Ray_3_Ray_3.h | 91 ++++++----- .../CGAL/Distance_3/Segment_3_Line_3.h | 45 +++--- .../CGAL/Distance_3/Segment_3_Plane_3.h | 31 ++-- .../include/CGAL/Distance_3/Segment_3_Ray_3.h | 148 +++++++++--------- .../CGAL/Distance_3/Segment_3_Segment_3.h | 29 ++-- .../CGAL/Distance_3/Triangle_3_Triangle_3.h | 4 +- .../Weighted_point_3_Weighted_point_3.h | 6 +- .../test/Distance_3/test_distance_3.cpp | 32 ++-- 35 files changed, 528 insertions(+), 451 deletions(-) diff --git a/Distance_2/include/CGAL/Distance_2/Line_2_Line_2.h b/Distance_2/include/CGAL/Distance_2/Line_2_Line_2.h index b87124a8ee9..53fef5cbd53 100644 --- a/Distance_2/include/CGAL/Distance_2/Line_2_Line_2.h +++ b/Distance_2/include/CGAL/Distance_2/Line_2_Line_2.h @@ -20,7 +20,6 @@ #define CGAL_DISTANCE_2_LINE_2_LINE_2_H #include -#include #include #include @@ -35,8 +34,11 @@ squared_distance(const typename K::Line_2& line1, const K& k) { typedef typename K::FT FT; + + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + if(internal::parallel(line1, line2, k)) - return internal::squared_distance(line1.point(), line2, k); + return sq_dist(line1.point(), line2); else return FT(0); } @@ -48,7 +50,7 @@ inline typename K::FT squared_distance(const Line_2& line1, const Line_2& line2) { - return internal::squared_distance(line1, line2, K()); + return K().compute_squared_distance_2_object()(line1, line2); } } // namespace CGAL diff --git a/Distance_2/include/CGAL/Distance_2/Line_2_Triangle_2.h b/Distance_2/include/CGAL/Distance_2/Line_2_Triangle_2.h index 6ba20ce2eef..3f9fc69ac3d 100644 --- a/Distance_2/include/CGAL/Distance_2/Line_2_Triangle_2.h +++ b/Distance_2/include/CGAL/Distance_2/Line_2_Triangle_2.h @@ -20,7 +20,6 @@ #define CGAL_DISTANCE_2_LINE_2_TRIANGLE_2_H #include -#include #include @@ -38,17 +37,19 @@ squared_distance(const typename K::Line_2& line, { typedef typename K::FT FT; - Oriented_side side0 = line.oriented_side(triangle.vertex(0)); + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + const Oriented_side side0 = line.oriented_side(triangle.vertex(0)); if(line.oriented_side(triangle.vertex(1)) != side0) return FT(0); if(line.oriented_side(triangle.vertex(2)) != side0) return FT(0); - FT mindist = internal::squared_distance(triangle.vertex(0), line, k); + FT mindist = sq_dist(triangle.vertex(0), line); for(int i=1; i<3; ++i) { - FT dist = internal::squared_distance(triangle.vertex(i), line, k); + FT dist = sq_dist(triangle.vertex(i), line); if(dist < mindist) mindist = dist; } @@ -72,7 +73,7 @@ inline typename K::FT squared_distance(const Line_2& line, const Triangle_2& triangle) { - return internal::squared_distance(line, triangle, K()); + return K().compute_squared_distance_2_object()(line, triangle); } template @@ -80,7 +81,7 @@ inline typename K::FT squared_distance(const Triangle_2& triangle, const Line_2& line) { - return internal::squared_distance(line, triangle, K()); + return K().compute_squared_distance_2_object()(triangle, line); } } // namespace CGAL diff --git a/Distance_2/include/CGAL/Distance_2/Point_2_Line_2.h b/Distance_2/include/CGAL/Distance_2/Point_2_Line_2.h index 43f1ff622ff..61550cb6908 100644 --- a/Distance_2/include/CGAL/Distance_2/Point_2_Line_2.h +++ b/Distance_2/include/CGAL/Distance_2/Point_2_Line_2.h @@ -92,7 +92,7 @@ inline typename K::FT squared_distance(const Point_2& pt, const Line_2& line) { - return internal::squared_distance(pt, line, K()); + return K().compute_squared_distance_2_object()(pt, line); } template @@ -100,7 +100,7 @@ inline typename K::FT squared_distance(const Line_2& line, const Point_2& pt) { - return internal::squared_distance(pt, line, K()); + return K().compute_squared_distance_2_object()(line, pt); } } // namespace CGAL diff --git a/Distance_2/include/CGAL/Distance_2/Point_2_Point_2.h b/Distance_2/include/CGAL/Distance_2/Point_2_Point_2.h index d8ae488e0a7..b7405fddd6b 100644 --- a/Distance_2/include/CGAL/Distance_2/Point_2_Point_2.h +++ b/Distance_2/include/CGAL/Distance_2/Point_2_Point_2.h @@ -41,7 +41,7 @@ inline typename K::FT squared_distance(const Point_2& pt1, const Point_2& pt2) { - return internal::squared_distance(pt1, pt2, K()); + return K().compute_squared_distance_2_object()(pt1, pt2); } } // namespace CGAL diff --git a/Distance_2/include/CGAL/Distance_2/Point_2_Segment_2.h b/Distance_2/include/CGAL/Distance_2/Point_2_Segment_2.h index c8dd3486141..cc591908a2b 100644 --- a/Distance_2/include/CGAL/Distance_2/Point_2_Segment_2.h +++ b/Distance_2/include/CGAL/Distance_2/Point_2_Segment_2.h @@ -20,8 +20,6 @@ #define CGAL_DISTANCE_2_POINT_2_SEGMENT_2_H #include -#include -#include #include #include @@ -57,11 +55,15 @@ squared_distance_indexed(const typename K::Point_2 &pt, int ind, const K& k) { + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + if(ind == 0) - return internal::squared_distance(pt, seg.source(), k); + return sq_dist(pt, seg.source()); + if(ind == 1) - return internal::squared_distance(pt, seg.target(), k); - return internal::squared_distance(pt, seg.supporting_line(), k); + return sq_dist(pt, seg.target()); + + return sq_dist(pt, seg.supporting_line()); } template @@ -73,21 +75,23 @@ squared_distance(const typename K::Point_2& pt, typedef typename K::Vector_2 Vector_2; typedef typename K::RT RT; - typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object(); + typename K::Construct_vector_2 vector = k.construct_vector_2_object(); + typename K::Compute_squared_length_2 sq_length = k.compute_squared_length_2_object(); + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); // assert that the segment is valid (non zero length). - Vector_2 diff = construct_vector(seg.source(), pt); - Vector_2 segvec = construct_vector(seg.source(), seg.target()); + const Vector_2 diff = vector(seg.source(), pt); + const Vector_2 segvec = vector(seg.source(), seg.target()); - RT d = wdot(diff, segvec, k); + const RT d = wdot(diff, segvec, k); if(d <= RT(0)) - return k.compute_squared_length_2_object()(diff); + return sq_length(diff); - RT e = wdot(segvec,segvec, k); + const RT e = wdot(segvec,segvec, k); if(wmult((K*)0 ,d, segvec.hw()) > wmult((K*)0, e, diff.hw())) - return internal::squared_distance(pt, seg.target(), k); + return sq_dist(pt, seg.target()); - return internal::squared_distance(pt, seg.supporting_line(), k); + return sq_dist(pt, seg.supporting_line()); } template @@ -106,7 +110,7 @@ inline typename K::FT squared_distance(const Point_2& pt, const Segment_2& seg) { - return internal::squared_distance(pt, seg, K()); + return K().compute_squared_distance_2_object()(pt, seg); } template @@ -114,7 +118,7 @@ inline typename K::FT squared_distance(const Segment_2& seg, const Point_2& pt) { - return internal::squared_distance(pt, seg, K()); + return K().compute_squared_distance_2_object()(seg, pt); } } // namespace CGAL diff --git a/Distance_2/include/CGAL/Distance_2/Point_2_Triangle_2.h b/Distance_2/include/CGAL/Distance_2/Point_2_Triangle_2.h index 9cd6c83fe14..2448737e116 100644 --- a/Distance_2/include/CGAL/Distance_2/Point_2_Triangle_2.h +++ b/Distance_2/include/CGAL/Distance_2/Point_2_Triangle_2.h @@ -212,13 +212,15 @@ squared_distance_indexed(const typename K::Point_2& pt, typedef typename K::FT FT; typedef typename K::Line_2 Line_2; + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + if(ind1 == -1) return FT(0); if(ind2 == -1) - return internal::squared_distance(pt, triangle.vertex(ind1), k); + return sq_dist(pt, triangle.vertex(ind1)); - return internal::squared_distance(pt, Line_2(triangle.vertex(ind1), triangle.vertex(ind2)), k); + return sq_dist(pt, Line_2{triangle.vertex(ind1), triangle.vertex(ind2)}); } template @@ -248,7 +250,7 @@ inline typename K::FT squared_distance(const Point_2& pt, const Triangle_2& triangle) { - return internal::squared_distance(pt, triangle, K()); + return K().compute_squared_distance_2_object()(pt, triangle); } template @@ -256,7 +258,7 @@ inline typename K::FT squared_distance(const Triangle_2& triangle, const Point_2& pt) { - return internal::squared_distance(pt, triangle, K()); + return K().compute_squared_distance_2_object()(triangle, pt); } } // namespace CGAL diff --git a/Distance_2/include/CGAL/Distance_2/Ray_2_Line_2.h b/Distance_2/include/CGAL/Distance_2/Ray_2_Line_2.h index bef607cf383..ea3c8fb7af0 100644 --- a/Distance_2/include/CGAL/Distance_2/Ray_2_Line_2.h +++ b/Distance_2/include/CGAL/Distance_2/Ray_2_Line_2.h @@ -72,7 +72,7 @@ inline typename K::FT squared_distance(const Line_2& line, const Ray_2& ray) { - return internal::squared_distance(line, ray, K()); + return K().compute_squared_distance_2_object()(line, ray); } template @@ -80,7 +80,7 @@ inline typename K::FT squared_distance(const Ray_2& ray, const Line_2& line) { - return internal::squared_distance(line, ray, K()); + return K().compute_squared_distance_2_object()(ray, line); } } // namespace CGAL diff --git a/Distance_2/include/CGAL/Distance_2/Ray_2_Ray_2.h b/Distance_2/include/CGAL/Distance_2/Ray_2_Ray_2.h index 87fdf1903f6..f8d046f602a 100644 --- a/Distance_2/include/CGAL/Distance_2/Ray_2_Ray_2.h +++ b/Distance_2/include/CGAL/Distance_2/Ray_2_Ray_2.h @@ -46,7 +46,7 @@ ray_ray_squared_distance_parallel(const typename K::Vector_2& ray1dir, RT wcr = wcross(ray1dir, from1to2, k); RT w = from1to2.hw(); - return (square(wcr) / FT(wmult((K*)0, RT(wdot(ray1dir, ray1dir, k)), w, w))); + return (square(wcr) / FT(wmult((K*)0, wdot(ray1dir, ray1dir, k), w, w))); } template @@ -58,11 +58,12 @@ squared_distance(const typename K::Ray_2& ray1, typedef typename K::Vector_2 Vector_2; typedef typename K::FT FT; - typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object(); + typename K::Construct_vector_2 vector = k.construct_vector_2_object(); + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); - const Vector_2& ray1dir = ray1.direction().vector(); - const Vector_2& ray2dir = ray2.direction().vector(); - Vector_2 diffvec(construct_vector(ray1.source(),ray2.source())); + const Vector_2 ray1dir = ray1.direction().vector(); + const Vector_2 ray2dir = ray2.direction().vector(); + const Vector_2 diffvec = vector(ray1.source(),ray2.source()); bool crossing1, crossing2; switch(orientation(ray1dir, ray2dir, k)) @@ -83,18 +84,18 @@ squared_distance(const typename K::Ray_2& ray1, { if(crossing2) return FT(0); - return internal::squared_distance(ray2.source(), ray1, k); + return sq_dist(ray2.source(), ray1); } else { if(crossing2) { - return internal::squared_distance(ray1.source(), ray2, k); + return sq_dist(ray1.source(), ray2); } else { - FT min1 = internal::squared_distance(ray1.source(), ray2, k); - FT min2 = internal::squared_distance(ray2.source(), ray1, k); + FT min1 = sq_dist(ray1.source(), ray2); + FT min2 = sq_dist(ray2.source(), ray1); return (min1 < min2) ? min1 : min2; } } @@ -106,7 +107,7 @@ template inline typename K::FT squared_distance(const Ray_2 &ray1, const Ray_2 &ray2) { - return internal::squared_distance(ray1, ray2, K()); + return K().compute_squared_distance_2_object()(ray1, ray2); } } // namespace CGAL diff --git a/Distance_2/include/CGAL/Distance_2/Ray_2_Triangle_2.h b/Distance_2/include/CGAL/Distance_2/Ray_2_Triangle_2.h index f549ce3d880..8c7bbd0be3f 100644 --- a/Distance_2/include/CGAL/Distance_2/Ray_2_Triangle_2.h +++ b/Distance_2/include/CGAL/Distance_2/Ray_2_Triangle_2.h @@ -20,6 +20,7 @@ #define CGAL_DISTANCE_2_RAY_2_TRIANGLE_2_H #include +#include #include #include @@ -64,11 +65,10 @@ squared_distance(const typename K::Ray_2& ray, { // Check if all the segment vertices lie at the same side of // the triangle segment. - const Point_2 &vt1 = triangle.vertex(ind_tr1); - const Point_2 &vt2 = triangle.vertex(ind_tr2); + const Point_2& vt1 = triangle.vertex(ind_tr1); + const Point_2& vt2 = triangle.vertex(ind_tr2); if(clockwise(ray.direction().vector(), vt2-vt1, k)) mindist = FT(0); - } else { @@ -105,7 +105,7 @@ inline typename K::FT squared_distance(const Ray_2& ray, const Triangle_2& triangle) { - return internal::squared_distance(ray, triangle, K()); + return K().compute_squared_distance_2_object()(ray, triangle); } template @@ -113,7 +113,7 @@ inline typename K::FT squared_distance(const Triangle_2& triangle, const Ray_2& ray) { - return internal::squared_distance(ray, triangle, K()); + return K().compute_squared_distance_2_object()(triangle, ray); } } // namespace CGAL diff --git a/Distance_2/include/CGAL/Distance_2/Segment_2_Line_2.h b/Distance_2/include/CGAL/Distance_2/Segment_2_Line_2.h index b5ba324207f..a4d8537b08a 100644 --- a/Distance_2/include/CGAL/Distance_2/Segment_2_Line_2.h +++ b/Distance_2/include/CGAL/Distance_2/Segment_2_Line_2.h @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -56,20 +57,20 @@ squared_distance(const typename K::Segment_2& seg, typedef typename K::Vector_2 Vector_2; typedef typename K::Point_2 Point_2; - typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object(); + typename K::Construct_vector_2 vector = k.construct_vector_2_object(); + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); - const Vector_2 &linedir = line.direction().vector(); - const Point_2 &linepoint = line.point(); - Vector_2 startvec(construct_vector(linepoint, seg.source())); - Vector_2 endvec(construct_vector(linepoint, seg.target())); + const Vector_2 linedir = line.direction().vector(); + const Point_2& linepoint = line.point(); + const Vector_2 startvec = vector(linepoint, seg.source()); + const Vector_2 endvec = vector(linepoint, seg.target()); + + if(seg.source() == seg.target()) + return sq_dist(seg.source(), line); bool crossing1; - RT c1s, c1e; - if(seg.source() == seg.target()) - return internal::squared_distance(seg.source(), line, k); - - c1s = wcross(linedir, startvec, k); - c1e = wcross(linedir, endvec, k); + const RT c1s = wcross(linedir, startvec, k); + const RT c1e = wcross(linedir, endvec, k); if(c1s < RT(0)) { crossing1 = (c1e >= RT(0)); @@ -88,8 +89,7 @@ squared_distance(const typename K::Segment_2& seg, } else { - RT dm; - dm = _distance_measure_sub(c1s, c1e, startvec, endvec); + const RT dm = _distance_measure_sub(c1s, c1e, startvec, endvec); if(dm <= RT(0)) return _sqd_to_line(startvec, c1s, linedir); else @@ -113,7 +113,7 @@ inline typename K::FT squared_distance(const Segment_2& seg, const Line_2& line) { - return internal::squared_distance(seg, line, K()); + return K().compute_squared_distance_2_object()(seg, line); } template @@ -121,7 +121,7 @@ inline typename K::FT squared_distance(const Line_2& line, const Segment_2& seg) { - return internal::squared_distance(seg, line, K()); + return K().compute_squared_distance_2_object()(line, seg); } } // namespace CGAL diff --git a/Distance_2/include/CGAL/Distance_2/Segment_2_Ray_2.h b/Distance_2/include/CGAL/Distance_2/Segment_2_Ray_2.h index 1c5c300648d..0c17e595c01 100644 --- a/Distance_2/include/CGAL/Distance_2/Segment_2_Ray_2.h +++ b/Distance_2/include/CGAL/Distance_2/Segment_2_Ray_2.h @@ -50,48 +50,49 @@ squared_distance_parallel(const typename K::Segment_2& seg, { typedef typename K::Vector_2 Vector_2; - const Vector_2& dir1 = seg.direction().vector(); - const Vector_2& dir2 = ray.direction().vector(); + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + const Vector_2 dir1 = seg.direction().vector(); + const Vector_2 dir2 = ray.direction().vector(); if(same_direction(dir1, dir2, k)) { if(!is_acute_angle(seg.source(), seg.target(), ray.source(), k)) - return internal::squared_distance(seg.target(), ray.source(), k); + return sq_dist(seg.target(), ray.source()); } else { if(!is_acute_angle(seg.target(), seg.source(), ray.source(), k)) - return internal::squared_distance(seg.source(), ray.source(), k); + return sq_dist(seg.source(), ray.source()); } - return internal::squared_distance(ray.source(), seg.supporting_line(), k); + return sq_dist(ray.source(), seg.supporting_line()); } template typename K::FT -squared_distance(const typename K::Segment_2 &seg, - const typename K::Ray_2 &ray, +squared_distance(const typename K::Segment_2& seg, + const typename K::Ray_2& ray, const K& k) { typedef typename K::RT RT; typedef typename K::FT FT; typedef typename K::Vector_2 Vector_2; - typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object(); + typename K::Construct_vector_2 vector = k.construct_vector_2_object(); typename K::Orientation_2 orientation = k.orientation_2_object(); + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); const Vector_2& raydir = ray.direction().vector(); - Vector_2 startvec(construct_vector(ray.source(), seg.source())); - Vector_2 endvec(construct_vector(ray.source(), seg.target())); - - bool crossing1, crossing2; - RT c1s, c1e; + const Vector_2 startvec = vector(ray.source(), seg.source()); + const Vector_2 endvec = vector(ray.source(), seg.target()); if(seg.source() == seg.target()) return internal::squared_distance(seg.source(), ray, k); - c1s = wcross(raydir, startvec, k); - c1e = wcross(raydir, endvec, k); + bool crossing1, crossing2; + const RT c1s = wcross(raydir, startvec, k); + const RT c1e = wcross(raydir, endvec, k); if(c1s < RT(0)) { crossing1 = (c1e >= RT(0)); @@ -114,10 +115,10 @@ squared_distance(const typename K::Segment_2 &seg, switch (orientation(seg.source(), seg.target(), ray.source())) { case LEFT_TURN: - crossing2 = right_turn(construct_vector(seg.source(), seg.target()), raydir, k); + crossing2 = right_turn(vector(seg.source(), seg.target()), raydir, k); break; case RIGHT_TURN: - crossing2 = left_turn(construct_vector(seg.source(), seg.target()), raydir, k); + crossing2 = left_turn(vector(seg.source(), seg.target()), raydir, k); break; default: crossing2 = true; @@ -129,36 +130,34 @@ squared_distance(const typename K::Segment_2 &seg, if(crossing2) return FT(0); - return internal::squared_distance(ray.source(), seg, k); + return sq_dist(ray.source(), seg); } else { if(crossing2) { - RT dm; - dm = _distance_measure_sub(c1s, c1e, startvec, endvec); + const RT dm = _distance_measure_sub(c1s, c1e, startvec, endvec); if(dm < RT(0)) { - return internal::squared_distance(seg.source(), ray, k); + return sq_dist(seg.source(), ray); } else { if(dm > RT(0)) - return internal::squared_distance(seg.target(), ray, k); + return sq_dist(seg.target(), ray); else // parallel, should not happen (no crossing) return internal::squared_distance_parallel(seg, ray, k); } } else { - FT min1, min2; - RT dm = _distance_measure_sub(c1s, c1e, startvec, endvec); + const RT dm = _distance_measure_sub(c1s, c1e, startvec, endvec); if(dm == RT(0)) return internal::squared_distance_parallel(seg, ray, k); - min1 = (dm < RT(0)) ? internal::squared_distance(seg.source(), ray, k) - : internal::squared_distance(seg.target(), ray, k); - min2 = internal::squared_distance(ray.source(), seg, k); + const FT min1 = (dm < RT(0)) ? sq_dist(seg.source(), ray) + : sq_dist(seg.target(), ray); + const FT min2 = sq_dist(ray.source(), seg); return (min1 < min2) ? min1 : min2; } @@ -181,7 +180,7 @@ inline typename K::FT squared_distance(const Segment_2& seg, const Ray_2& ray) { - return internal::squared_distance(seg, ray, K()); + return K().compute_squared_distance_2_object()(seg, ray); } template @@ -189,7 +188,7 @@ inline typename K::FT squared_distance(const Ray_2& ray, const Segment_2& seg) { - return internal::squared_distance(seg, ray, K()); + return K().compute_squared_distance_2_object()(ray, seg); } } // namespace CGAL diff --git a/Distance_2/include/CGAL/Distance_2/Segment_2_Segment_2.h b/Distance_2/include/CGAL/Distance_2/Segment_2_Segment_2.h index 5757e39e637..23e2f07c827 100644 --- a/Distance_2/include/CGAL/Distance_2/Segment_2_Segment_2.h +++ b/Distance_2/include/CGAL/Distance_2/Segment_2_Segment_2.h @@ -40,27 +40,29 @@ squared_distance_parallel(const typename K::Segment_2& seg1, { typedef typename K::Vector_2 Vector_2; - const Vector_2 &dir1 = seg1.direction().vector(); - const Vector_2 &dir2 = seg2.direction().vector(); + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + const Vector_2 dir1 = seg1.direction().vector(); + const Vector_2 dir2 = seg2.direction().vector(); if(same_direction(dir1, dir2, k)) { if(!is_acute_angle(seg1.source(), seg1.target(), seg2.source(), k)) - return internal::squared_distance(seg1.target(), seg2.source(), k); + return sq_dist(seg1.target(), seg2.source()); if(!is_acute_angle(seg1.target(), seg1.source(), seg2.target(), k)) - return internal::squared_distance(seg1.source(), seg2.target(), k); + return sq_dist(seg1.source(), seg2.target()); } else { if(!is_acute_angle(seg1.source(), seg1.target(), seg2.target(), k)) - return internal::squared_distance(seg1.target(), seg2.target(), k); + return sq_dist(seg1.target(), seg2.target()); if(!is_acute_angle(seg1.target(), seg1.source(), seg2.source(), k)) - return internal::squared_distance(seg1.source(), seg2.source(), k); + return sq_dist(seg1.source(), seg2.source()); } - return internal::squared_distance(seg2.source(), seg1.supporting_line(), k); + return sq_dist(seg2.source(), seg1.supporting_line()); } template @@ -84,17 +86,19 @@ squared_distance(const typename K::Segment_2& seg1, typedef typename K::RT RT; typedef typename K::FT FT; - bool crossing1, crossing2; - RT c1s, c1e, c2s, c2e; + typename K::Orientation_2 orientation = k.orientation_2_object(); + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); if(seg1.source() == seg1.target()) - return internal::squared_distance(seg1.source(), seg2, k); + return sq_dist(seg1.source(), seg2); if(seg2.source() == seg2.target()) - return internal::squared_distance(seg2.source(), seg1, k); + return sq_dist(seg2.source(), seg1); - Orientation o1s = orientation(seg2.source(), seg2.target(), seg1.source()); - Orientation o1e = orientation(seg2.source(), seg2.target(), seg1.target()); + const Orientation o1s = orientation(seg2.source(), seg2.target(), seg1.source()); + const Orientation o1e = orientation(seg2.source(), seg2.target(), seg1.target()); + + bool crossing1, crossing2; if(o1s == RIGHT_TURN) { crossing1 = (o1e != RIGHT_TURN); @@ -114,8 +118,8 @@ squared_distance(const typename K::Segment_2& seg1, } } - Orientation o2s = orientation(seg1.source(), seg1.target(), seg2.source()); - Orientation o2e = orientation(seg1.source(), seg1.target(), seg2.target()); + const Orientation o2s = orientation(seg1.source(), seg1.target(), seg2.source()); + const Orientation o2e = orientation(seg1.source(), seg1.target(), seg2.target()); if(o2s == RIGHT_TURN) { crossing2 = (o2e != RIGHT_TURN); @@ -140,19 +144,19 @@ squared_distance(const typename K::Segment_2& seg1, if(crossing2) return (FT)0; - c2s = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.source(), k)); - c2e = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.target(), k)); - Comparison_result dm = CGAL_NTS compare(c2s,c2e); + const RT c2s = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.source(), k)); + const RT c2e = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.target(), k)); + Comparison_result dm = CGAL_NTS compare(c2s, c2e); if(dm == SMALLER) { - return internal::squared_distance(seg2.source(), seg1, k); + return sq_dist(seg2.source(), seg1); } else { if(dm == LARGER) { - return internal::squared_distance(seg2.target(), seg1, k); + return sq_dist(seg2.target(), seg1); } else { @@ -163,42 +167,40 @@ squared_distance(const typename K::Segment_2& seg1, } else { - c1s = CGAL_NTS abs(wcross(seg2.source(), seg2.target(), seg1.source(), k)); - c1e = CGAL_NTS abs(wcross(seg2.source(), seg2.target(), seg1.target(), k)); - Comparison_result dm = CGAL_NTS compare(c1s,c1e); + const RT c1s = CGAL_NTS abs(wcross(seg2.source(), seg2.target(), seg1.source(), k)); + const RT c1e = CGAL_NTS abs(wcross(seg2.source(), seg2.target(), seg1.target(), k)); + Comparison_result dm = CGAL_NTS compare(c1s, c1e); if(crossing2) { if(dm == SMALLER) { - return internal::squared_distance(seg1.source(), seg2, k); + return sq_dist(seg1.source(), seg2); } else { if(dm == LARGER) - return internal::squared_distance(seg1.target(), seg2, k); + return sq_dist(seg1.target(), seg2); else // parallel, should not happen (no crossing) return internal::squared_distance_parallel(seg1, seg2, k); } } else { - FT min1, min2; - if(dm == EQUAL) return internal::squared_distance_parallel(seg1, seg2, k); - min1 = (dm == SMALLER) ? internal::squared_distance(seg1.source(), seg2, k): - internal::squared_distance(seg1.target(), seg2, k); + FT min1 = (dm == SMALLER) ? sq_dist(seg1.source(), seg2): + sq_dist(seg1.target(), seg2); + + const RT c2s = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.source(), k)); + const RT c2e = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.target(), k)); - c2s = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.source(), k)); - c2e = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.target(), k)); dm = CGAL_NTS compare(c2s,c2e); - if(dm == EQUAL) // should not happen. return internal::squared_distance_parallel(seg1, seg2, k); - min2 = (dm == SMALLER) ? internal::squared_distance(seg2.source(), seg1, k): - internal::squared_distance(seg2.target(), seg1, k); + FT min2 = (dm == SMALLER) ? sq_dist(seg2.source(), seg1): + sq_dist(seg2.target(), seg1); return (min1 < min2) ? min1 : min2; } @@ -207,27 +209,28 @@ squared_distance(const typename K::Segment_2& seg1, template typename K::FT -squared_distance(const typename K::Segment_2 &seg1, - const typename K::Segment_2 &seg2, +squared_distance(const typename K::Segment_2& seg1, + const typename K::Segment_2& seg2, const K& k, const Homogeneous_tag&) { typedef typename K::RT RT; typedef typename K::FT FT; - bool crossing1, crossing2; - RT c1s, c1e, c2s, c2e; + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); if(seg1.source() == seg1.target()) - return internal::squared_distance(seg1.source(), seg2, k); + return sq_dist(seg1.source(), seg2); if(seg2.source() == seg2.target()) - return internal::squared_distance(seg2.source(), seg1, k); + return sq_dist(seg2.source(), seg1); - c1s = wcross(seg2.source(), seg2.target(), seg1.source(), k); - c1e = wcross(seg2.source(), seg2.target(), seg1.target(), k); - c2s = wcross(seg1.source(), seg1.target(), seg2.source(), k); - c2e = wcross(seg1.source(), seg1.target(), seg2.target(), k); + const RT c1s = wcross(seg2.source(), seg2.target(), seg1.source(), k); + const RT c1e = wcross(seg2.source(), seg2.target(), seg1.target(), k); + const RT c2s = wcross(seg1.source(), seg1.target(), seg2.source(), k); + const RT c2e = wcross(seg1.source(), seg1.target(), seg2.target(), k); + + bool crossing1, crossing2; if(c1s < RT(0)) { @@ -272,16 +275,15 @@ squared_distance(const typename K::Segment_2 &seg1, if(crossing2) return (FT)0; - RT dm; - dm = _distance_measure_sub(c2s,c2e, seg2.source(), seg2.target()); + const RT dm = _distance_measure_sub(c2s,c2e, seg2.source(), seg2.target()); if(dm < RT(0)) { - return internal::squared_distance(seg2.source(), seg1, k); + return sq_dist(seg2.source(), seg1); } else { if(dm > RT(0)) - return internal::squared_distance(seg2.target(), seg1, k); + return sq_dist(seg2.target(), seg1); else // parallel, should not happen (no crossing) return internal::squared_distance_parallel(seg1, seg2, k); } @@ -290,41 +292,50 @@ squared_distance(const typename K::Segment_2 &seg1, { if(crossing2) { - RT dm = _distance_measure_sub(c1s, c1e,seg1.source(),seg1.target()); + const RT dm = _distance_measure_sub(c1s, c1e,seg1.source(),seg1.target()); if(dm < RT(0)) { - return internal::squared_distance(seg1.source(), seg2, k); + return sq_dist(seg1.source(), seg2); } else { if(dm > RT(0)) - return internal::squared_distance(seg1.target(), seg2, k); + return sq_dist(seg1.target(), seg2); else // parallel, should not happen (no crossing) return internal::squared_distance_parallel(seg1, seg2, k); } } else { - FT min1, min2; RT dm = _distance_measure_sub(c1s, c1e, seg1.source(), seg1.target()); if(dm == RT(0)) return internal::squared_distance_parallel(seg1, seg2, k); - min1 = (dm < RT(0)) ? internal::squared_distance(seg1.source(), seg2, k): - internal::squared_distance(seg1.target(), seg2, k); - dm = _distance_measure_sub(c2s, c2e, seg2.source(), seg2.target()); + FT min1 = (dm < RT(0)) ? sq_dist(seg1.source(), seg2): + sq_dist(seg1.target(), seg2); + dm = _distance_measure_sub(c2s, c2e, seg2.source(), seg2.target()); if(dm == RT(0)) // should not happen. return internal::squared_distance_parallel(seg1, seg2, k); - min2 = (dm < RT(0)) ? internal::squared_distance(seg2.source(), seg1, k): - internal::squared_distance(seg2.target(), seg1, k); + FT min2 = (dm < RT(0)) ? sq_dist(seg2.source(), seg1): + sq_dist(seg2.target(), seg1); return (min1 < min2) ? min1 : min2; } } } +template +inline typename K::FT +squared_distance(const Segment_2& seg1, + const Segment_2& seg2, + const K& k) +{ + typedef typename K::Kernel_tag Tag; + return squared_distance(seg1, seg2, k, Tag()); +} + } // namespace internal template @@ -332,8 +343,7 @@ inline typename K::FT squared_distance(const Segment_2& seg1, const Segment_2& seg2) { - typedef typename K::Kernel_tag Tag; - return internal::squared_distance(seg1, seg2, K(), Tag()); + return K().compute_squared_distance_2_object()(seg1, seg2); } } // namespace CGAL diff --git a/Distance_2/include/CGAL/Distance_2/Segment_2_Triangle_2.h b/Distance_2/include/CGAL/Distance_2/Segment_2_Triangle_2.h index c8234370526..13424998bf8 100644 --- a/Distance_2/include/CGAL/Distance_2/Segment_2_Triangle_2.h +++ b/Distance_2/include/CGAL/Distance_2/Segment_2_Triangle_2.h @@ -20,6 +20,7 @@ #define CGAL_DISTANCE_2_SEGMENT_2_TRIANGLE_2_H #include +#include #include #include @@ -79,7 +80,7 @@ squared_distance(const typename K::Segment_2& seg, // the triangle segment. const Point_2 &vt1 = triangle.vertex(ind_tr1); const Point_2 &vt2 = triangle.vertex(ind_tr2); - Orientation or_s = orientation(vt1, vt2, seg.source()); + const Orientation or_s = orientation(vt1, vt2, seg.source()); if(orientation(vt1, vt2, seg.target()) != or_s) mindist = FT(0); } @@ -87,9 +88,9 @@ squared_distance(const typename K::Segment_2& seg, { // Check if all the triangle vertices lie // at the same side of the segment. - const Point_2 &vt1 = seg.source(); - const Point_2 &vt2 = seg.target(); - Orientation or_s = orientation(vt1, vt2, triangle.vertex(0)); + const Point_2& vt1 = seg.source(); + const Point_2& vt2 = seg.target(); + const Orientation or_s = orientation(vt1, vt2, triangle.vertex(0)); for(i=1; i<3; ++i) { if(orientation(vt1, vt2, triangle.vertex(i)) != or_s) @@ -119,7 +120,7 @@ inline typename K::FT squared_distance(const Segment_2& seg, const Triangle_2& triangle) { - return internal::squared_distance(seg, triangle, K()); + return K().compute_squared_distance_2_object()(seg, triangle); } template @@ -127,7 +128,7 @@ inline typename K::FT squared_distance(const Triangle_2& triangle, const Segment_2& seg) { - return internal::squared_distance(seg, triangle, K()); + return K().compute_squared_distance_2_object()(triangle, seg); } } // namespace CGAL diff --git a/Distance_2/include/CGAL/Distance_2/Triangle_2_Triangle_2.h b/Distance_2/include/CGAL/Distance_2/Triangle_2_Triangle_2.h index 67cb787b215..b308ccff35f 100644 --- a/Distance_2/include/CGAL/Distance_2/Triangle_2_Triangle_2.h +++ b/Distance_2/include/CGAL/Distance_2/Triangle_2_Triangle_2.h @@ -21,6 +21,7 @@ #include #include +#include #include @@ -68,8 +69,7 @@ squared_distance(const typename K::Triangle_2& triangle1, } } - // now check if all vertices are on the right side of the - // separating line. + // now check if all vertices are on the right side of the separating line. if(ind1_2 == -1 && ind2_2 == -1) return mindist; @@ -80,7 +80,7 @@ squared_distance(const typename K::Triangle_2& triangle1, { const Point_2& vt1 = triangle1.vertex(ind1_1); const Point_2& vt2 = triangle1.vertex(ind1_2); - Orientation or_s = orientation(vt1, vt2, triangle2.vertex(0)); + const Orientation or_s = orientation(vt1, vt2, triangle2.vertex(0)); for(int i=1; i<3; ++i) { if(orientation(vt1, vt2, triangle2.vertex(i)) != or_s) @@ -94,7 +94,7 @@ squared_distance(const typename K::Triangle_2& triangle1, { const Point_2& vt1 = triangle2.vertex(ind2_1); const Point_2& vt2 = triangle2.vertex(ind2_2); - Orientation or_s = orientation(vt1, vt2, triangle1.vertex(0)); + const Orientation or_s = orientation(vt1, vt2, triangle1.vertex(0)); for(int i=1; i<3; ++i) { if(orientation(vt1, vt2, triangle1.vertex(i)) != or_s) @@ -115,7 +115,7 @@ inline typename K::FT squared_distance(const Triangle_2& triangle1, const Triangle_2& triangle2) { - return internal::squared_distance(triangle1, triangle2, K()); + return K().compute_squared_distance_2_object()(triangle1, triangle2); } } // namespace CGAL diff --git a/Distance_2/test/Distance_2/test_distance_2.cpp b/Distance_2/test/Distance_2/test_distance_2.cpp index 371086c6185..2736f8fe551 100644 --- a/Distance_2/test/Distance_2/test_distance_2.cpp +++ b/Distance_2/test/Distance_2/test_distance_2.cpp @@ -1,12 +1,12 @@ -// 2D distance tests. - #ifdef NDEBUG #undef NDEBUG //this testsuite requires NDEBUG to be not defined #endif - #include #include +#include +#include +#include #include #include @@ -268,7 +268,8 @@ struct Test { void run() { - std::cout << "2D Distance tests\n"; + std::cout << "-- Kernel: " << typeid(K).name() << std::endl; + P_P(); P_S(); P_R(); @@ -293,8 +294,12 @@ struct Test { int main() { - Test< CGAL::Simple_cartesian >().run(); - Test< CGAL::Simple_homogeneous >().run(); + std::cout << "2D Distance tests\n"; - // TODO : test more kernels. + Test >().run(); + Test >().run(); + + Test >().run(); + Test().run(); + Test().run(); } 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 88a69f727e3..03495be04fa 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 @@ -34,11 +34,11 @@ squared_distance(const typename K::Line_3& line1, typename K::Construct_vector_3 vector = k.construct_vector_3_object(); - Vector_3 dir1, dir2, normal, diff; - dir1 = line1.direction().vector(); - dir2 = line2.direction().vector(); - normal = wcross(dir1, dir2, k); - diff = vector(line1.point(), line2.point()); + const Vector_3 dir1 = line1.direction().vector(); + const Vector_3 dir2 = line2.direction().vector(); + const Vector_3 normal = wcross(dir1, dir2, k); + const Vector_3 diff = vector(line1.point(), line2.point()); + if (is_null(normal, k)) return squared_distance_to_line(dir2, diff, k); @@ -53,7 +53,7 @@ typename K::FT squared_distance(const Line_3& line1, const Line_3& line2) { - return internal::squared_distance(line1, line2, K()); + return K().compute_squared_distance_3_object()(line1, line2); } } // namespace CGAL diff --git a/Distance_3/include/CGAL/Distance_3/Line_3_Plane_3.h b/Distance_3/include/CGAL/Distance_3/Line_3_Plane_3.h index 69bea4dcbe5..6bb4d125c59 100644 --- a/Distance_3/include/CGAL/Distance_3/Line_3_Plane_3.h +++ b/Distance_3/include/CGAL/Distance_3/Line_3_Plane_3.h @@ -18,7 +18,6 @@ #define CGAL_DISTANCE_3_LINE_3_PLANE_3_H #include -#include #include #include @@ -45,8 +44,10 @@ squared_distance(const typename K::Line_3& l, { typedef typename K::FT FT; - if (contains_vector(pl, l.direction().vector(), k)) - return squared_distance(pl, l.point(), k); + typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object(); + + if(contains_vector(pl, l.direction().vector(), k)) + return sq_dist(pl, l.point()); return FT(0); } @@ -68,7 +69,7 @@ typename K::FT squared_distance(const Line_3& line, const Plane_3& plane) { - return internal::squared_distance(line, plane, K()); + return K().compute_squared_distance_3_object()(line, plane); } template @@ -77,7 +78,7 @@ typename K::FT squared_distance(const Plane_3& plane, const Line_3& line) { - return internal::squared_distance(line, plane, K()); + return K().compute_squared_distance_3_object()(plane, line); } } // namespace CGAL diff --git a/Distance_3/include/CGAL/Distance_3/Plane_3_Plane_3.h b/Distance_3/include/CGAL/Distance_3/Plane_3_Plane_3.h index 8feada6266d..d18fb366b7f 100644 --- a/Distance_3/include/CGAL/Distance_3/Plane_3_Plane_3.h +++ b/Distance_3/include/CGAL/Distance_3/Plane_3_Plane_3.h @@ -18,11 +18,28 @@ #define CGAL_DISTANCE_3_PLANE_3_PLANE_3_H #include -#include #include namespace CGAL { +namespace internal { + +template +inline typename K::FT +squared_distance(const typename K::Plane_3& plane1, + const typename K::Plane_3& plane2, + const K& k) +{ + typename K::Construct_orthogonal_vector_3 ortho_vec = k.construct_orthogonal_vector_3_object(); + typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object(); + + if(!is_null(wcross(ortho_vec(plane1), ortho_vec(plane2), k), k)) + return typename K::FT(0); + else + return sq_dist(plane1.point(), plane2); +} + +} // namespace internal template inline @@ -30,13 +47,7 @@ typename K::FT squared_distance(const Plane_3& plane1, const Plane_3& plane2) { - K k; - typename K::Construct_orthogonal_vector_3 ortho_vec = k.construct_orthogonal_vector_3_object(); - - if (!internal::is_null(internal::wcross(ortho_vec(plane1), ortho_vec(plane2), k), k)) - return typename K::FT(0); - else - return internal::squared_distance(plane1.point(), plane2, k); + return K().compute_squared_distance_3_object()(plane1, plane2); } } // namespace CGAL 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 6ac84fc2223..24f7593d51d 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 @@ -33,9 +33,10 @@ squared_distance(const typename K::Point_3& pt, { typedef typename K::Vector_3 Vector_3; - typename K::Construct_vector_3 construct_vector; - Vector_3 dir(line.direction().vector()); - Vector_3 diff = construct_vector(line.point(), pt); + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + const Vector_3 dir(line.direction().vector()); + const Vector_3 diff = vector(line.point(), pt); return internal::squared_distance_to_line(dir, diff, k); } @@ -58,7 +59,7 @@ typename K::FT squared_distance(const Point_3& pt, const Line_3& line) { - return internal::squared_distance(pt, line, K()); + return K().compute_squared_distance_3_object()(pt, line); } template @@ -67,7 +68,7 @@ typename K::FT squared_distance(const Line_3& line, const Point_3& pt) { - return internal::squared_distance(pt, line, K()); + return K().compute_squared_distance_3_object()(line, pt); } } // namespace CGAL 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 6d0da93dfe0..7544a72d963 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 @@ -56,7 +56,7 @@ typename K::FT squared_distance(const Point_3& pt, const Plane_3& plane) { - return internal::squared_distance(pt, plane, K()); + return K().compute_squared_distance_3_object()(pt, plane); } template @@ -65,7 +65,7 @@ typename K::FT squared_distance(const Plane_3& plane, const Point_3& pt) { - return internal::squared_distance(pt, plane, K()); + return K().compute_squared_distance_3_object()(plane, pt); } } // namespace CGAL 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 a3c4ab12dc9..91c8965d26f 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 @@ -33,13 +33,13 @@ squared_distance(const typename K::Point_3& pt, { typedef typename K::Vector_3 Vector_3; - typename K::Construct_vector_3 construct_vector; + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); - Vector_3 diff = construct_vector(ray.source(), pt); - const Vector_3 &dir = ray.direction().vector(); + const Vector_3 diff = vector(ray.source(), pt); + const Vector_3 dir = ray.direction().vector(); if(!is_acute_angle(dir, diff, k)) - return (typename K::FT)(diff*diff); + return diff*diff; return squared_distance_to_line(dir, diff, k); } @@ -61,7 +61,7 @@ typename K::FT squared_distance(const Point_3& pt, const Ray_3& ray) { - return internal::squared_distance(pt, ray, K()); + return K().compute_squared_distance_3_object()(pt, ray); } template @@ -70,7 +70,7 @@ typename K::FT squared_distance(const Ray_3& ray, const Point_3& pt) { - return internal::squared_distance(pt, ray, K()); + return K().compute_squared_distance_3_object()(ray, pt); } } // namespace CGAL 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 a28dd10a33c..34ee169c8e1 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 @@ -37,21 +37,22 @@ squared_distance(const typename K::Point_3& pt, typedef typename K::RT RT; typedef typename K::FT FT; - typename K::Construct_vector_3 construct_vector; + 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(); // assert that the segment is valid (non zero length). - Vector_3 diff = construct_vector(seg.source(), pt); - Vector_3 segvec = construct_vector(seg.source(), seg.target()); + Vector_3 diff = vector(seg.source(), pt); + Vector_3 segvec = vector(seg.source(), seg.target()); RT d = wdot(diff,segvec, k); if(d <= RT(0)) - return FT(diff*diff); + return diff*diff; RT e = wdot(segvec,segvec, k); if((d * segvec.hw()) > (e * diff.hw())) - return squared_distance(pt, seg.target(), k); + return sq_dist(pt, seg.target()); Vector_3 wcr = wcross(segvec, diff, k); - return FT(wcr*wcr)/FT(e * diff.hw() * diff.hw()); + return FT(wcr*wcr) / FT(e * diff.hw() * diff.hw()); } template @@ -65,19 +66,20 @@ squared_distance(const typename K::Point_3& pt, typedef typename K::RT RT; typedef typename K::FT FT; - typename K::Construct_vector_3 construct_vector; + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + typename K::Compute_squared_distance_3 sqd = k.compute_squared_distance_3_object(); // assert that the segment is valid (non zero length). - Vector_3 diff = construct_vector(seg.source(), pt); - Vector_3 segvec = construct_vector(seg.source(), seg.target()); + Vector_3 diff = vector(seg.source(), pt); + Vector_3 segvec = vector(seg.source(), seg.target()); RT d = wdot(diff,segvec, k); if(d <= RT(0)) - return (FT(diff*diff)); + return diff*diff; RT e = wdot(segvec,segvec, k); if(d > e) - return squared_distance(pt, seg.target(), k); + return sqd(pt, seg.target()); Vector_3 wcr = wcross(segvec, diff, k); return FT(wcr*wcr)/e; @@ -113,7 +115,7 @@ typename K::FT squared_distance(const Point_3& pt, const Segment_3& seg) { - return internal::squared_distance(pt, seg, K()); + return K().compute_squared_distance_3_object()(pt, seg); } template @@ -122,7 +124,7 @@ typename K::FT squared_distance(const Segment_3& seg, const Point_3& pt) { - return internal::squared_distance(pt, seg, K()); + return K().compute_squared_distance_3_object()(seg, pt); } } // namespace CGAL diff --git a/Distance_3/include/CGAL/Distance_3/Point_3_Tetrahedron_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Tetrahedron_3.h index c2bedd0aba1..04d148818a3 100644 --- a/Distance_3/include/CGAL/Distance_3/Point_3_Tetrahedron_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Tetrahedron_3.h @@ -132,7 +132,7 @@ typename K::FT squared_distance(const Tetrahedron_3& tet, const Point_3& pt) { - return internal::squared_distance(pt, tet, K()); + return K().compute_squared_distance_3_object()(tet, pt); } template @@ -140,7 +140,7 @@ typename K::FT squared_distance(const Point_3& pt, const Tetrahedron_3& tet) { - return internal::squared_distance(pt, tet, K()); + return K().compute_squared_distance_3_object()(pt, tet); } } // namespace CGAL 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 4231977b22d..8859831c6f0 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 @@ -26,6 +26,7 @@ namespace CGAL { namespace internal { +// returns true iff pt is on the negative side of the plane defined by (ep0, ep1) and normal template inline bool on_left_of_triangle_edge(const typename K::Point_3& pt, @@ -34,16 +35,15 @@ on_left_of_triangle_edge(const typename K::Point_3& pt, const typename K::Point_3& ep1, const K& k) { - // returns true iff pt is on the negative side of the plane defined by (ep0, ep1) and normal + typedef typename K::RT RT; + typedef typename K::Vector_3 Vector_3; typename K::Construct_vector_3 vector = k.construct_vector_3_object(); - typename K::Vector_3 edge = vector(ep0, ep1); - typename K::Vector_3 diff = vector(ep0, pt); - typedef typename K::RT RT; + const Vector_3 edge = vector(ep0, ep1); + const Vector_3 diff = vector(ep0, pt); - const bool result = RT(wdot(wcross(edge, normal, k), diff, k)) <= RT(0); - return result; + return (wdot(wcross(edge, normal, k), diff, k) <= RT(0)); } template @@ -59,6 +59,7 @@ squared_distance_to_triangle(const typename K::Point_3& pt, 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); @@ -74,24 +75,24 @@ squared_distance_to_triangle(const typename K::Point_3& pt, // 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 = internal::squared_distance(pt, segment(t2, t0), k); - typename K::FT d2 = internal::squared_distance(pt, segment(t1, t2), k); - typename K::FT d3 = internal::squared_distance(pt, segment(t0, t1), k); + 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); } const bool b01 = on_left_of_triangle_edge(pt, normal, t0, t1, k); if(!b01) - return internal::squared_distance(pt, segment(t0, t1), k); + return sq_dist(pt, segment(t0, t1)); const bool b12 = on_left_of_triangle_edge(pt, normal, t1, t2, k); if(!b12) - return internal::squared_distance(pt, segment(t1, t2), k); + return sq_dist(pt, segment(t1, t2)); const bool b20 = on_left_of_triangle_edge(pt, normal, t2, t0, k); if(!b20) - return internal::squared_distance(pt, segment(t2, t0), k); + return sq_dist(pt, segment(t2, t0)); // The projection of pt is inside the triangle inside = true; @@ -115,6 +116,15 @@ squared_distance(const typename K::Point_3& pt, unused_inside); } +template +inline typename K::FT +squared_distance(const typename K::Triangle_3& t, + const typename K::Point_3& pt, + const K& k) +{ + return squared_distance(pt, t, k); +} + } // namespace internal template @@ -123,7 +133,7 @@ typename K::FT squared_distance(const Point_3& pt, const Triangle_3& t) { - return internal::squared_distance(pt, t, K()); + return K().compute_squared_distance_3_object()(pt, t); } template @@ -132,7 +142,7 @@ typename K::FT squared_distance(const Triangle_3& t, const Point_3& pt) { - return internal::squared_distance(pt, t, K()); + return K().compute_squared_distance_3_object()(t, pt); } } // namespace CGAL diff --git a/Distance_3/include/CGAL/Distance_3/Point_3_Weighted_point_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Weighted_point_3.h index 5f19203a64b..f5db1c3c46f 100644 --- a/Distance_3/include/CGAL/Distance_3/Point_3_Weighted_point_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Weighted_point_3.h @@ -30,7 +30,7 @@ typename K::FT squared_distance(const Weighted_point_3& wpt, const Point_3& pt) { - return internal::squared_distance(wpt.point(), pt, K()); + return K().compute_squared_distance_3_object()(wpt.point(), pt); } template @@ -39,7 +39,7 @@ typename K::FT squared_distance(const Point_3& pt, const Weighted_point_3& wpt) { - return internal::squared_distance(pt, wpt.point(), K()); + return K().compute_squared_distance_3_object()(pt, wpt.point()); } } // namespace CGAL diff --git a/Distance_3/include/CGAL/Distance_3/Ray_3_Line_3.h b/Distance_3/include/CGAL/Distance_3/Ray_3_Line_3.h index 63b98004ac0..d4b51b59cbe 100644 --- a/Distance_3/include/CGAL/Distance_3/Ray_3_Line_3.h +++ b/Distance_3/include/CGAL/Distance_3/Ray_3_Line_3.h @@ -27,60 +27,65 @@ namespace internal { template typename K::FT -squared_distance(const typename K::Line_3& line, - const typename K::Ray_3& ray, +squared_distance(const typename K::Ray_3& ray, + const typename K::Line_3& line, const K& k) { typedef typename K::Vector_3 Vector_3; typedef typename K::Point_3 Point_3; typedef typename K::RT RT; - typename K::Construct_vector_3 construct_vector; + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); const Point_3& rs = ray.source(); - Vector_3 raydir, linedir, normal; - linedir = line.direction().vector(); - raydir = ray.direction().vector(); - normal = wcross(raydir, linedir, k); + const Vector_3 linedir = line.direction().vector(); + const Vector_3 raydir = ray.direction().vector(); + const Vector_3 normal = wcross(raydir, linedir, k); - Vector_3 rs_min_lp = construct_vector(line.point(), rs); - if (is_null(normal, k)) + const Vector_3 rs_min_lp = vector(line.point(), rs); + if(is_null(normal, k)) return squared_distance_to_line(linedir, rs_min_lp, k); bool crossing; - RT sdm_sr_l; - Vector_3 perpend2l; - perpend2l = wcross(linedir, normal, k); - - sdm_sr_l = wdot(perpend2l, rs_min_lp, k); - if (sdm_sr_l < RT(0)) + const Vector_3 perpend2l = wcross(linedir, normal, k); + const RT sdm_sr_l = wdot(perpend2l, rs_min_lp, k); + if(sdm_sr_l < RT(0)) { - crossing = (RT(wdot(perpend2l, raydir, k)) >= RT(0)); + crossing = (wdot(perpend2l, raydir, k) >= RT(0)); } else { - if (RT(wdot(perpend2l, raydir, k)) <= RT(0)) + if(wdot(perpend2l, raydir, k) <= RT(0)) crossing = true; else crossing = (sdm_sr_l == RT(0)); } - if (crossing) + if(crossing) return squared_distance_to_plane(normal, rs_min_lp, k); else return squared_distance_to_line(linedir, rs_min_lp, k); } +template +typename K::FT +squared_distance(const typename K::Line_3& line, + const typename K::Ray_3& ray, + const K& k) +{ + return squared_distance(ray, line, k); +} + } // namespace internal template inline typename K::FT -squared_distance(const Line_3 &line, - const Ray_3 &ray) +squared_distance(const Line_3& line, + const Ray_3& ray) { - return internal::squared_distance(line, ray, K()); + return K().compute_squared_distance_3_object()(line, ray); } template @@ -89,7 +94,7 @@ typename K::FT squared_distance(const Ray_3& ray, const Line_3& line) { - return internal::squared_distance(line, ray, K()); + return K().compute_squared_distance_3_object()(ray, line); } } // namespace CGAL diff --git a/Distance_3/include/CGAL/Distance_3/Ray_3_Plane_3.h b/Distance_3/include/CGAL/Distance_3/Ray_3_Plane_3.h index c72ee2975ee..bdc9a956146 100644 --- a/Distance_3/include/CGAL/Distance_3/Ray_3_Plane_3.h +++ b/Distance_3/include/CGAL/Distance_3/Ray_3_Plane_3.h @@ -18,10 +18,10 @@ #define CGAL_DISTANCE_3_RAY_3_PLANE_3_H #include +#include #include #include -#include namespace CGAL { namespace internal { @@ -32,32 +32,32 @@ squared_distance(const typename K::Ray_3 &ray, const typename K::Plane_3 &plane, const K& k) { - typedef typename K::Point_3 Point_3; - typedef typename K::Vector_3 Vector_3; typedef typename K::RT RT; typedef typename K::FT FT; + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; - typename K::Construct_vector_3 construct_vector; + typename K::Construct_vector_3 construct_vector = k.construct_vector_3_object(); - const Point_3 &start = ray.start(); - const Point_3 &planepoint = plane.point(); - Vector_3 start_min_pp = construct_vector(planepoint, start); - Vector_3 end_min_pp = ray.direction().vector(); - const Vector_3 &normal = plane.orthogonal_vector(); - RT sdm_rs2pp = wdot(normal, start_min_pp, k); - RT sdm_re2pp = wdot(normal, end_min_pp, k); + const Point_3& start = ray.start(); + const Point_3& planepoint = plane.point(); + const Vector_3 start_min_pp = construct_vector(planepoint, start); + const Vector_3 end_min_pp = ray.direction().vector(); + const Vector_3 normal = plane.orthogonal_vector(); + const RT sdm_rs2pp = wdot(normal, start_min_pp, k); + const RT sdm_re2pp = wdot(normal, end_min_pp, k); switch (CGAL_NTS sign(sdm_rs2pp)) { case -1: - if (sdm_re2pp > RT(0)) + if(sdm_re2pp > RT(0)) return FT(0); return squared_distance_to_plane(normal, start_min_pp, k); case 0: default: return FT(0); case 1: - if (sdm_re2pp < RT(0)) + if(sdm_re2pp < RT(0)) return FT(0); return squared_distance_to_plane(normal, start_min_pp, k); } @@ -80,7 +80,7 @@ typename K::FT squared_distance(const Ray_3& ray, const Plane_3& plane) { - return internal::squared_distance(ray, plane, K()); + return K().compute_squared_distance_3_object()(ray, plane); } template @@ -89,7 +89,7 @@ typename K::FT squared_distance(const Plane_3& plane, const Ray_3& ray) { - return internal::squared_distance(ray, plane, K()); + return K().compute_squared_distance_3_object()(plane, ray); } } // namespace CGAL diff --git a/Distance_3/include/CGAL/Distance_3/Ray_3_Ray_3.h b/Distance_3/include/CGAL/Distance_3/Ray_3_Ray_3.h index 015e9a734c1..8ca1eca308c 100644 --- a/Distance_3/include/CGAL/Distance_3/Ray_3_Ray_3.h +++ b/Distance_3/include/CGAL/Distance_3/Ray_3_Ray_3.h @@ -19,7 +19,7 @@ #include -#include +#include #include namespace CGAL { @@ -32,8 +32,8 @@ ray_ray_squared_distance_parallel(const typename K::Vector_3& ray1dir, const typename K::Vector_3& s1_min_s2, const K& k) { - if (!is_acute_angle(ray2dir, s1_min_s2, k)) - if (!same_direction(ray1dir, ray2dir, k)) + if(!is_acute_angle(ray2dir, s1_min_s2, k)) + if(!same_direction(ray1dir, ray2dir, k)) return typename K::FT(s1_min_s2*s1_min_s2); return squared_distance_to_line(ray1dir, s1_min_s2, k); @@ -45,62 +45,73 @@ squared_distance(const typename K::Ray_3& ray1, const typename K::Ray_3& ray2, const K& k) { - typedef typename K::Vector_3 Vector_3; - typedef typename K::Point_3 Point_3; typedef typename K::RT RT; typedef typename K::FT FT; + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; - typename K::Construct_vector_3 construct_vector; + typename K::Construct_vector_3 construct_vector = k.construct_vector_3_object(); + typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object(); const Point_3& s1 = ray1.source(); const Point_3& s2 = ray2.source(); - Vector_3 dir1, dir2, normal; - dir1 = ray1.direction().vector(); - dir2 = ray2.direction().vector(); - normal = wcross(dir1, dir2, k); - Vector_3 s1_min_s2 = construct_vector(s2, s1); - if (is_null(normal, k)) + const Vector_3 dir1 = ray1.direction().vector(); + const Vector_3 dir2 = ray2.direction().vector(); + const Vector_3 normal = wcross(dir1, dir2, k); + const Vector_3 s1_min_s2 = construct_vector(s2, s1); + + if(is_null(normal, k)) return ray_ray_squared_distance_parallel(dir1, dir2, s1_min_s2, k); bool crossing1, crossing2; - RT sdm_s1_2, sdm_s2_1; - Vector_3 perpend1, perpend2; - perpend1 = wcross(dir1, normal, k); - perpend2 = wcross(dir2, normal, k); - sdm_s1_2 = wdot(perpend2, s1_min_s2, k); - if (sdm_s1_2 < RT(0)) { - crossing1 = (RT(wdot(perpend2, dir1, k)) >= RT(0)); - } else { - if (RT(wdot(perpend2, dir1, k)) <= RT(0)) { + const Vector_3 perpend1 = wcross(dir1, normal, k); + const Vector_3 perpend2 = wcross(dir2, normal, k); + + const RT sdm_s1_2 = wdot(perpend2, s1_min_s2, k); + if(sdm_s1_2 < RT(0)) + { + crossing1 = (wdot(perpend2, dir1, k) >= RT(0)); + } + else + { + if(RT(wdot(perpend2, dir1, k)) <= RT(0)) crossing1 = true; - } else { + else crossing1 = (sdm_s1_2 == RT(0)); - } } - sdm_s2_1 = -RT(wdot(perpend1, s1_min_s2, k)); - if (sdm_s2_1 < RT(0)) { - crossing2 = (RT(wdot(perpend1, dir2, k)) >= RT(0)); - } else { - if (RT(wdot(perpend1, dir2, k)) <= RT(0)) { + const RT sdm_s2_1 = - wdot(perpend1, s1_min_s2, k); + if(sdm_s2_1 < RT(0)) + { + crossing2 = (wdot(perpend1, dir2, k) >= RT(0)); + } + else + { + if(wdot(perpend1, dir2, k) <= RT(0)) crossing2 = true; - } else { + else crossing2 = (sdm_s2_1 == RT(0)); - } } - if (crossing1) { - if (crossing2) + if(crossing1) + { + if(crossing2) return squared_distance_to_plane(normal, s1_min_s2, k); - return squared_distance(ray2.source(), ray1, k); - } else { - if (crossing2) { - return squared_distance(ray1.source(), ray2, k); - } else { + + return sq_dist(s2, ray1); + } + else + { + if(crossing2) + { + return sq_dist(s1, ray2); + } + else + { FT min1, min2; - min1 = squared_distance(ray1.source(), ray2, k); - min2 = squared_distance(ray2.source(), ray1, k); + min1 = sq_dist(s1, ray2); + min2 = sq_dist(s2, ray1); return (min1 < min2) ? min1 : min2; } } @@ -124,7 +135,7 @@ typename K::FT squared_distance(const Ray_3& ray1, const Ray_3& ray2) { - return internal::squared_distance(ray1, ray2, K()); + return K().compute_squared_distance_3_object()(ray1, ray2); } } // namespace CGAL diff --git a/Distance_3/include/CGAL/Distance_3/Segment_3_Line_3.h b/Distance_3/include/CGAL/Distance_3/Segment_3_Line_3.h index a6717e4e853..5781c5ceb74 100644 --- a/Distance_3/include/CGAL/Distance_3/Segment_3_Line_3.h +++ b/Distance_3/include/CGAL/Distance_3/Segment_3_Line_3.h @@ -31,51 +31,50 @@ squared_distance(const typename K::Segment_3& seg, const typename K::Line_3& line, const K& k) { - typedef typename K::Vector_3 Vector_3; - typedef typename K::Point_3 Point_3; typedef typename K::RT RT; + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; 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 Point_3& linepoint = line.point(); const Point_3& start = seg.source(); const Point_3& end = seg.target(); - if (start == end) - return squared_distance(start, line, k); + if(start == end) + return sq_dist(start, line); - Vector_3 linedir = line.direction().vector(); - Vector_3 segdir = seg.direction().vector(); - Vector_3 normal = wcross(segdir, linedir, k); + const Vector_3 linedir = line.direction().vector(); + const Vector_3 segdir = seg.direction().vector(); + const Vector_3 normal = wcross(segdir, linedir, k); - if (is_null(normal, k)) + if(is_null(normal, k)) return squared_distance_to_line(linedir, vector(linepoint,start), k); bool crossing; - RT sdm_ss2l, sdm_se2l; - Vector_3 perpend2line, start_min_lp, end_min_lp; - perpend2line = wcross(linedir, normal, k); - start_min_lp = vector(linepoint, start); - end_min_lp = vector(linepoint, end); - sdm_ss2l = wdot(perpend2line, start_min_lp, k); - sdm_se2l = wdot(perpend2line, end_min_lp, k); - if (sdm_ss2l < RT(0)) { + const Vector_3 perpend2line = wcross(linedir, normal, k); + const Vector_3 start_min_lp = vector(linepoint, start); + const Vector_3 end_min_lp = vector(linepoint, end); + const RT sdm_ss2l = wdot(perpend2line, start_min_lp, k); + const RT sdm_se2l = wdot(perpend2line, end_min_lp, k); + + if(sdm_ss2l < RT(0)) { crossing = (sdm_se2l >= RT(0)); } else { - if (sdm_se2l <= RT(0)) { + if(sdm_se2l <= RT(0)) { crossing = true; } else { crossing = (sdm_ss2l == RT(0)); } } - if (crossing) { + if(crossing) { return squared_distance_to_plane(normal, start_min_lp, k); } else { - RT dm; - dm = distance_measure_sub(sdm_ss2l, sdm_se2l, start_min_lp, end_min_lp, k); - if (dm <= RT(0)) { + const RT dm = distance_measure_sub(sdm_ss2l, sdm_se2l, start_min_lp, end_min_lp, k); + if(dm <= RT(0)) { return squared_distance_to_line(linedir, start_min_lp, k); } else { return squared_distance_to_line(linedir, end_min_lp, k); @@ -100,7 +99,7 @@ typename K::FT squared_distance(const Segment_3& seg, const Line_3& line) { - return internal::squared_distance(seg, line, K()); + return K().compute_squared_distance_3_object()(seg, line); } template @@ -109,7 +108,7 @@ typename K::FT squared_distance(const Line_3& line, const Segment_3& seg) { - return internal::squared_distance(seg, line, K()); + return K().compute_squared_distance_3_object()(line, seg); } } // namespace CGAL diff --git a/Distance_3/include/CGAL/Distance_3/Segment_3_Plane_3.h b/Distance_3/include/CGAL/Distance_3/Segment_3_Plane_3.h index d67c6c3e543..1c8d6799556 100644 --- a/Distance_3/include/CGAL/Distance_3/Segment_3_Plane_3.h +++ b/Distance_3/include/CGAL/Distance_3/Segment_3_Plane_3.h @@ -31,24 +31,27 @@ squared_distance(const typename K::Segment_3 &seg, const typename K::Plane_3 &plane, const K& k) { - typedef typename K::Point_3 Point_3; - typedef typename K::Vector_3 Vector_3; typedef typename K::RT RT; typedef typename K::FT FT; + typedef typename K::Vector_3 Vector_3; + typedef typename K::Point_3 Point_3; - typename K::Construct_vector_3 construct_vector; + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + const Point_3& start = seg.start(); + const Point_3& end = seg.end(); - const Point_3 &start = seg.start(); - const Point_3 &end = seg.end(); if (start == end) return squared_distance(start, plane, k); - const Point_3 &planepoint = plane.point(); - Vector_3 start_min_pp = construct_vector(planepoint, start); - Vector_3 end_min_pp = construct_vector(planepoint, end); - const Vector_3 &normal = plane.orthogonal_vector(); - RT sdm_ss2pp = wdot(normal, start_min_pp, k); - RT sdm_se2pp = wdot(normal, end_min_pp, k); + const Point_3& planepoint = plane.point(); + const Vector_3 start_min_pp = vector(planepoint, start); + const Vector_3 end_min_pp = vector(planepoint, end); + const Vector_3& normal = plane.orthogonal_vector(); + + const RT sdm_ss2pp = wdot(normal, start_min_pp, k); + const RT sdm_se2pp = wdot(normal, end_min_pp, k); + switch (CGAL_NTS sign(sdm_ss2pp)) { case -1: @@ -64,7 +67,7 @@ squared_distance(const typename K::Segment_3 &seg, case 1: if (sdm_se2pp <= RT(0)) return FT(0); - if (sdm_ss2pp * end_min_pp.hw() <= sdm_se2pp * start_min_pp.hw()) + if (sdm_ss2pp * end_min_pp.hw() <= sdm_se2pp * start_min_pp.hw()) return squared_distance_to_plane(normal, start_min_pp, k); else return squared_distance_to_plane(normal, end_min_pp, k); @@ -88,7 +91,7 @@ typename K::FT squared_distance(const Segment_3& seg, const Plane_3& plane) { - return internal::squared_distance(seg, plane, K()); + return K().compute_squared_distance_3_object()(seg, plane); } template @@ -97,7 +100,7 @@ typename K::FT squared_distance(const Plane_3& plane, const Segment_3& seg) { - return internal::squared_distance(seg, plane, K()); + return K().compute_squared_distance_3_object()(plane, seg); } } // namespace CGAL diff --git a/Distance_3/include/CGAL/Distance_3/Segment_3_Ray_3.h b/Distance_3/include/CGAL/Distance_3/Segment_3_Ray_3.h index aa3fb6c1ee7..5943630d76f 100644 --- a/Distance_3/include/CGAL/Distance_3/Segment_3_Ray_3.h +++ b/Distance_3/include/CGAL/Distance_3/Segment_3_Ray_3.h @@ -18,10 +18,6 @@ #define CGAL_DISTANCE_3_SEGMENT_3_RAY_3_H #include -#include -#include -#include -#include #include #include @@ -37,21 +33,23 @@ squared_distance_parallel(const typename K::Segment_3& seg, { typedef typename K::Vector_3 Vector_3; + const Vector_3 dir1 = seg.direction().vector(); + const Vector_3 dir2 = ray.direction().vector(); + bool same_direction; - const Vector_3 &dir1 = seg.direction().vector(); - const Vector_3 &dir2 = ray.direction().vector(); - - if (CGAL_NTS abs(dir1.hx()) > CGAL_NTS abs(dir1.hy())) { + if(CGAL_NTS abs(dir1.hx()) > CGAL_NTS abs(dir1.hy())) same_direction = (CGAL_NTS sign(dir1.hx()) == CGAL_NTS sign(dir2.hx())); - } else { + else same_direction = (CGAL_NTS sign(dir1.hy()) == CGAL_NTS sign(dir2.hy())); - } - if (same_direction) { - if (!is_acute_angle(seg.source(), seg.target(), ray.source(), k)) + if(same_direction) + { + if(!is_acute_angle(seg.source(), seg.target(), ray.source(), k)) return squared_distance(seg.target(), ray.source(), k); - } else { - if (!is_acute_angle(seg.target(), seg.source(), ray.source(), k)) + } + else + { + if(!is_acute_angle(seg.target(), seg.source(), ray.source(), k)) return squared_distance(seg.source(), ray.source(), k); } @@ -64,88 +62,96 @@ squared_distance(const typename K::Segment_3& seg, const typename K::Ray_3& ray, const K& k) { - typedef typename K::Point_3 Point_3; - typedef typename K::Vector_3 Vector_3; typedef typename K::RT RT; typedef typename K::FT FT; + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; - typename K::Construct_vector_3 construct_vector; + 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 Point_3& ss = seg.source(); const Point_3& se = seg.target(); - if (ss == se) - return squared_distance(ss, ray, k); + if(ss == se) + return sq_dist(ss, ray); - Vector_3 raydir, segdir, normal; - raydir = ray.direction().vector(); - segdir = seg.direction().vector(); - normal = wcross(segdir, raydir, k); + const Vector_3 raydir = ray.direction().vector(); + const Vector_3 segdir = seg.direction().vector(); + const Vector_3 normal = wcross(segdir, raydir, k); - if (is_null(normal, k)) + if(is_null(normal, k)) return squared_distance_parallel(seg, ray, k); bool crossing1, crossing2; - RT sdm_ss2r, sdm_se2r, sdm_rs2s, sdm_re2s; - Vector_3 perpend2seg, perpend2ray, ss_min_rs, se_min_rs; - perpend2seg = wcross(segdir, normal, k); - perpend2ray = wcross(raydir, normal, k); - ss_min_rs = construct_vector(ray.source(), ss); - se_min_rs = construct_vector(ray.source(), se); - sdm_ss2r = wdot(perpend2ray, ss_min_rs, k); - sdm_se2r = wdot(perpend2ray, se_min_rs, k); - if (sdm_ss2r < RT(0)) { + const Vector_3 perpend2seg = wcross(segdir, normal, k); + const Vector_3 perpend2ray = wcross(raydir, normal, k); + const Vector_3 ss_min_rs = vector(ray.source(), ss); + const Vector_3 se_min_rs = vector(ray.source(), se); + const RT sdm_ss2r = wdot(perpend2ray, ss_min_rs, k); + const RT sdm_se2r = wdot(perpend2ray, se_min_rs, k); + + if(sdm_ss2r < RT(0)) + { crossing1 = (sdm_se2r >= RT(0)); - } else { - if (sdm_se2r <= RT(0)) { + } + else + { + if(sdm_se2r <= RT(0)) crossing1 = true; - } else { + else crossing1 = (sdm_ss2r == RT(0)); - } } - sdm_rs2s = -RT(wdot(perpend2seg, ss_min_rs, k)); - sdm_re2s = wdot(perpend2seg, raydir, k); - if (sdm_rs2s < RT(0)) { + const RT sdm_rs2s = - wdot(perpend2seg, ss_min_rs, k); + const RT sdm_re2s = wdot(perpend2seg, raydir, k); + if(sdm_rs2s < RT(0)) + { crossing2 = (sdm_re2s >= RT(0)); - } else { - if (sdm_re2s <= RT(0)) { + } else + { + if(sdm_re2s <= RT(0)) crossing2 = true; - } else { + else crossing2 = (sdm_rs2s == RT(0)); - } } - if (crossing1) { - if (crossing2) { + if(crossing1) + { + if(crossing2) return squared_distance_to_plane(normal, ss_min_rs, k); - } - return squared_distance(ray.source(), seg, k); - } else { - if (crossing2) { - RT dm; - dm = distance_measure_sub(sdm_ss2r, sdm_se2r, ss_min_rs, se_min_rs, k); - if (dm < RT(0)) { - return squared_distance(ss, ray, k); - } else { - if (dm > RT(0)) { - return squared_distance(se, ray, k); - } else { + + return sq_dist(ray.source(), seg); + } + else + { + if(crossing2) + { + const RT dm = distance_measure_sub(sdm_ss2r, sdm_se2r, ss_min_rs, se_min_rs, k); + if(dm < RT(0)) + { + return sq_dist(ss, ray); + } + else + { + if(dm > RT(0)) + return sq_dist(se, ray); + else // parallel, should not happen (no crossing) return squared_distance_parallel(seg, ray, k); - } } - } else { - FT min1, min2; - RT dm; - dm = distance_measure_sub(sdm_ss2r, sdm_se2r, ss_min_rs, se_min_rs, k); - if (dm == RT(0)) + } + else + { + const RT dm = distance_measure_sub(sdm_ss2r, sdm_se2r, ss_min_rs, se_min_rs, k); + if(dm == RT(0)) return squared_distance_parallel(seg, ray, k); - min1 = (dm < RT(0)) - ? squared_distance(ss, ray, k) - : squared_distance(se, ray, k); - min2 = squared_distance(ray.source(), seg, k); + + const FT min1 = (dm < RT(0)) ? sq_dist(ss, ray) + : sq_dist(se, ray); + const FT min2 = sq_dist(ray.source(), seg); + return (min1 < min2) ? min1 : min2; } } @@ -168,7 +174,7 @@ typename K::FT squared_distance_parallel(const Segment_3& seg, const Ray_3& ray) { - return internal::squared_distance_parallel(ray,seg, K()); + return internal::squared_distance_parallel(ray, seg, K()); } template @@ -177,7 +183,7 @@ typename K::FT squared_distance(const Segment_3& seg, const Ray_3& ray) { - return internal::squared_distance(seg, ray, K()); + return K().compute_squared_distance_3_object()(seg, ray); } template @@ -186,7 +192,7 @@ typename K::FT squared_distance(const Ray_3& ray, const Segment_3& seg) { - return internal::squared_distance(seg, ray, K()); + return K().compute_squared_distance_3_object()(ray, seg); } } // namespace CGAL 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 8232a7647b7..ad933787204 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 @@ -18,7 +18,6 @@ #define CGAL_DISTANCE_3_SEGMENT_3_SEGMENT_3_H #include -#include #include @@ -49,6 +48,7 @@ squared_distance(const typename K::Segment_3& s1, typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); typename K::Construct_vector_3 cv = k.construct_vector_3_object(); typename K::Compute_scalar_product_3 sp = k.compute_scalar_product_3_object(); + typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object(); Segment_3_Segment_3_Result res; @@ -73,7 +73,7 @@ squared_distance(const typename K::Segment_3& s1, { res.x = 0; res.y = 0; - res.squared_distance = CGAL::squared_distance(p1, p2); + res.squared_distance = sq_dist(p1, p2); return res; } @@ -81,7 +81,7 @@ squared_distance(const typename K::Segment_3& s1, res.x = 0; res.y = boost::algorithm::clamp(f/d, 0, 1); // (f - x*c) / d - res.squared_distance = CGAL::squared_distance(p1, p2 + res.y*v2); + res.squared_distance = sq_dist(p1, p2 + res.y*v2); return res; } @@ -91,7 +91,7 @@ squared_distance(const typename K::Segment_3& s1, res.y = 0; res.x = boost::algorithm::clamp(e/a, 0, 1); // (e + y*c) / a - res.squared_distance = CGAL::squared_distance(p1 + res.x*v1, p2); + res.squared_distance = sq_dist(p1 + res.x*v1, p2); return res; } @@ -128,7 +128,7 @@ squared_distance(const typename K::Segment_3& s1, CGAL_postcondition(FT(0) <= res.x && res.x <= FT(1)); CGAL_postcondition(FT(0) <= res.y && res.y <= FT(1)); - res.squared_distance = CGAL::squared_distance(p1 + res.x*v1, p2 + res.y*v2); + res.squared_distance = sq_dist(p1 + res.x*v1, p2 + res.y*v2); CGAL_postcondition(res.squared_distance >= FT(0)); @@ -148,24 +148,27 @@ squared_distance_parallel(const typename K::Segment_3& seg1, { typedef typename K::Vector_3 Vector_3; - const Vector_3& dir1 = seg1.direction().vector(); - const Vector_3& dir2 = seg2.direction().vector(); + typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object(); + + const Vector_3 dir1 = seg1.direction().vector(); + const Vector_3 dir2 = seg2.direction().vector(); if(same_direction(dir1, dir2, k)) { if(!is_acute_angle(seg1.source(), seg1.target(), seg2.source(), k)) - return squared_distance(seg1.target(), seg2.source(), k); + return sq_dist(seg1.target(), seg2.source(), k); if(!is_acute_angle(seg1.target(), seg1.source(), seg2.target(), k)) - return squared_distance(seg1.source(), seg2.target(), k); + return sq_dist(seg1.source(), seg2.target(), k); } else { if(!is_acute_angle(seg1.source(), seg1.target(), seg2.target(), k)) - return squared_distance(seg1.target(), seg2.target(), k); + return sq_dist(seg1.target(), seg2.target(), k); if(!is_acute_angle(seg1.target(), seg1.source(), seg2.source(), k)) - return squared_distance(seg1.source(), seg2.source(), k); + return sq_dist(seg1.source(), seg2.source(), k); } - return squared_distance(seg2.source(), seg1.supporting_line(), k); + + return sq_dist(seg2.source(), seg1.supporting_line(), k); } template @@ -197,7 +200,7 @@ typename K::FT squared_distance(const Segment_3& seg1, const Segment_3& seg2) { - return internal::squared_distance(seg1, seg2, K()); + return K().compute_squared_distance_3_object()(seg1, seg2); } } // namespace CGAL diff --git a/Distance_3/include/CGAL/Distance_3/Triangle_3_Triangle_3.h b/Distance_3/include/CGAL/Distance_3/Triangle_3_Triangle_3.h index 5454d73d67f..73f4b0eb69c 100644 --- a/Distance_3/include/CGAL/Distance_3/Triangle_3_Triangle_3.h +++ b/Distance_3/include/CGAL/Distance_3/Triangle_3_Triangle_3.h @@ -161,7 +161,7 @@ squared_distance(const typename K::Triangle_3& tr1, typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); // ideally just limits::infinity|max(), but it is not available for exact NTs... - FT global_min_sqd = CGAL::squared_distance(vertex(tr1, 0), vertex(tr2, 0)); + FT global_min_sqd = squared_distance(vertex(tr1, 0), vertex(tr2, 0)); bool are_triangles_known_to_be_disjoint = false; std::pair, bool> ss_res; @@ -221,7 +221,7 @@ typename K::FT squared_distance(const Triangle_3& tr1, const Triangle_3& tr2) { - return internal::squared_distance(tr1, tr2, K()); + return K().compute_squared_distance_3_object()(tr1, tr2); } } // namespace CGAL diff --git a/Distance_3/include/CGAL/Distance_3/Weighted_point_3_Weighted_point_3.h b/Distance_3/include/CGAL/Distance_3/Weighted_point_3_Weighted_point_3.h index bd880062faf..54a41981103 100644 --- a/Distance_3/include/CGAL/Distance_3/Weighted_point_3_Weighted_point_3.h +++ b/Distance_3/include/CGAL/Distance_3/Weighted_point_3_Weighted_point_3.h @@ -17,9 +17,7 @@ #ifndef CGAL_DISTANCE_3_WEIGHTED_POINT_3_WEIGHTED_POINT_3_H #define CGAL_DISTANCE_3_WEIGHTED_POINT_3_WEIGHTED_POINT_3_H -#include - -#include +#include namespace CGAL { @@ -29,7 +27,7 @@ typename K::FT squared_distance(const Weighted_point_3& wpt1, const Weighted_point_3& wpt2) { - return internal::squared_distance(wpt1.point(), wpt2.point(), K()); + return K().compute_squared_distance_3_object()(wpt1.point(), wpt2.point()); } } // namespace CGAL diff --git a/Distance_3/test/Distance_3/test_distance_3.cpp b/Distance_3/test/Distance_3/test_distance_3.cpp index 4354d158286..ff375560b55 100644 --- a/Distance_3/test/Distance_3/test_distance_3.cpp +++ b/Distance_3/test/Distance_3/test_distance_3.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include @@ -252,9 +253,9 @@ private: P p2 = random_point(); P p3 = random_point(); p0 = CGAL::midpoint(p0, p1); - p1 = p0 + 0.1 * (p1 - p0); - p2 = p2 + (p2 - CGAL::ORIGIN) / CGAL::approximate_sqrt(CGAL::square(p2.x()) + CGAL::square(p2.y()) + CGAL::square(p2.z()) + 3); - p3 = p3 + (p3 - CGAL::ORIGIN) * std::cos(1.3); + p1 = p0 + FT(0.1) * V{p1 - p0}; + p2 = p2 + V{p2 - CGAL::ORIGIN} / CGAL::approximate_sqrt(CGAL::square(p2.x()) + CGAL::square(p2.y()) + CGAL::square(p2.z()) + 3); + p3 = p3 + V{p3 - CGAL::ORIGIN} * FT(std::cos(1.3)); // degenerate inputs check_squared_distance(S{p0, p0}, S{p0, p0}, 0); // both degen @@ -273,9 +274,9 @@ private: // collinear segments const double lambda_4 = r.get_double(0, 1); - const P p4 = p2 + lambda_4 * (p3 - p2); + const P p4 = p2 + FT(lambda_4) * V{p3 - p2}; const double lambda_5 = r.get_double(0, 1); - const P p5 = p2 + lambda_5 * (p3 - p2); + const P p5 = p2 + FT(lambda_5) * V{p3 - p2}; // [p2;p3) fully contains [p4;p5] check_squared_distance(S{p2, p3}, S{p4, p5}, 0); @@ -284,8 +285,7 @@ private: check_squared_distance(S{p3, p2}, S{p4, p5}, 0); const double lambda_6 = r.get_double(0, 1); - const P p6 = p3 + lambda_6 * (p3 - p2); - + const P p6 = p3 + FT(lambda_6) * V{p3 - p2}; // [p2;p3] overlaps [p5;p6] check_squared_distance(S{p2, p3}, S{p6, p5}, 0); check_squared_distance(S{p2, p3}, S{p5, p6}, 0); @@ -293,7 +293,7 @@ private: check_squared_distance(S{p3, p2}, S{p6, p5}, 0); const double lambda_7 = r.get_double(1, 2); - const P p7 = p3 + lambda_7 * (p3 - p2); + const P p7 = p3 + FT(lambda_7) * V{p3 - p2}; // [p2;p3] disjoint && left of [p6;p7] check_squared_distance(S{p2, p3}, S{p6, p7}, CGAL::squared_distance(p3, p6)); @@ -303,9 +303,9 @@ private: // Generic collinear const double lambda_8 = r.get_double(-M, M); - const P p8 = p2 + lambda_8 * (p3 - p2); + const P p8 = p2 + FT(lambda_8) * V{p3 - p2}; const double lambda_9 = r.get_double(-M, M); - const P p9 = p2 + lambda_9 * (p3 - p2); + const P p9 = p2 + FT(lambda_9) * V{p3 - p2}; S s89(p8, p9); S s32(p3, p2); @@ -364,7 +364,7 @@ private: FT upper_bound = CGAL::squared_distance(p0, p2); - V p01 = V{p0, p1} / N; + V p01 = V{p0, p1} / FT(N); for(int l=0; l >(r, 1e-5).run(); // Test > >(r, 1e-5).run(); + Test >(r, 0).run(); + const double epick_eps = 10 * std::numeric_limits::epsilon(); Test(r, epick_eps).run(); From a4a00d969d5e1a8f7ab896b93a76aab157071a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 23 Jun 2021 22:30:23 +0200 Subject: [PATCH 23/23] Reapply changes from PR #5680 (merge conflict resolution) Outside of the merge commit for clarity. --- .../include/CGAL/Distance_3/Point_3_Line_3.h | 29 +++-- .../include/CGAL/Distance_3/Point_3_Ray_3.h | 38 ++++++- .../CGAL/Distance_3/Point_3_Segment_3.h | 103 +++++++++--------- .../CGAL/Distance_3/Point_3_Triangle_3.h | 96 +++++++++++++++- .../internal/squared_distance_utils_3.h | 17 +-- 5 files changed, 213 insertions(+), 70 deletions(-) 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 24f7593d51d..0d1527c48a7 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 @@ -12,7 +12,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // -// Author(s) : Geert-Jan Giezeman, Andreas Fabri +// Author(s) : Geert-Jan Giezeman, Andreas Fabri, Mael Rouxel-Labbé #ifndef CGAL_DISTANCE_3_POINT_3_LINE_3_H #define CGAL_DISTANCE_3_POINT_3_LINE_3_H @@ -26,19 +26,34 @@ namespace CGAL { namespace internal { template -typename K::FT -squared_distance(const typename K::Point_3& pt, - const typename K::Line_3& line, - const K& k) +void +squared_distance_RT(const typename K::Point_3 &pt, + const typename K::Line_3 &line, + typename K::RT& num, + typename K::RT& den, + const K& k) { typedef typename K::Vector_3 Vector_3; typename K::Construct_vector_3 vector = k.construct_vector_3_object(); - const Vector_3 dir(line.direction().vector()); + const Vector_3& dir = line.direction().vector(); const Vector_3 diff = vector(line.point(), pt); - return internal::squared_distance_to_line(dir, diff, k); + return internal::squared_distance_to_line_RT(dir, diff, num, den, k); +} + +template +typename K::FT +squared_distance(const typename K::Point_3& pt, + const typename K::Line_3& line, + const K& k) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + RT num, den; + squared_distance_RT(pt, line, num, den, k); + return Rational_traits().make_rational(num, den); } 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 91c8965d26f..7eff899b0eb 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 @@ -12,7 +12,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // -// Author(s) : Geert-Jan Giezeman, Andreas Fabri +// Author(s) : Geert-Jan Giezeman, Andreas Fabri, Mael Rouxel-Labbé #ifndef CGAL_DISTANCE_3_POINT_3_RAY_3_H #define CGAL_DISTANCE_3_POINT_3_RAY_3_H @@ -25,18 +25,52 @@ namespace CGAL { namespace internal { +template +void +squared_distance_RT(const typename K::Point_3 &pt, + const typename K::Ray_3 &ray, + typename K::RT& num, + typename K::RT& den, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + typedef typename K::RT RT; + + 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); + + if(!is_acute_angle(dir, diff, k)) + { + num = wdot(diff, diff, k); + den = wmult((K*)0, RT(1), diff.hw(), diff.hw()); + return; + } + + squared_distance_to_line_RT(dir, diff, num, den, k); +} + template typename K::FT squared_distance(const typename K::Point_3& pt, const typename K::Ray_3& ray, const K& k) { + // This duplicates code from the _RT functions, but it is a slowdown to do something like: + // + // RT num, den; + // squared_distance_RT(pt, ray, num, den, k); + // return Rational_traits().make_rational(num, den); + // + // See https://github.com/CGAL/cgal/pull/5680 + typedef typename K::Vector_3 Vector_3; typename K::Construct_vector_3 vector = k.construct_vector_3_object(); - const Vector_3 diff = vector(ray.source(), pt); const Vector_3 dir = ray.direction().vector(); + const Vector_3 diff = vector(ray.source(), pt); if(!is_acute_angle(dir, diff, k)) return diff*diff; 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 34ee169c8e1..554c0a58d2d 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 @@ -27,74 +27,75 @@ namespace CGAL { namespace internal { template -typename K::FT -squared_distance(const typename K::Point_3& pt, - const typename K::Segment_3& seg, - const K& k, - const Homogeneous_tag&) +void +squared_distance_RT(const typename K::Point_3& pt, + const typename K::Segment_3& seg, + typename K::RT& num, + typename K::RT& den, + const K& k) { - typedef typename K::Vector_3 Vector_3; 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(); - typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object(); // assert that the segment is valid (non zero length). - Vector_3 diff = vector(seg.source(), pt); - Vector_3 segvec = vector(seg.source(), seg.target()); + const Vector_3 diff_s = vector(seg.source(), pt); + const Vector_3 segvec = vector(seg.source(), seg.target()); - RT d = wdot(diff,segvec, k); + const RT d = wdot(diff_s, segvec, k); if(d <= RT(0)) - return diff*diff; - RT e = wdot(segvec,segvec, k); - if((d * segvec.hw()) > (e * diff.hw())) - return sq_dist(pt, seg.target()); + { + // this is squared_distance(pt, seg.source()) + num = wdot(diff_s, diff_s, k); + den = wmult((K*)0, RT(1), diff_s.hw(), diff_s.hw()); + return; + } - Vector_3 wcr = wcross(segvec, diff, k); - return FT(wcr*wcr) / FT(e * diff.hw() * diff.hw()); + const RT e = wdot(segvec, segvec, k); + if(wmult((K*)0, d, segvec.hw()) > wmult((K*)0, e, diff_s.hw())) + { + // this is squared_distance(pt, seg.target()) + const Vector_3 diff_t = vector(seg.target(), pt); + num = wdot(diff_t, diff_t, k); + den = wmult((K*)0, RT(1), diff_t.hw(), diff_t.hw()); + return; + } + + // This is an expanded call to squared_distance_to_line_RT() to avoid recomputing 'e' + const Vector_3 wcr = wcross(segvec, diff_s, k); + num = wdot(wcr, wcr, k); + den = wmult((K*)0, e, diff_s.hw(), diff_s.hw()); } template typename K::FT -squared_distance(const typename K::Point_3& pt, - const typename K::Segment_3& seg, - const K& k, - const Cartesian_tag&) -{ - typedef typename K::Vector_3 Vector_3; - typedef typename K::RT RT; - typedef typename K::FT FT; - - typename K::Construct_vector_3 vector = k.construct_vector_3_object(); - typename K::Compute_squared_distance_3 sqd = k.compute_squared_distance_3_object(); - - // assert that the segment is valid (non zero length). - Vector_3 diff = vector(seg.source(), pt); - Vector_3 segvec = vector(seg.source(), seg.target()); - - RT d = wdot(diff,segvec, k); - if(d <= RT(0)) - return diff*diff; - - RT e = wdot(segvec,segvec, k); - if(d > e) - return sqd(pt, seg.target()); - - Vector_3 wcr = wcross(segvec, diff, k); - return FT(wcr*wcr)/e; -} - -template -inline -typename K::FT squared_distance(const typename K::Point_3& pt, const typename K::Segment_3& seg, const K& k) { - typedef typename K::Kernel_tag Tag; - Tag tag; - return squared_distance(pt, seg, k, tag); + 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()); + + const RT d = wdot(diff, segvec, k); + if(d <= RT(0)) + return (FT(diff*diff)); + + const RT e = wdot(segvec, segvec, k); + if(wmult((K*)0, d, segvec.hw()) > wmult((K*)0, e, diff.hw())) + return squared_distance(pt, seg.target(), k); + + // This is an expanded call to squared_distance_to_line() to avoid recomputing 'e' + const Vector_3 wcr = wcross(segvec, diff, k); + + return FT(wcr*wcr) / wmult((K*)0, e, diff.hw(), diff.hw()); } template 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 8859831c6f0..a6f2e7c8e94 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 @@ -46,6 +46,99 @@ on_left_of_triangle_edge(const typename K::Point_3& pt, return (wdot(wcross(edge, normal, k), diff, k) <= RT(0)); } +template +inline void +squared_distance_to_triangle_RT(const typename K::Point_3& pt, + const typename K::Point_3& t0, + const typename K::Point_3& t1, + const typename K::Point_3& t2, + bool& inside, + typename K::RT& num, + typename K::RT& den, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + typename K::Construct_segment_3 segment = k.construct_segment_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. + squared_distance_RT(pt, segment(t2, t0), num, den, k); + + typename K::RT num2, den2; + squared_distance_RT(pt, segment(t1, t2), num2, den2, k); + if(compare_quotients(num2,den2, num,den) == SMALLER) + { + num = num2; + den = den2; + } + + // Should not be needed since at most 2 edges cover the full triangle in the degenerate case, + // but leaving it for robustness + squared_distance_RT(pt, segment(t0, t1), num2, den2, k); + if(compare_quotients(num2,den2, num,den) == SMALLER) + { + num = num2; + den = den2; + } + + return; + } + + const bool b01 = on_left_of_triangle_edge(pt, normal, t0, t1, k); + if(!b01) + { + squared_distance_RT(pt, segment(t0, t1), num, den, k); + return; + } + + const bool b12 = on_left_of_triangle_edge(pt, normal, t1, t2, k); + if(!b12) + { + squared_distance_RT(pt, segment(t1, t2), num, den, k); + return; + } + + const bool b20 = on_left_of_triangle_edge(pt, normal, t2, t0, k); + if(!b20) + { + squared_distance_RT(pt, segment(t2, t0), num, den, k); + return; + } + + // The projection of pt is inside the triangle + inside = true; + squared_distance_to_plane_RT(normal, vector(t0, pt), num, den, k); +} + +template +void +squared_distance_RT(const typename K::Point_3& pt, + const typename K::Triangle_3& t, + typename K::RT& num, + typename K::RT& den, + const K& k) +{ + typename K::Construct_vertex_3 vertex; + bool inside = false; + squared_distance_to_triangle_RT(pt, + vertex(t, 0), + vertex(t, 1), + vertex(t, 2), + inside, + num, + den, + k); +} + template inline typename K::FT squared_distance_to_triangle(const typename K::Point_3& pt, @@ -74,12 +167,11 @@ squared_distance_to_triangle(const typename K::Point_3& pt, // 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); + return (std::min)((std::min)(d1, d2), d3); } const bool b01 = on_left_of_triangle_edge(pt, normal, t0, t1, k); 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 b9669d86eb7..7dbf82e246e 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 @@ -167,8 +167,8 @@ is_obtuse_angle(const typename K::Point_3 &p, } template void -squared_distance_to_plane_RT(const typename K::Vector_3 & normal, - const typename K::Vector_3 & diff, +squared_distance_to_plane_RT(const typename K::Vector_3& normal, + const typename K::Vector_3& diff, typename K::RT& num, typename K::RT& den, const K& k) @@ -183,8 +183,8 @@ squared_distance_to_plane_RT(const typename K::Vector_3 & normal, template typename K::FT -squared_distance_to_plane(const typename K::Vector_3 & normal, - const typename K::Vector_3 & diff, +squared_distance_to_plane(const typename K::Vector_3& normal, + const typename K::Vector_3& diff, const K& k) { typedef typename K::RT RT; @@ -196,8 +196,8 @@ squared_distance_to_plane(const typename K::Vector_3 & normal, template void -squared_distance_to_line_RT(const typename K::Vector_3 & dir, - const typename K::Vector_3 & diff, +squared_distance_to_line_RT(const typename K::Vector_3& dir, + const typename K::Vector_3& diff, typename K::RT& num, typename K::RT& den, const K& k) @@ -207,10 +207,11 @@ squared_distance_to_line_RT(const typename K::Vector_3 & dir, num = wdot(wcr, wcr, k); den = wmult((K*)0, wdot(dir, dir, k), diff.hw(), diff.hw()); } + template typename K::FT -squared_distance_to_line(const typename K::Vector_3 & dir, - const typename K::Vector_3 & diff, +squared_distance_to_line(const typename K::Vector_3& dir, + const typename K::Vector_3& diff, const K& k) { typedef typename K::RT RT;