diff --git a/Frechet_distance/include/CGAL/Frechet_distance/internal/Frechet_distance.h b/Frechet_distance/include/CGAL/Frechet_distance/internal/Frechet_distance.h index 8e135966b24e..af12e2e645fc 100644 --- a/Frechet_distance/include/CGAL/Frechet_distance/internal/Frechet_distance.h +++ b/Frechet_distance/include/CGAL/Frechet_distance/internal/Frechet_distance.h @@ -19,25 +19,39 @@ #include #include #include +#include #include #include #include +#include +// #include +#include +#include namespace CGAL { namespace Frechet_distance_ { namespace internal { +template ::value> +struct Is_filtered_kernel +{ + static constexpr bool value = K::Has_filtered_predicates_tag::value; +}; + +template +struct Is_filtered_kernel +{ + static constexpr bool value = false; +}; + template auto toCurve(const PointRange& point_range, const Traits& traits) { using IPoint = typename Traits::Point_d; - constexpr bool is_from_cgal_kernel = - !std::is_same_v::Kernel, internal_kernel_traits::Dummy_kernel>; - if constexpr (is_from_cgal_kernel) + if constexpr (Is_filtered_kernel::Kernel>::value) { - if constexpr (std::is_floating_point::type::value && - Kernel_traits::Kernel::Has_filtered_predicates_tag::value) + if constexpr (std::is_floating_point::type::value) { if constexpr (Traits::Dimension::value==2) { @@ -58,20 +72,45 @@ auto toCurve(const PointRange& point_range, const Traits& traits) return Curve(point_range); } else + { + // using AK = Kernel_d_interface>>; + // using EK = typename CGAL::Frechet_distance_::internal::Get_exact_kernel::type; + // using Filtered_traits = std::pair, Frechet_distance_traits_d>; + + // return Curve(point_range); return Curve(point_range, traits); -/* - else + } + } + else + { + if constexpr (Traits::Dimension::value==2) { - using AK = Kernel_d_interface>>; - using EK = typename CGAL::Frechet_distance_::internal::Get_exact_kernel::type; - using Filtered_traits = std::pair, Frechet_distance_traits_3>; + using AK = CGAL::Simple_cartesian; + using EK = typename Kernel_traits::Kernel::Exact_kernel; + + using Filtered_traits = std::tuple, Frechet_distance_traits_2>; + + return Curve(point_range); + } + else if constexpr (Traits::Dimension::value==3) + { + using AK = CGAL::Simple_cartesian; + using EK = typename Kernel_traits::Kernel::Exact_kernel; + + using Filtered_traits = std::tuple, Frechet_distance_traits_3>; return Curve(point_range); } -*/ + else + { + // using AK = Kernel_d_interface>>; + // using EK = typename CGAL::Frechet_distance_::internal::Get_exact_kernel::type; + // using Filtered_traits = std::pair, Frechet_distance_traits_d>; + + // return Curve(point_range); + return Curve(point_range, traits); + } } - else - return Curve(point_range, traits); } else return Curve(point_range, traits); diff --git a/Frechet_distance/include/CGAL/Frechet_distance/internal/curve.h b/Frechet_distance/include/CGAL/Frechet_distance/internal/curve.h index 04d04c0cd1a4..77d56593369e 100644 --- a/Frechet_distance/include/CGAL/Frechet_distance/internal/curve.h +++ b/Frechet_distance/include/CGAL/Frechet_distance/internal/curve.h @@ -58,8 +58,6 @@ double length_of_diagonal(const Bbox,T>& bb) return sqrt(d).sup(); } -// TODO: Clean up Curve + factorize filtered vs non-filtered version with a base class - /*! * \ingroup PkgFrechetDistanceFunctions * A class representing a trajectory. Additionally to the points given in the @@ -68,7 +66,18 @@ double length_of_diagonal(const Bbox,T>& bb) template class Curve; -//filtered version +/* + K Has_filtered_predicates is_floating_point(K::FT) store input + Epick Y Y N as we can do to_double of interval + Epeck Y N Y as we later need exact + SC N Y N as we can do to_double of interval + SC N N Y as we later need exact + SC N N Y to simplify life + SC N N Y as we later need exact + == Epeck_with_sqrt +*/ + +//floating-point based filtered version template class Curve, true> : public Curve @@ -82,22 +91,16 @@ class Curve, true> using Rational = typename Rational_traits::FT; using Rational_point = typename Rational_traits::Point_d; + using AT = Approximate_traits; + using ET = Rational_traits; + // TODO: this assumes that input interval are all tight --> need a PM! using I2R = Cartesian_converter< typename Kernel_traits::Kernel, typename Kernel_traits::Kernel, NT_converter>; Curve() = default; -/* - K Has_filtered_predicates is_floating_point(K::FT) store input - Epick Y Y N as we can do to_double of interval - Epeck Y N Y as we later need exact - SC N Y N as we can do to_double of interval - SC N N Y as we later need exact - SC N N Y to simplify life - SC N N Y as we later need exact - == Epeck_with_sqrt -*/ + template Curve(const PointRange& point_range) { @@ -105,14 +108,6 @@ class Curve, true> using K2I = Cartesian_converter< typename Kernel_traits::Kernel, typename Kernel_traits::Kernel>; - //TODO: not working for now with EPECK or SC - //~ if constexpr ( ! is_floating_point) { - //~ input.reserve(point_range.size()); - //~ for (auto const& p : point_range) { - //~ input.push_back(p); - //~ } - //~ } - this->points.reserve(point_range.size()); K2I convert; for (auto const& p : point_range) @@ -123,19 +118,53 @@ class Curve, true> Rational_point rpoint(PointID const& i) const { - //~ if constexpr (is_floating_point) { - I2R convert; - return convert(this->point(i)); - //~ }else{ - //~ if constexpr (is_filtered) { - //~ return typename K::C2E()(input[i]); - //~ }else{ - //~ return input[i]; - //~ } - //~ } - //~ CGAL_assertion(false); - //~ return Rational_point(); + I2R convert; + return convert(this->point(i)); + } +}; + +//Exact rational based filtered version +template +class Curve, true> + : public Curve +{ +public: + using Base = Curve; + using distance_t = typename Approximate_traits::FT; + using Point = typename Approximate_traits::Point_d; + using PointID = typename Base::PointID; + + using Rational = typename Rational_traits::FT; + using Rational_point = typename Rational_traits::Point_d; + + using AT = Approximate_traits; + using ET = Rational_traits; + + Curve() = default; + + template + Curve(const PointRange& point_range) + { + using IPoint = typename std::iterator_traits::value_type; + + this->points.reserve(point_range.size()); + rational_points.reserve(point_range.size()); + + typename Kernel_traits::Kernel::C2F convert; + for (auto const& p : point_range) + { + this->points.push_back(convert(p)); + rational_points.push_back(p); + } + this->init(); + } + + Rational_point rpoint(PointID const& i) const + { + return exact(rational_points[i]); } + + std::vector rational_points; }; template diff --git a/Frechet_distance/include/CGAL/Frechet_distance/internal/geometry_basics.h b/Frechet_distance/include/CGAL/Frechet_distance/internal/geometry_basics.h index 8465b1892cca..99b267897cfb 100644 --- a/Frechet_distance/include/CGAL/Frechet_distance/internal/geometry_basics.h +++ b/Frechet_distance/include/CGAL/Frechet_distance/internal/geometry_basics.h @@ -53,7 +53,7 @@ struct Lambda> using Approx = distance_t; using PointID = typename C::PointID; using Rational = typename Curve::Rational; - using Exact = CGAL::Sqrt_extension; + using Exact = typename Root_of_traits::Root_of_2; mutable Approx approx; mutable std::optional exact; @@ -128,11 +128,12 @@ struct Lambda> CGAL_assertion(radius.is_point()); c -= CGAL::square(Rational(to_double(radius))); + CGAL_assertion(a!=0); Rational minus_b_div_a = b / a; Rational d = CGAL::square(minus_b_div_a) - c / a; if (! is_negative(d)) { if (is_start) { - Exact start(minus_b_div_a, -1, d); + Exact start = make_root_of_2(minus_b_div_a, -1, d); if (is_negative(start)) start = Exact(0); if (start <= Exact(1)) { exact = std::make_optional(start); @@ -141,7 +142,7 @@ struct Lambda> return true; } } else { - Exact end(minus_b_div_a, 1, d); + Exact end = make_root_of_2(minus_b_div_a, 1, d); if (end > Exact(1)) end = Exact(1); if (! is_negative(end)) { exact = std::make_optional(end); diff --git a/Frechet_distance/include/CGAL/Frechet_distance/internal/high_level_predicates.h b/Frechet_distance/include/CGAL/Frechet_distance/internal/high_level_predicates.h index e7aa5485d09e..88b701a2e2ac 100644 --- a/Frechet_distance/include/CGAL/Frechet_distance/internal/high_level_predicates.h +++ b/Frechet_distance/include/CGAL/Frechet_distance/internal/high_level_predicates.h @@ -90,7 +90,7 @@ fill_lambda(const Point& circle_center, make_positive(start); make_less_than_one(end); - auto valid_interval = start <= FT(1) && end >= FT(0); + auto valid_interval = CGAL_AND(start <= FT(1), end >= FT(0)); if (!is_certain(valid_interval)) return std::nullopt; if (valid_interval) @@ -127,7 +127,7 @@ intersection_interval(Curve const& curve1, // if not empty std::optional res = - fill_lambda( + fill_lambda( curve1[center_id], curve2[seg_start_id], curve2[seg_start_id + 1], C::inf(radius), II, curve1, center_id, curve2, seg_start_id); @@ -140,7 +140,7 @@ intersection_interval(Curve const& curve1, CGAL_assertion(radius.is_point()); std::pair, Lambda> II; // if not empty - if (fill_lambda( + if (fill_lambda( curve1.rpoint(center_id), curve2.rpoint(seg_start_id), curve2.rpoint(seg_start_id + 1), C::inf(radius), II, curve1, center_id, curve2, seg_start_id).value()) { diff --git a/Frechet_distance/include/CGAL/Frechet_distance_traits_2.h b/Frechet_distance/include/CGAL/Frechet_distance_traits_2.h index 261a35212b4b..f5c3d29bcef4 100644 --- a/Frechet_distance/include/CGAL/Frechet_distance_traits_2.h +++ b/Frechet_distance/include/CGAL/Frechet_distance_traits_2.h @@ -17,15 +17,6 @@ #define CGAL_Frechet_distance_TRAITS_2_H #include -#include -#include -#include -#include -#include -#include - -// TODO: is it too restrictive to use vectors by default? -#include namespace CGAL { @@ -44,15 +35,10 @@ class Frechet_distance_traits_2 using Kernel = GT; using FT = typename Kernel::FT; using Point_d = typename Kernel::Point_2; - using Compute_squared_distance_d = typename Kernel::Compute_squared_distance_2; using Construct_bbox_d = typename Kernel::Construct_bbox_2; using Cartesian_const_iterator_d = typename Kernel::Cartesian_const_iterator_2; using Construct_cartesian_const_iterator_d = typename Kernel::Construct_cartesian_const_iterator_2; - Compute_squared_distance_d compute_squared_distance_d_object() const { - return Construct_cartesian_const_iterator_d(); - } - Construct_bbox_d construct_bbox_d_object() const { return Construct_bbox_d(); } @@ -60,26 +46,6 @@ class Frechet_distance_traits_2 Construct_cartesian_const_iterator_d construct_cartesian_const_iterator_d_object() const { return Construct_cartesian_const_iterator_d(); } - - -/* - static constexpr bool is_filtered = CGAL::Frechet_distance_::internal::Get_exact_kernel::is_filtered; - static constexpr bool is_floating_point = CGAL::Frechet_distance_::internal::Get_exact_kernel::is_floating_point; - - using distance_t = CGAL::Interval_nt; - using Approximate_kernel = CGAL::Simple_cartesian; - using Approximate_point = typename Approximate_kernel::Point_2; - - - using Exact_kernel = typename CGAL::Frechet_distance_::internal::Get_exact_kernel::type; - using Exact_point = typename Exact_kernel::Point_2; - - using D2D = NT_converter; - using A2E = Cartesian_converter; - - using FT2I = NT_converter; - using K2A = Cartesian_converter; -*/ }; } // end of namespace CGAL diff --git a/Frechet_distance/include/CGAL/Frechet_distance_traits_3.h b/Frechet_distance/include/CGAL/Frechet_distance_traits_3.h index 19f62a242c3d..111c1a2a4830 100644 --- a/Frechet_distance/include/CGAL/Frechet_distance_traits_3.h +++ b/Frechet_distance/include/CGAL/Frechet_distance_traits_3.h @@ -17,15 +17,6 @@ #define CGAL_Frechet_distance_TRAITS_3_H #include -#include -#include -#include -#include -#include -#include - -// TODO: is it too restrictive to use vectors by default? -#include namespace CGAL { @@ -44,14 +35,9 @@ class Frechet_distance_traits_3 using Kernel = GT; using FT = typename Kernel::FT; using Point_d = typename Kernel::Point_3; - using Compute_squared_distance_d = typename Kernel::Compute_squared_distance_3; using Construct_bbox_d = typename Kernel::Construct_bbox_3; using Cartesian_const_iterator_d = typename Kernel::Cartesian_const_iterator_2; - using Construct_cartesian_const_iterator_d = typename Kernel::Construct_cartesian_const_iterator_2; - - Compute_squared_distance_d compute_squared_distance_d_object() const { - return Construct_cartesian_const_iterator_d(); - } + using Construct_cartesian_const_iterator_d = typename Kernel::Construct_cartesian_const_iterator_3; Construct_bbox_d construct_bbox_d_object() const { return Construct_bbox_d(); @@ -60,26 +46,6 @@ class Frechet_distance_traits_3 Construct_cartesian_const_iterator_d construct_cartesian_const_iterator_d_object() const { return Construct_cartesian_const_iterator_d(); } - - -/* - static constexpr bool is_filtered = CGAL::Frechet_distance_::internal::Get_exact_kernel::is_filtered; - static constexpr bool is_floating_point = CGAL::Frechet_distance_::internal::Get_exact_kernel::is_floating_point; - - using distance_t = CGAL::Interval_nt; - using Approximate_kernel = CGAL::Simple_cartesian; - using Approximate_point = typename Approximate_kernel::Point_3; - - - using Exact_kernel = typename CGAL::Frechet_distance_::internal::Get_exact_kernel::type; - using Exact_point = typename Exact_kernel::Point_3; - - using D2D = NT_converter; - using A2E = Cartesian_converter; - - using FT2I = NT_converter; - using K2A = Cartesian_converter; -*/ }; } // end of namespace CGAL diff --git a/Frechet_distance/include/CGAL/Frechet_distance_traits_d.h b/Frechet_distance/include/CGAL/Frechet_distance_traits_d.h index 4d671ad47442..467f214d3318 100644 --- a/Frechet_distance/include/CGAL/Frechet_distance_traits_d.h +++ b/Frechet_distance/include/CGAL/Frechet_distance_traits_d.h @@ -17,9 +17,6 @@ #define CGAL_Frechet_distance_TRAITS_D_H #include -#include -#include -#include namespace CGAL { @@ -38,15 +35,10 @@ class Frechet_distance_traits_d using Kernel = GT; using FT = typename Kernel::FT; using Point_d = typename Kernel::Point_d; - using Compute_squared_distance_d = typename Kernel::Squared_distance_d; using Construct_bbox_d = typename Kernel::Construct_bbox_d; using Cartesian_const_iterator_d = typename Kernel::Cartesian_const_iterator_d; using Construct_cartesian_const_iterator_d = typename Kernel::Construct_cartesian_const_iterator_d; - Compute_squared_distance_d compute_squared_distance_d_object() const { - return Construct_cartesian_const_iterator_d(); - } - Construct_bbox_d construct_bbox_d_object() const { return Construct_bbox_d(); } diff --git a/Frechet_distance/test/Frechet_distance/Frechet_distance_test.cpp b/Frechet_distance/test/Frechet_distance/Frechet_distance_test.cpp index bc9e2dddc1b3..d260dba8d403 100644 --- a/Frechet_distance/test/Frechet_distance/Frechet_distance_test.cpp +++ b/Frechet_distance/test/Frechet_distance/Frechet_distance_test.cpp @@ -226,43 +226,43 @@ int main(int argc, char** argv) if (test_set.empty() || test_set.count(0)) { using SCD = CGAL::Simple_cartesian; + std::cout <<"Simple_cartesian\n"; double t1=Test_struct::testFrechetDistanceNearNeighborsDS(); double t2=Test_struct::testFrechetDistance(); - std::cout <<"Simple_cartesian\n"; std::cout << t1 << " " << t2 << "\n"; } if (test_set.empty() || test_set.count(1)) { + std::cout <<"CGAL::Epick\n"; double t1=Test_struct::testFrechetDistanceNearNeighborsDS(); double t2=Test_struct::testFrechetDistance(); - std::cout <<"CGAL::Epick\n"; std::cout << t1 << " " << t2 << "\n"; } if (test_set.empty() || test_set.count(2)) { + std::cout <<"CGAL::Epeck\n"; double t1=Test_struct::testFrechetDistanceNearNeighborsDS(); double t2=Test_struct::testFrechetDistance(); - std::cout <<"CGAL::Epeck\n"; std::cout << t1 << " " << t2 << "\n"; } if (test_set.empty() || test_set.count(3)) { using Epeck_sqrt = CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt; + std::cout <<"Exact_predicates_exact_constructions_kernel_with_sqrt\n"; double t1=Test_struct::testFrechetDistanceNearNeighborsDS(); double t2=Test_struct::testFrechetDistance(); - std::cout <<"Exact_predicates_exact_constructions_kernel_with_sqrt\n"; std::cout << t1 << " " << t2 << "\n"; } if (test_set.empty() || test_set.count(4)) { using SCE = CGAL::Simple_cartesian; + std::cout <<"Simple_cartesian\n"; double t1=Test_struct::testFrechetDistanceNearNeighborsDS(); double t2=Test_struct::testFrechetDistance(); - std::cout <<"Simple_cartesian\n"; std::cout << t1 << " " << t2 << "\n"; }