diff --git a/Frechet_distance/include/CGAL/Frechet_distance.h b/Frechet_distance/include/CGAL/Frechet_distance.h index 42d46197ff86..531928cf7713 100644 --- a/Frechet_distance/include/CGAL/Frechet_distance.h +++ b/Frechet_distance/include/CGAL/Frechet_distance.h @@ -35,7 +35,7 @@ namespace CGAL * \param traits the geometric traits object * * \tparam Traits a model of `FrechetDistanceTraits` - * \tparam force_filtering if `true` interval arithmetic will be used as a filter + * \tparam force_filtering if `true` interval arithmetic combined with exact rational will be used internally * \tparam PointRange a model of the concept `RandomAccessContainer` * with `Traits::Point` as value type. */ @@ -69,7 +69,7 @@ bool is_Frechet_distance_larger(const PointRange& polyline1, * \param traits the geometric traits object * * \tparam Traits a model of `FrechetDistanceTraits` - * \tparam force_filtering if `true` interval arithmetic will be used as a filter + * \tparam force_filtering if `true` interval arithmetic combined with exact rational will be used internally * \tparam PointRange a model of the concept `RandomAccessContainer` * with `Traits::Point` as value type. * @@ -83,7 +83,7 @@ std::pair approximate_Frechet_distance(const PointRange& polyline const Traits& traits = Traits()) { constexpr bool filtered = force_filtering || - std::is_same_v(polyline1, traits))::FT, Interval_nt>; Protect_FPU_rounding p; 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 9c4a49b62519..b0847959cac1 100644 --- a/Frechet_distance/include/CGAL/Frechet_distance/internal/Frechet_distance.h +++ b/Frechet_distance/include/CGAL/Frechet_distance/internal/Frechet_distance.h @@ -61,7 +61,7 @@ auto toCurve(const PointRange& point_range, const Traits& traits) using Filtered_traits = std::pair, Frechet_distance_traits_2>; - return Curve(point_range); + return Curve(point_range, traits); } else if constexpr (Traits::Dimension::value==3) { @@ -70,7 +70,7 @@ auto toCurve(const PointRange& point_range, const Traits& traits) using Filtered_traits = std::pair, Frechet_distance_traits_3>; - return Curve(point_range); + return Curve(point_range, traits); } else { @@ -91,7 +91,7 @@ auto toCurve(const PointRange& point_range, const Traits& traits) using Filtered_traits = std::tuple, Frechet_distance_traits_2>; - return Curve(point_range); + return Curve(point_range, traits); } else if constexpr (Traits::Dimension::value==3) { @@ -100,7 +100,7 @@ auto toCurve(const PointRange& point_range, const Traits& traits) using Filtered_traits = std::tuple, Frechet_distance_traits_3>; - return Curve(point_range); + return Curve(point_range, traits); } else { @@ -126,7 +126,7 @@ auto toCurve(const PointRange& point_range, const Traits& traits) using Filtered_traits = std::pair; - return Curve(point_range); + return Curve(point_range, traits); } else if constexpr (Traits::Dimension::value==3) { @@ -135,7 +135,7 @@ auto toCurve(const PointRange& point_range, const Traits& traits) using Filtered_traits = std::pair; - return Curve(point_range); + return Curve(point_range, traits); } else { @@ -156,7 +156,7 @@ auto toCurve(const PointRange& point_range, const Traits& traits) using Filtered_traits = std::tuple; - return Curve(point_range); + return Curve(point_range, traits, traits); } else if constexpr (Traits::Dimension::value==3) { @@ -165,7 +165,7 @@ auto toCurve(const PointRange& point_range, const Traits& traits) using Filtered_traits = std::tuple; - return Curve(point_range); + return Curve(point_range, traits, traits); } else { diff --git a/Frechet_distance/include/CGAL/Frechet_distance/internal/curve.h b/Frechet_distance/include/CGAL/Frechet_distance/internal/curve.h index 5c231835a2df..00262b3482fd 100644 --- a/Frechet_distance/include/CGAL/Frechet_distance/internal/curve.h +++ b/Frechet_distance/include/CGAL/Frechet_distance/internal/curve.h @@ -100,17 +100,27 @@ class Curve, true> Curve() = default; - template - Curve(const PointRange& point_range) + template + Curve(const PointRange& point_range, const Input_traits& in_traits, const Rational_traits& rt = Rational_traits()) + : rational_traits_(rt) { - using IPoint = typename std::iterator_traits::value_type; - using K2I = Cartesian_converter< typename Kernel_traits::Kernel, - typename Kernel_traits::Kernel>; + static constexpr int dim = Approximate_traits::Dimension::value; this->points.reserve(point_range.size()); - K2I convert; + std::array coords; + auto ccci = in_traits.construct_cartesian_const_iterator_d_object(); for (auto const& p : point_range) - this->points.push_back(convert(p)); + { + auto itp = ccci(p); + for (int i=0;ipoints.emplace_back(coords[0], coords[1]); + else if constexpr (dim==3) + this->points.emplace_back(coords[0], coords[1], coords[2]); + else + this->points.emplace_back(coords.begin(), coords.end()); + } this->init(); } @@ -120,6 +130,10 @@ class Curve, true> I2R convert; return convert(this->point(i)); } + + const Rational_traits& rational_traits() const { return rational_traits_; } + + Rational_traits rational_traits_; }; //Exact rational based filtered version @@ -141,8 +155,9 @@ class Curve, true> Curve() = default; - template - Curve(const PointRange& point_range) + template + Curve(const PointRange& point_range, const Input_traits& in_traits, const Rational_traits& rt = Rational_traits()) + : rational_traits_(rt) { this->points.reserve(point_range.size()); rational_points.reserve(point_range.size()); @@ -151,9 +166,23 @@ class Curve, true> { if constexpr(std::is_same_v) { - Cartesian_converter::Kernel, - typename Kernel_traits::Kernel> convert; - this->points.push_back(convert(p)); + static constexpr int dim = Approximate_traits::Dimension::value; + + this->points.reserve(point_range.size()); + std::array coords; + auto ccci = in_traits.construct_cartesian_const_iterator_d_object(); + for (auto const& p : point_range) + { + auto itp = ccci(p); + for (int i=0;ipoints.emplace_back(coords[0], coords[1]); + else if constexpr (dim==3) + this->points.emplace_back(coords[0], coords[1], coords[2]); + else + this->points.emplace_back(coords.begin(), coords.end()); + } } else { @@ -173,6 +202,9 @@ class Curve, true> return exact(rational_points[i]); } + const Rational_traits& rational_traits() const { return rational_traits_; } + + Rational_traits rational_traits_; std::vector rational_points; }; 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 99b267897cfb..89e173c00552 100644 --- a/Frechet_distance/include/CGAL/Frechet_distance/internal/geometry_basics.h +++ b/Frechet_distance/include/CGAL/Frechet_distance/internal/geometry_basics.h @@ -117,13 +117,19 @@ struct Lambda> const typename Curve::Rational_point& ls = curve2->rpoint(line_start); const typename Curve::Rational_point& le = curve2->rpoint(line_start+1); const typename Curve::Rational_point& cc = curve1->rpoint(circle_center); + + auto ccci = curve1->rational_traits().construct_cartesian_const_iterator_d_object(); Rational a, b, c; + + auto it_le=ccci(le), it_ls=ccci(ls), it_cc=ccci(cc); + for (auto i = 0; i < Curve::dimension; ++i) { - Rational start_end_diff = le[i] - ls[i]; + Rational start_end_diff = *it_le - *it_ls; a += CGAL::square(start_end_diff); - Rational start_center_diff = ls[i] - cc[i]; + Rational start_center_diff = *it_ls - *it_cc; b -= start_center_diff * start_end_diff; c += CGAL::square(start_center_diff); + ++it_le; ++it_ls; ++it_cc; } CGAL_assertion(radius.is_point()); c -= CGAL::square(Rational(to_double(radius))); diff --git a/Frechet_distance/test/Frechet_distance/Frechet_distance_minimal_traits_2.cpp b/Frechet_distance/test/Frechet_distance/Frechet_distance_minimal_traits_2.cpp index 910e942bdf38..06e462a73c56 100644 --- a/Frechet_distance/test/Frechet_distance/Frechet_distance_minimal_traits_2.cpp +++ b/Frechet_distance/test/Frechet_distance/Frechet_distance_minimal_traits_2.cpp @@ -1,9 +1,10 @@ #include #include +template struct MinimalFrechetTraits { using Dimension = CGAL::Dimension_tag<2>; - using FT = double; + using FT = FT_; struct Point_d {}; @@ -52,7 +53,19 @@ struct MinimalFrechetTraits { int main() { - std::vector curve; - /* bool decision = */ CGAL::is_Frechet_distance_larger(curve, curve, 0.1); + { + using Traits = MinimalFrechetTraits; + std::vector curve; + /* bool decision = */ CGAL::is_Frechet_distance_larger(curve, curve, 0.1); + } + + { + using Traits = MinimalFrechetTraits; + std::vector curve; + /* bool decision = */ CGAL::is_Frechet_distance_larger(curve, curve, 0.1); + } + + + return 0; }