Skip to content

Commit

Permalink
enable filtering with exact nt with custom traits
Browse files Browse the repository at this point in the history
  • Loading branch information
sloriot committed Nov 14, 2024
1 parent b3f420e commit 5bb5aa9
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 28 deletions.
6 changes: 3 additions & 3 deletions Frechet_distance/include/CGAL/Frechet_distance.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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.
*
Expand All @@ -83,7 +83,7 @@ std::pair<double,double> approximate_Frechet_distance(const PointRange& polyline
const Traits& traits = Traits())
{
constexpr bool filtered = force_filtering ||
std::is_same_v<typename decltype(Frechet_distance_::internal::toCurve(polyline1, traits))::FT,
std::is_same_v<typename decltype(Frechet_distance_::internal::toCurve<force_filtering>(polyline1, traits))::FT,
Interval_nt<false>>;
Protect_FPU_rounding<filtered> p;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ auto toCurve(const PointRange& point_range, const Traits& traits)

using Filtered_traits = std::pair<Frechet_distance_traits_2<AK>, Frechet_distance_traits_2<EK>>;

return Curve<Filtered_traits, true>(point_range);
return Curve<Filtered_traits, true>(point_range, traits);
}
else if constexpr (Traits::Dimension::value==3)
{
Expand All @@ -70,7 +70,7 @@ auto toCurve(const PointRange& point_range, const Traits& traits)

using Filtered_traits = std::pair<Frechet_distance_traits_3<AK>, Frechet_distance_traits_3<EK>>;

return Curve<Filtered_traits, true>(point_range);
return Curve<Filtered_traits, true>(point_range, traits);
}
else
{
Expand All @@ -91,7 +91,7 @@ auto toCurve(const PointRange& point_range, const Traits& traits)

using Filtered_traits = std::tuple<typename Traits::Point_d, Frechet_distance_traits_2<AK>, Frechet_distance_traits_2<EK>>;

return Curve<Filtered_traits, true>(point_range);
return Curve<Filtered_traits, true>(point_range, traits);
}
else if constexpr (Traits::Dimension::value==3)
{
Expand All @@ -100,7 +100,7 @@ auto toCurve(const PointRange& point_range, const Traits& traits)

using Filtered_traits = std::tuple<typename Traits::Point_d, Frechet_distance_traits_3<AK>, Frechet_distance_traits_3<EK>>;

return Curve<Filtered_traits, true>(point_range);
return Curve<Filtered_traits, true>(point_range, traits);
}
else
{
Expand All @@ -126,7 +126,7 @@ auto toCurve(const PointRange& point_range, const Traits& traits)

using Filtered_traits = std::pair<AT,ET>;

return Curve<Filtered_traits, true>(point_range);
return Curve<Filtered_traits, true>(point_range, traits);
}
else if constexpr (Traits::Dimension::value==3)
{
Expand All @@ -135,7 +135,7 @@ auto toCurve(const PointRange& point_range, const Traits& traits)

using Filtered_traits = std::pair<AT,ET>;

return Curve<Filtered_traits, true>(point_range);
return Curve<Filtered_traits, true>(point_range, traits);
}
else
{
Expand All @@ -156,7 +156,7 @@ auto toCurve(const PointRange& point_range, const Traits& traits)

using Filtered_traits = std::tuple<typename ET::Point_d,AT,ET>;

return Curve<Filtered_traits, true>(point_range);
return Curve<Filtered_traits, true>(point_range, traits, traits);
}
else if constexpr (Traits::Dimension::value==3)
{
Expand All @@ -165,7 +165,7 @@ auto toCurve(const PointRange& point_range, const Traits& traits)

using Filtered_traits = std::tuple<typename ET::Point_d,AT,ET>;

return Curve<Filtered_traits, true>(point_range);
return Curve<Filtered_traits, true>(point_range, traits, traits);
}
else
{
Expand Down
56 changes: 44 additions & 12 deletions Frechet_distance/include/CGAL/Frechet_distance/internal/curve.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,27 @@ class Curve<std::pair<Approximate_traits,Rational_traits>, true>
Curve() = default;


template <class PointRange>
Curve(const PointRange& point_range)
template <class PointRange, class Input_traits>
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<typename PointRange::const_iterator>::value_type;
using K2I = Cartesian_converter< typename Kernel_traits<IPoint>::Kernel,
typename Kernel_traits<Point>::Kernel>;
static constexpr int dim = Approximate_traits::Dimension::value;

this->points.reserve(point_range.size());
K2I convert;
std::array<distance_t, dim> 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;i<dim; ++i)
coords[i]=distance_t(to_interval(*itp++));
if constexpr (dim==2)
this->points.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();
}
Expand All @@ -120,6 +130,10 @@ class Curve<std::pair<Approximate_traits,Rational_traits>, 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
Expand All @@ -141,8 +155,9 @@ class Curve<std::tuple<Input_point, Approximate_traits,Rational_traits>, true>

Curve() = default;

template <class PointRange>
Curve(const PointRange& point_range)
template <class PointRange, class Input_traits>
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());
Expand All @@ -151,9 +166,23 @@ class Curve<std::tuple<Input_point, Approximate_traits,Rational_traits>, true>
{
if constexpr(std::is_same_v<Input_point, Rational_point>)
{
Cartesian_converter<typename Kernel_traits<Input_point>::Kernel,
typename Kernel_traits<typename Approximate_traits::Point_d>::Kernel> convert;
this->points.push_back(convert(p));
static constexpr int dim = Approximate_traits::Dimension::value;

this->points.reserve(point_range.size());
std::array<distance_t, dim> 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;i<dim; ++i)
coords[i]=distance_t(to_interval(*itp++));
if constexpr (dim==2)
this->points.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
{
Expand All @@ -173,6 +202,9 @@ class Curve<std::tuple<Input_point, Approximate_traits,Rational_traits>, true>
return exact(rational_points[i]);
}

const Rational_traits& rational_traits() const { return rational_traits_; }

Rational_traits rational_traits_;
std::vector<Input_point> rational_points;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,19 @@ struct Lambda<Curve<FilteredTraits,true>>
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)));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#include <CGAL/Dimension.h>
#include <CGAL/Bbox_2.h>

template <class FT_>
struct MinimalFrechetTraits {
using Dimension = CGAL::Dimension_tag<2>;
using FT = double;
using FT = FT_;

struct Point_d
{};
Expand Down Expand Up @@ -52,7 +53,19 @@ struct MinimalFrechetTraits {

int main()
{
std::vector<MinimalFrechetTraits::Point_d> curve;
/* bool decision = */ CGAL::is_Frechet_distance_larger<MinimalFrechetTraits>(curve, curve, 0.1);
{
using Traits = MinimalFrechetTraits<double>;
std::vector<Traits::Point_d> curve;
/* bool decision = */ CGAL::is_Frechet_distance_larger<Traits, true>(curve, curve, 0.1);
}

{
using Traits = MinimalFrechetTraits<CGAL::Exact_rational>;
std::vector<Traits::Point_d> curve;
/* bool decision = */ CGAL::is_Frechet_distance_larger<Traits, true>(curve, curve, 0.1);
}



return 0;
}

0 comments on commit 5bb5aa9

Please sign in to comment.