From 1b7555826ad51fc98264466fdafd0d06b492633f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 2 May 2017 11:38:14 +0200 Subject: [PATCH] Fixed Lazy_alpha_NT_2 -- Aligned with the improvements that exist in Alpha_shapes_3 -- Actually define proper overloads for side_of_bounded_circle for weighted points (was broken) -- Minor stuff --- .../include/CGAL/internal/Lazy_alpha_nt_2.h | 285 ++++++++++++------ 1 file changed, 185 insertions(+), 100 deletions(-) diff --git a/Alpha_shapes_2/include/CGAL/internal/Lazy_alpha_nt_2.h b/Alpha_shapes_2/include/CGAL/internal/Lazy_alpha_nt_2.h index af6cab194c8..1e2968d44a9 100644 --- a/Alpha_shapes_2/include/CGAL/internal/Lazy_alpha_nt_2.h +++ b/Alpha_shapes_2/include/CGAL/internal/Lazy_alpha_nt_2.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 INRIA Sophia-Antipolis (France). +// Copyright (c) 2012, 2017 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org). @@ -13,29 +13,35 @@ // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // Author(s) : Sébastien Loriot - +// Mael Rouxel-Labbé #ifndef CGAL_INTERNAL_LAZY_ALPHA_NT_2_H #define CGAL_INTERNAL_LAZY_ALPHA_NT_2_H #include -#include -#include #include -#include +#include +#include #include -#include #include #include #include -#include namespace CGAL { namespace internal { +template +struct Input_points_for_lazy_alpha_nt_2 +{ + int nbpts; + const T* p0; + const T* p1; + const T* p2; +}; + //non-weighted case template @@ -63,21 +69,17 @@ struct Types_for_alpha_nt_2<::CGAL::Tag_true /* Weighted_tag */, Kernel_approx, Kernel_exact> { //Converter types - typedef CGAL::Cartesian_converter To_approx; - typedef CGAL::Cartesian_converter To_exact; - - //Traits types - typedef ::CGAL::Regular_triangulation_euclidean_traits_2 Approx_traits; - typedef ::CGAL::Regular_triangulation_euclidean_traits_2 Exact_traits; + typedef CGAL::Cartesian_converter To_approx; + typedef CGAL::Cartesian_converter To_exact; //Point types - typedef typename Approx_traits::Weighted_point Approx_point; - typedef typename Exact_traits::Weighted_point Exact_point; - typedef typename Input_traits::Weighted_point Input_point; + typedef typename Kernel_approx::Weighted_point_2 Approx_point; + typedef typename Kernel_exact::Weighted_point_2 Exact_point; + typedef typename Input_traits::Weighted_point_2 Input_point; //Constructions - typedef typename Approx_traits::Compute_squared_radius_2 Approx_squared_radius; - typedef typename Exact_traits::Compute_squared_radius_2 Exact_squared_radius; + typedef typename Kernel_approx::Compute_squared_radius_smallest_orthogonal_circle_2 Approx_squared_radius; + typedef typename Kernel_exact::Compute_squared_radius_smallest_orthogonal_circle_2 Exact_squared_radius; }; template @@ -123,19 +125,16 @@ class Lazy_alpha_nt_2 } //members - unsigned nb_pt; //the members can be updated when calling method exact() - mutable bool updated; - mutable NT_exact exact_; + mutable boost::optional exact_; mutable NT_approx approx_; - typedef std::vector Data_vector; - boost::shared_ptr inputs_ptr; //private functions - const Data_vector& data() const { return *inputs_ptr; } + typedef Input_points_for_lazy_alpha_nt_2 Data_vector; + Data_vector input_points; - Data_vector& - data(){ return *inputs_ptr; } + const Data_vector& data() const{ return input_points;} + Data_vector& data(){ return input_points;} public: typedef NT_exact Exact_nt; @@ -143,33 +142,32 @@ public: void update_exact() const { - switch (nb_pt){ + switch(data().nbpts) { case 1: - exact_ = Exact_squared_radius()( to_exact(*data()[0]) ); + exact_ = Exact_squared_radius()( to_exact(*data().p0) ); break; case 2: - exact_ = Exact_squared_radius()( to_exact(*data()[0]),to_exact(*data()[1]) ); + exact_ = Exact_squared_radius()( to_exact(*data().p0),to_exact(*data().p1) ); break; case 3: - exact_ = Exact_squared_radius()( to_exact(*data()[0]),to_exact(*data()[1]),to_exact(*data()[2]) ); + exact_ = Exact_squared_radius()( to_exact(*data().p0),to_exact(*data().p1),to_exact(*data().p2) ); break; default: CGAL_assertion(false); } - updated=true; } void set_approx() { - switch (nb_pt){ + switch(data().nbpts) { case 1: - approx_ = Approx_squared_radius()( to_approx(*data()[0]) ); + approx_ = Approx_squared_radius()( to_approx(*data().p0) ); break; case 2: - approx_ = Approx_squared_radius()( to_approx(*data()[0]),to_approx(*data()[1]) ); + approx_ = Approx_squared_radius()( to_approx(*data().p0),to_approx(*data().p1) ); break; case 3: - approx_ = Approx_squared_radius()( to_approx(*data()[0]),to_approx(*data()[1]),to_approx(*data()[2]) ); + approx_ = Approx_squared_radius()( to_approx(*data().p0),to_approx(*data().p1),to_approx(*data().p2) ); break; default: CGAL_assertion(false); @@ -178,11 +176,11 @@ public: const NT_exact& exact() const { - if (!updated){ + if (exact_ == boost::none) { update_exact(); - approx_ = to_interval(exact_); + approx_=to_interval(*exact_); } - return exact_; + return *exact_; } const NT_approx& approx() const { @@ -190,36 +188,51 @@ public: } //Constructors - Lazy_alpha_nt_2() : nb_pt(0), updated(true), exact_(0), approx_(0) { } - Lazy_alpha_nt_2(double d) : nb_pt(0), updated(true), exact_(d), approx_(d) { } - - Lazy_alpha_nt_2(const Input_point& wp1) - :nb_pt(1), updated(false), inputs_ptr(new Data_vector()) + Lazy_alpha_nt_2() + : exact_(Exact_nt(0)), approx_(0) { - data().reserve(nb_pt); - data().push_back(&wp1); + data().nbpts=0; + data().p0=NULL; + data().p1=NULL; + data().p2=NULL; + } + + Lazy_alpha_nt_2(double d) + : exact_(Exact_nt(d)), approx_(d) + { + data().nbpts=0; + data().p0=NULL; + data().p1=NULL; + data().p2=NULL; + } + + Lazy_alpha_nt_2(const Input_point& wp0) + { + data().nbpts=1; + data().p0=&wp0; + data().p1=NULL; + data().p2=NULL; set_approx(); } - Lazy_alpha_nt_2(const Input_point& wp1, + Lazy_alpha_nt_2(const Input_point& wp0, + const Input_point& wp1) + { + data().nbpts=2; + data().p0=&wp0; + data().p1=&wp1; + data().p2=NULL; + set_approx(); + } + + Lazy_alpha_nt_2(const Input_point& wp0, + const Input_point& wp1, const Input_point& wp2) - : nb_pt(2), updated(false), inputs_ptr(new Data_vector()) { - data().reserve(nb_pt); - data().push_back(&wp1); - data().push_back(&wp2); - set_approx(); - } - - Lazy_alpha_nt_2(const Input_point& wp1, - const Input_point& wp2, - const Input_point& wp3) - : nb_pt(3), updated(false), inputs_ptr(new Data_vector()) - { - data().reserve(nb_pt); - data().push_back(&wp1); - data().push_back(&wp2); - data().push_back(&wp3); + data().nbpts=3; + data().p0=&wp0; + data().p1=&wp1; + data().p2=&wp2; set_approx(); } @@ -227,14 +240,12 @@ public: bool \ operator CMP (const Lazy_alpha_nt_2 &other) const \ { \ - try{ \ - return this->approx() CMP other.approx(); \ - } \ - catch(CGAL::Uncertain_conversion_exception&){ \ + Uncertain res = this->approx() CMP other.approx(); \ + if (res.is_certain()) \ + return res; \ + else \ return this->exact() CMP other.exact(); \ - } \ } \ - \ CGAL_LANT_COMPARE_FUNCTIONS(<) CGAL_LANT_COMPARE_FUNCTIONS(>) @@ -246,23 +257,67 @@ public: #undef CGAL_LANT_COMPARE_FUNCTIONS }; -template +template std::ostream& -operator<< (std::ostream& os, const Lazy_alpha_nt_2& a){ +operator<< (std::ostream& os, + const Lazy_alpha_nt_2& a){ return os << ::CGAL::to_double(a.approx()); } -template +// small classes to select the functors in weighted or unweighted cases +template +struct iCompute_squared_radius_2; + +template +struct iCompute_squared_radius_2 +{ + template + typename GeomTraits::Compute_squared_radius_2 + operator()(const As& as) const { + return static_cast(as).geom_traits(). + compute_squared_radius_2_object(); + } +}; + +template +struct iCompute_squared_radius_2 +{ + template + typename GeomTraits::Compute_squared_radius_smallest_orthogonal_circle_2 + operator()(const As& as) const { + return static_cast(as).geom_traits(). + compute_squared_radius_smallest_orthogonal_circle_2_object(); + } +}; + +template +struct iSide_of_bounded_circle_2; + +template +struct iSide_of_bounded_circle_2 +{ + template + typename GeomTraits::Side_of_bounded_circle_2 + operator()(const As& as) const { + return static_cast(as).geom_traits(). + side_of_bounded_circle_2_object(); + } +}; + +template +struct iSide_of_bounded_circle_2 +{ + template + typename GeomTraits::Power_side_of_bounded_power_circle_2 + operator()(const As& as) const { + return static_cast(as).geom_traits(). + power_side_of_bounded_power_circle_2_object(); + } +}; + +template struct Lazy_compute_squared_radius_2 { - typedef typename Type_of_alpha::Input_point Point; - - Type_of_alpha operator()(const Point& p, - const Point& q, - const Point& r, - const Point& s) - { return Type_of_alpha(p,q,r,s); } - Type_of_alpha operator()(const Point& p, const Point& q, const Point& r) @@ -276,34 +331,59 @@ struct Lazy_compute_squared_radius_2 { return Type_of_alpha(p); } }; -template +template struct Alpha_nt_selector_impl_2; -template -struct Alpha_nt_selector_impl_2 +template +struct Alpha_nt_selector_impl_2 { - typedef typename GeomTraits::FT Type_of_alpha; - typedef typename GeomTraits::Compute_squared_radius_2 Compute_squared_radius_2; + typedef typename GeomTraits::FT Type_of_alpha; + typedef iCompute_squared_radius_2 Compute_squared_radius_2; + typedef iSide_of_bounded_circle_2 Side_of_bounded_circle_2; }; -BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_typedef_Weighted_point,Weighted_point,false) - -template -struct Alpha_nt_selector_impl_2 +template +struct Alpha_nt_selector_impl_2 { - //This is not very satisfactory but we can improve it if some user complains. - typedef Boolean_tag< - Has_typedef_Weighted_point::value && - !boost::is_same< - typename Kernel_traits::Kernel::Compute_squared_radius_2, - typename GeomTraits::Compute_squared_radius_2 - >::value - > Weighted_tag; - typedef Lazy_alpha_nt_2 Type_of_alpha; - typedef Lazy_compute_squared_radius_2 Compute_squared_radius_2; + typedef Lazy_alpha_nt_2< + GeomTraits, true /* mode */, Tag_false /* Weighted_tag */> Type_of_alpha; + typedef Lazy_compute_squared_radius_2< + Type_of_alpha, typename GeomTraits::Point_2> Functor; + + struct Compute_squared_radius_2 + { + template + Functor operator()(const As&){return Functor();} + }; + + typedef iSide_of_bounded_circle_2 Side_of_bounded_circle_2; }; -template +template +struct Alpha_nt_selector_impl_2 +{ + typedef Lazy_alpha_nt_2< + GeomTraits, true /* mode */, Tag_true /* Weighted_tag */> Type_of_alpha; + + typedef Lazy_compute_squared_radius_2< + Type_of_alpha, typename GeomTraits::Weighted_point_2> Functor; + + struct Compute_squared_radius_2 + { + template + Functor operator()(const As&){return Functor();} + }; + + typedef iSide_of_bounded_circle_2 Side_of_bounded_circle_2; +}; + +template struct Alpha_nt_selector_2 : public Alpha_nt_selector_impl_2< GeomTraits, @@ -311,9 +391,14 @@ struct Alpha_nt_selector_2 ExactAlphaComparisonTag::value > > { }; - } // namespace internal +template +double to_double(const internal::Lazy_alpha_nt_2& a) +{ + return to_double(a.approx()); +} + } // namespace CGAL #endif // CGAL_INTERNAL_LAZY_ALPHA_NT_2_H