Add member operator() to Approximate() for point and segment approximation and used it to remove the compile-time-dispatching all together in the drawing function

This commit is contained in:
Efi Fogel 2023-04-27 13:31:10 +03:00
parent 3f65c37eda
commit ef7b62119b
3 changed files with 115 additions and 51 deletions

View File

@ -30,6 +30,7 @@
* functors required by the concept it models.
*/
#include <CGAL/Cartesian.h>
#include <CGAL/Algebraic_structure_traits.h>
#include <CGAL/number_utils.h>
#include <CGAL/tags.h>
@ -231,36 +232,62 @@ public:
/// \name Functor definitions for the landmarks point-location strategy.
//@{
typedef double Approximate_number_type;
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
typedef Approximate_kernel::Point_2 Approximate_point_2;
class Approximate_2 {
protected:
using Traits = Arr_non_caching_segment_basic_traits_2<Kernel>;
/*! The traits (in case it has state) */
const Traits& m_traits;
/*! Constructor
* \param traits the traits.
*/
Approximate_2(const Traits& traits) : m_traits(traits) {}
friend class Arr_non_caching_segment_basic_traits_2<Kernel>;
class Approximate_2
{
public:
/*!
* Return an approximation of a point coordinate.
/*! Return an approximation of a point coordinate.
* \param p The exact point.
* \param i The coordinate index (either 0 or 1).
* \pre i is either 0 or 1.
* \return An approximation of p's x-coordinate (if i == 0), or an
* approximation of p's y-coordinate (if i == 1).
*/
Approximate_number_type operator() (const Point_2& p,
int i) const
{
Approximate_number_type operator() (const Point_2& p, int i) const {
CGAL_precondition (i == 0 || i == 1);
return (i == 0) ? (CGAL::to_double(p.x())) : (CGAL::to_double(p.y()));
}
if (i == 0)
return (CGAL::to_double(p.x()));
else
return (CGAL::to_double(p.y()));
/*! Obtain an approximation of a point.
*/
Approximate_point_2 operator()(const Point_2& p) const
{ return Approximate_point_2(operator()(p, 0), operator()(p, 1)); }
/*! Obtain an approximation of an \f$x\f$-monotone curve.
*/
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2& xcv, double error,
OutputIterator oi, bool l2r = true) const {
auto min_vertex = m_traits.construct_min_vertex_2_object();
auto max_vertex = m_traits.construct_max_vertex_2_object();
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
auto xs = CGAL::to_double(src.x());
auto ys = CGAL::to_double(src.y());
auto xt = CGAL::to_double(trg.x());
auto yt = CGAL::to_double(trg.y());
*oi++ = Approximate_point_2(xs, ys);
*oi++ = Approximate_point_2(xt, yt);
return oi;
}
};
/*! Get an Approximate_2 functor object. */
Approximate_2 approximate_2_object () const
{
return Approximate_2();
}
Approximate_2 approximate_2_object () const { return Approximate_2(*this); }
typedef typename Kernel::Construct_segment_2 Construct_x_monotone_curve_2;

View File

@ -28,6 +28,7 @@
#include <boost/variant.hpp>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Cartesian.h>
#include <CGAL/tags.h>
#include <CGAL/intersections.h>
#include <CGAL/Arr_tags.h>
@ -880,8 +881,23 @@ public:
/// \name Functor definitions for the landmarks point-location strategy.
//@{
typedef double Approximate_number_type;
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
typedef Approximate_kernel::Point_2 Approximate_point_2;
class Approximate_2 {
protected:
using Traits = Arr_segment_traits_2<Kernel>;
/*! The traits (in case it has state) */
const Traits& m_traits;
/*! Constructor
* \param traits the traits.
*/
Approximate_2(const Traits& traits) : m_traits(traits) {}
friend class Arr_segment_traits_2<Kernel>;
public:
/*! Obtain an approximation of a point coordinate.
* \param p the exact point.
@ -890,15 +906,37 @@ public:
* \return An approximation of p's x-coordinate (if i == 0), or an
* approximation of p's y-coordinate (if i == 1).
*/
Approximate_number_type operator()(const Point_2& p, int i) const
{
Approximate_number_type operator()(const Point_2& p, int i) const {
CGAL_precondition((i == 0) || (i == 1));
return (i == 0) ? (CGAL::to_double(p.x())) : (CGAL::to_double(p.y()));
}
/*! Obtain an approximation of a point.
*/
Approximate_point_2 operator()(const Point_2& p) const
{ return Approximate_point_2(operator()(p, 0), operator()(p, 1)); }
/*! Obtain an approximation of an \f$x\f$-monotone curve.
*/
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2& xcv, double error,
OutputIterator oi, bool l2r = true) const {
auto min_vertex = m_traits.construct_min_vertex_2_object();
auto max_vertex = m_traits.construct_max_vertex_2_object();
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
auto xs = CGAL::to_double(src.x());
auto ys = CGAL::to_double(src.y());
auto xt = CGAL::to_double(trg.x());
auto yt = CGAL::to_double(trg.y());
*oi++ = Approximate_point_2(xs, ys);
*oi++ = Approximate_point_2(xt, yt);
return oi;
}
};
/*! Obtain an Approximate_2 functor object. */
Approximate_2 approximate_2_object() const { return Approximate_2(); }
Approximate_2 approximate_2_object() const { return Approximate_2(*this); }
//! Functor
class Construct_x_monotone_curve_2 {

View File

@ -122,9 +122,9 @@ public:
/*! Compile time dispatching
*/
#if 0
template <typename T>
auto bounding_box_impl2(CGAL::Bbox_2& bbox, const Point& p, T const&, long)
-> decltype(void())
void bounding_box_impl2(CGAL::Bbox_2& bbox, const Point& p, T const&, long)
{ bbox += exact_bbox(p); }
template <typename T>
@ -133,8 +133,7 @@ public:
{ bbox += approximate_bbox(p, approx); }
template <typename T>
auto bounding_box_impl1(CGAL::Bbox_2& bbox, const Point& p, T const&, long)
-> decltype(void())
void bounding_box_impl1(CGAL::Bbox_2& bbox, const Point& p, T const&, long)
{ bbox += exact_bbox(p); }
template <typename T>
@ -144,6 +143,12 @@ public:
using Approximate = typename Gt::Approximate_2;
bounding_box_impl2<Approximate>(bbox, p, traits.approximate_2_object(), 0);
}
#else
template <typename T>
void bounding_box_impl1(CGAL::Bbox_2& bbox, const Point& p, T const& traits,
int)
{ bbox += approximate_bbox(p, traits.approximate_2_object()); }
#endif
/*! Compute the bounding box.
*/
@ -268,9 +273,9 @@ protected:
/*! Compile time dispatching
*/
#if 0
template <typename T, typename I = void>
auto draw_region_impl2(Halfedge_const_handle curr, T const&, long) ->
decltype(void())
void draw_region_impl2(Halfedge_const_handle curr, T const&, long)
{ draw_exact_region(curr); }
template <typename T, typename I>
@ -280,8 +285,7 @@ protected:
{ draw_approximate_region(curr, approx); }
template <typename T>
auto draw_region_impl1(Halfedge_const_handle curr, T const&, long) ->
decltype(void())
void draw_region_impl1(Halfedge_const_handle curr, T const&, long)
{ draw_exact_region(curr); }
template <typename T>
@ -290,6 +294,11 @@ protected:
using Approximate = typename Gt::Approximate_2;
draw_region_impl2<Approximate, int>(curr, traits.approximate_2_object(), 0);
}
#else
template <typename T>
void draw_region_impl1(Halfedge_const_handle curr, T const& traits, int)
{ draw_approximate_region(curr, traits.approximate_2_object()); }
#endif
/*! Draw a region.
*/
@ -346,9 +355,9 @@ protected:
/*! Compile time dispatching
*/
#if 0
template <typename T, typename I = void>
auto draw_curve_impl2(const X_monotone_curve& xcv, T const&, long) ->
decltype(void())
void draw_curve_impl2(const X_monotone_curve& xcv, T const&, long)
{ draw_exact_curve(xcv); }
template <typename T, typename I>
@ -358,8 +367,7 @@ protected:
{ draw_approximate_curve(xcv, approx); }
template <typename T>
auto draw_curve_impl1(const X_monotone_curve& xcv, T const&, long) ->
decltype(void())
void draw_curve_impl1(const X_monotone_curve& xcv, T const&, long)
{ draw_exact_curve(xcv); }
template <typename T>
@ -368,6 +376,11 @@ protected:
using Approximate = typename Gt::Approximate_2;
draw_curve_impl2<Approximate, int>(xcv, traits.approximate_2_object(), 0);
}
#else
template <typename T>
void draw_curve_impl1(const X_monotone_curve& xcv, T const& traits, int)
{ draw_approximate_curve(xcv, traits.approximate_2_object()); }
#endif
/*! Draw a curve.
*/
@ -407,8 +420,7 @@ protected:
*/
#if 0
template <typename T>
auto draw_point_impl2(const Point& p, T const&, long) -> decltype(void())
{ add_point(p); }
void draw_point_impl2(const Point& p, T const&, long) { add_point(p); }
template <typename T>
auto draw_point_impl2(const Point& p, T const& approx, int) ->
@ -416,8 +428,7 @@ protected:
{ add_point(approx(p)); }
template <typename T>
auto draw_point_impl1(const Point& p, T const&, long) -> decltype(void())
{ add_point(p); }
void draw_point_impl1(const Point& p, T const&, long) { add_point(p); }
template <typename T>
auto draw_point_impl1(const Point& p, T const& traits, int) ->
@ -427,20 +438,8 @@ protected:
}
#else
template <typename T>
void draw_point_impl2(const Point& p, T const&, ...) { add_point(p); }
template <typename T, typename = decltype(T().approximate_2_object()(Point()))>
void draw_point_impl2(const Point& p, T const& traits, bool) {
auto approx = traits.approximate_2_object();
add_point(approx(p));
}
template <typename T>
void draw_point_impl1(const Point& p, T const&, ...) { add_point(p); }
template <typename T, typename = decltype(T().approximate_2_object())>
void draw_point_impl1(const Point& p, T const& traits, bool)
{ draw_point_impl2<Gt>(p, traits, true); }
void draw_point_impl1(const Point& p, T const& traits, int)
{ add_point(traits.approximate_2_object()(p)); }
#endif
/*! Draw a point.