Skip to content

Commit

Permalink
add filtering for EPECK too
Browse files Browse the repository at this point in the history
  • Loading branch information
sloriot committed Nov 14, 2024
1 parent e1f5a1b commit c2d7402
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 134 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,39 @@
#include <CGAL/Frechet_distance/internal/curve.h>
#include <CGAL/Frechet_distance/internal/frechet_light.h>
#include <CGAL/Frechet_distance/internal/geometry_basics.h>
#include <CGAL/STL_Extension/internal/Has_nested_type_Has_filtered_predicates_tag.h>
#include <CGAL/Frechet_distance_traits_2.h>
#include <CGAL/Frechet_distance_traits_3.h>
#include <CGAL/Frechet_distance_traits_d.h>
#include <CGAL/Simple_cartesian.h>
// #include <CGAL/Epick_d.h>
#include <CGAL/Exact_rational.h>
#include <CGAL/Interval_nt.h>

namespace CGAL {
namespace Frechet_distance_ {
namespace internal {

template <class K, bool hfp = ::CGAL::internal::Has_nested_type_Has_filtered_predicates_tag<K>::value>
struct Is_filtered_kernel
{
static constexpr bool value = K::Has_filtered_predicates_tag::value;
};

template <class K>
struct Is_filtered_kernel<K,false>
{
static constexpr bool value = false;
};

template <class PointRange, class Traits>
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<typename Kernel_traits<IPoint>::Kernel, internal_kernel_traits::Dummy_kernel<IPoint>>;

if constexpr (is_from_cgal_kernel)
if constexpr (Is_filtered_kernel<typename Kernel_traits<IPoint>::Kernel>::value)
{
if constexpr (std::is_floating_point<typename Traits::FT>::type::value &&
Kernel_traits<IPoint>::Kernel::Has_filtered_predicates_tag::value)
if constexpr (std::is_floating_point<typename Traits::FT>::type::value)
{
if constexpr (Traits::Dimension::value==2)
{
Expand All @@ -58,20 +72,45 @@ auto toCurve(const PointRange& point_range, const Traits& traits)
return Curve<Filtered_traits, true>(point_range);
}
else
{
// using AK = Kernel_d_interface<Cartesian_base_d<distance_t,Dimension_tag<dimension>>>;
// using EK = typename CGAL::Frechet_distance_::internal::Get_exact_kernel<Kernel>::type;
// using Filtered_traits = std::pair<Frechet_distance_traits_d<AK>, Frechet_distance_traits_d<EK>>;

// return Curve<Filtered_traits, true>(point_range);
return Curve<Traits, false>(point_range, traits);
/*
else
}
}
else
{
if constexpr (Traits::Dimension::value==2)
{
using AK = Kernel_d_interface<Cartesian_base_d<distance_t,Dimension_tag<dimension>>>;
using EK = typename CGAL::Frechet_distance_::internal::Get_exact_kernel<Kernel>::type;
using Filtered_traits = std::pair<Frechet_distance_traits_3<AK>, Frechet_distance_traits_3<EK>>;
using AK = CGAL::Simple_cartesian<Interval_nt_advanced>;
using EK = typename Kernel_traits<typename Traits::Point_d>::Kernel::Exact_kernel;

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);
}
else if constexpr (Traits::Dimension::value==3)
{
using AK = CGAL::Simple_cartesian<Interval_nt_advanced>;
using EK = typename Kernel_traits<typename Traits::Point_d>::Kernel::Exact_kernel;

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);
}
*/
else
{
// using AK = Kernel_d_interface<Cartesian_base_d<distance_t,Dimension_tag<dimension>>>;
// using EK = typename CGAL::Frechet_distance_::internal::Get_exact_kernel<Kernel>::type;
// using Filtered_traits = std::pair<Frechet_distance_traits_d<AK>, Frechet_distance_traits_d<EK>>;

// return Curve<Filtered_traits, true>(point_range);
return Curve<Traits, false>(point_range, traits);
}
}
else
return Curve<Traits, false>(point_range, traits);
}
else
return Curve<Traits, false>(point_range, traits);
Expand Down
95 changes: 62 additions & 33 deletions Frechet_distance/include/CGAL/Frechet_distance/internal/curve.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ double length_of_diagonal(const Bbox<Dimension_tag<N>,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
Expand All @@ -68,7 +66,18 @@ double length_of_diagonal(const Bbox<Dimension_tag<N>,T>& bb)
template <typename Traits, bool is_filtered=false>
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<double> N Y N as we can do to_double of interval
SC<Rational> N N Y as we later need exact
SC<Interval_nt> N N Y to simplify life
SC<Expr> N N Y as we later need exact
== Epeck_with_sqrt
*/

//floating-point based filtered version
template <typename Approximate_traits, typename Rational_traits>
class Curve<std::pair<Approximate_traits,Rational_traits>, true>
: public Curve<Approximate_traits, false>
Expand All @@ -82,37 +91,23 @@ class Curve<std::pair<Approximate_traits,Rational_traits>, 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<Point>::Kernel,
typename Kernel_traits<Rational_point>::Kernel, NT_converter<distance_t,double>>;

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<double> N Y N as we can do to_double of interval
SC<Rational> N N Y as we later need exact
SC<Interval_nt> N N Y to simplify life
SC<Expr> N N Y as we later need exact
== Epeck_with_sqrt
*/

template <class PointRange>
Curve(const PointRange& point_range)
{
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>;

//TODO: not working for now with EPECK or SC<Rational>
//~ 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)
Expand All @@ -123,19 +118,53 @@ class Curve<std::pair<Approximate_traits,Rational_traits>, 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 <typename Input_point, typename Approximate_traits, typename Rational_traits>
class Curve<std::tuple<Input_point, Approximate_traits,Rational_traits>, true>
: public Curve<Approximate_traits, false>
{
public:
using Base = Curve<Approximate_traits, false>;
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 <class PointRange>
Curve(const PointRange& point_range)
{
using IPoint = typename std::iterator_traits<typename PointRange::const_iterator>::value_type;

this->points.reserve(point_range.size());
rational_points.reserve(point_range.size());

typename Kernel_traits<Input_point>::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<Input_point> rational_points;
};

template <typename T>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ struct Lambda<Curve<FilteredTraits,true>>
using Approx = distance_t;
using PointID = typename C::PointID;
using Rational = typename Curve::Rational;
using Exact = CGAL::Sqrt_extension<Rational, Rational, CGAL::Tag_true, CGAL::Tag_false>;
using Exact = typename Root_of_traits<Rational>::Root_of_2;

mutable Approx approx;
mutable std::optional<Exact> exact;
Expand Down Expand Up @@ -128,11 +128,12 @@ struct Lambda<Curve<FilteredTraits,true>>
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);
Expand All @@ -141,7 +142,7 @@ struct Lambda<Curve<FilteredTraits,true>>
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -127,7 +127,7 @@ intersection_interval(Curve<T, true> const& curve1,
// if not empty

std::optional<bool> res =
fill_lambda<typename T::first_type>(
fill_lambda<typename C::AT>(
curve1[center_id], curve2[seg_start_id], curve2[seg_start_id + 1],
C::inf(radius), II, curve1, center_id, curve2, seg_start_id);

Expand All @@ -140,7 +140,7 @@ intersection_interval(Curve<T, true> const& curve1,
CGAL_assertion(radius.is_point());
std::pair<Lambda<C>, Lambda<C>> II;
// if not empty
if (fill_lambda<typename T::second_type>(
if (fill_lambda<typename C::ET>(
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())
{
Expand Down
34 changes: 0 additions & 34 deletions Frechet_distance/include/CGAL/Frechet_distance_traits_2.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,6 @@
#define CGAL_Frechet_distance_TRAITS_2_H

#include <CGAL/license/Frechet_distance.h>
#include <CGAL/Frechet_distance/internal/id.h>
#include <CGAL/Frechet_distance/internal/Get_exact_kernel.h>
#include <CGAL/Bbox_2.h>
#include <CGAL/Interval_nt.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Cartesian_converter.h>

// TODO: is it too restrictive to use vectors by default?
#include <vector>

namespace CGAL
{
Expand All @@ -44,42 +35,17 @@ 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();
}

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<Kernel>::is_filtered;
static constexpr bool is_floating_point = CGAL::Frechet_distance_::internal::Get_exact_kernel<Kernel>::is_floating_point;
using distance_t = CGAL::Interval_nt<false>;
using Approximate_kernel = CGAL::Simple_cartesian<distance_t>;
using Approximate_point = typename Approximate_kernel::Point_2;
using Exact_kernel = typename CGAL::Frechet_distance_::internal::Get_exact_kernel<Kernel>::type;
using Exact_point = typename Exact_kernel::Point_2;
using D2D = NT_converter<distance_t,double>;
using A2E = Cartesian_converter<Approximate_kernel, Exact_kernel, D2D>;
using FT2I = NT_converter<typename Kernel::FT,distance_t>;
using K2A = Cartesian_converter<Kernel, Approximate_kernel, FT2I>;
*/
};

} // end of namespace CGAL
Expand Down
Loading

0 comments on commit c2d7402

Please sign in to comment.