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
This commit is contained in:
Mael Rouxel-Labbé 2017-05-02 11:38:14 +02:00
parent 3e81fd1b6b
commit 1b7555826a
1 changed files with 185 additions and 100 deletions

View File

@ -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 <sebastien.loriot@geometryfactory.com>
// Mael Rouxel-Labbé
#ifndef CGAL_INTERNAL_LAZY_ALPHA_NT_2_H
#define CGAL_INTERNAL_LAZY_ALPHA_NT_2_H
#include <CGAL/license/Alpha_shapes_2.h>
#include <CGAL/number_type_basic.h>
#include <CGAL/internal/Exact_type_selector.h>
#include <CGAL/assertions.h>
#include <CGAL/Regular_triangulation_euclidean_traits_2.h>
#include <CGAL/internal/Exact_type_selector.h>
#include <CGAL/number_type_basic.h>
#include <CGAL/Cartesian_converter.h>
#include <boost/shared_ptr.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/type_traits.hpp>
#include <iostream>
#include <vector>
namespace CGAL {
namespace internal {
template <class T>
struct Input_points_for_lazy_alpha_nt_2
{
int nbpts;
const T* p0;
const T* p1;
const T* p2;
};
//non-weighted case
template <class Weighted_tag, class Input_traits, class Kernel_input,
class Kernel_approx, class Kernel_exact>
@ -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<Kernel_input, Kernel_approx> To_approx;
typedef CGAL::Cartesian_converter<Kernel_input, Kernel_exact> To_exact;
//Traits types
typedef ::CGAL::Regular_triangulation_euclidean_traits_2<Kernel_approx> Approx_traits;
typedef ::CGAL::Regular_triangulation_euclidean_traits_2<Kernel_exact> Exact_traits;
typedef CGAL::Cartesian_converter<Kernel_input, Kernel_approx> To_approx;
typedef CGAL::Cartesian_converter<Kernel_input, Kernel_exact> 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<class Input_traits, bool mode, class Weighted_tag>
@ -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<NT_exact> exact_;
mutable NT_approx approx_;
typedef std::vector<const Input_point*> Data_vector;
boost::shared_ptr<Data_vector> inputs_ptr;
//private functions
const Data_vector& data() const { return *inputs_ptr; }
typedef Input_points_for_lazy_alpha_nt_2<Input_point> 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<Input_traits,mode,Weighted_tag> &other) const \
{ \
try{ \
return this->approx() CMP other.approx(); \
} \
catch(CGAL::Uncertain_conversion_exception&){ \
Uncertain<bool> 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<class Input_traits, class Kernel_input, bool mode, class Weighted_tag>
template<class Input_traits, bool mode, class Weighted_tag>
std::ostream&
operator<< (std::ostream& os, const Lazy_alpha_nt_2<Input_traits, mode, Weighted_tag>& a){
operator<< (std::ostream& os,
const Lazy_alpha_nt_2<Input_traits, mode, Weighted_tag>& a){
return os << ::CGAL::to_double(a.approx());
}
template <class Type_of_alpha>
// small classes to select the functors in weighted or unweighted cases
template <class GeomTraits, class Weighted_tag>
struct iCompute_squared_radius_2;
template <class GeomTraits>
struct iCompute_squared_radius_2<GeomTraits, Tag_false /* Weighted_tag*/>
{
template <class As>
typename GeomTraits::Compute_squared_radius_2
operator()(const As& as) const {
return static_cast<const typename As::Triangulation&>(as).geom_traits().
compute_squared_radius_2_object();
}
};
template <class GeomTraits>
struct iCompute_squared_radius_2<GeomTraits, Tag_true /* Weighted_tag*/>
{
template <class As>
typename GeomTraits::Compute_squared_radius_smallest_orthogonal_circle_2
operator()(const As& as) const {
return static_cast<const typename As::Triangulation&>(as).geom_traits().
compute_squared_radius_smallest_orthogonal_circle_2_object();
}
};
template <class GeomTraits, class Weighted_tag>
struct iSide_of_bounded_circle_2;
template <class GeomTraits>
struct iSide_of_bounded_circle_2<GeomTraits, Tag_false /* Weighted_tag*/>
{
template <class As>
typename GeomTraits::Side_of_bounded_circle_2
operator()(const As& as) const {
return static_cast<const typename As::Triangulation&>(as).geom_traits().
side_of_bounded_circle_2_object();
}
};
template <class GeomTraits>
struct iSide_of_bounded_circle_2<GeomTraits, Tag_true /* Weighted_tag*/>
{
template <class As>
typename GeomTraits::Power_side_of_bounded_power_circle_2
operator()(const As& as) const {
return static_cast<const typename As::Triangulation&>(as).geom_traits().
power_side_of_bounded_power_circle_2_object();
}
};
template <class Type_of_alpha, class Point>
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 <class GeomTraits, class ExactAlphaComparisonTag>
template <class GeomTraits, class ExactAlphaComparisonTag, class Weighted_tag>
struct Alpha_nt_selector_impl_2;
template <class GeomTraits>
struct Alpha_nt_selector_impl_2<GeomTraits, Tag_false>
template <class GeomTraits, class Weighted_tag>
struct Alpha_nt_selector_impl_2<GeomTraits,
Tag_false /* ExactAlphaComparisonTag */,
Weighted_tag>
{
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<GeomTraits, Weighted_tag> Compute_squared_radius_2;
typedef iSide_of_bounded_circle_2<GeomTraits, Weighted_tag> Side_of_bounded_circle_2;
};
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_typedef_Weighted_point,Weighted_point,false)
template <class GeomTraits>
struct Alpha_nt_selector_impl_2<GeomTraits, Tag_true>
template <class GeomTraits, class Weighted_tag>
struct Alpha_nt_selector_impl_2<GeomTraits,
Tag_true /* ExactAlphaComparisonTag */,
Weighted_tag>
{
//This is not very satisfactory but we can improve it if some user complains.
typedef Boolean_tag<
Has_typedef_Weighted_point<GeomTraits>::value &&
!boost::is_same<
typename Kernel_traits<typename GeomTraits::Point_2>::Kernel::Compute_squared_radius_2,
typename GeomTraits::Compute_squared_radius_2
>::value
> Weighted_tag;
typedef Lazy_alpha_nt_2<GeomTraits, true, Weighted_tag> Type_of_alpha;
typedef Lazy_compute_squared_radius_2<Type_of_alpha> 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<class As>
Functor operator()(const As&){return Functor();}
};
typedef iSide_of_bounded_circle_2<GeomTraits, Weighted_tag> Side_of_bounded_circle_2;
};
template <class GeomTraits, class ExactAlphaComparisonTag>
template <class GeomTraits>
struct Alpha_nt_selector_impl_2<GeomTraits,
Tag_true /* ExactAlphaComparisonTag */,
Tag_true /* Weighted_tag */ >
{
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<class As>
Functor operator()(const As&){return Functor();}
};
typedef iSide_of_bounded_circle_2<GeomTraits, Tag_true> Side_of_bounded_circle_2;
};
template <class GeomTraits, class ExactAlphaComparisonTag, class Weighted_tag>
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<class Input_traits, bool mode, class Weighted_tag>
double to_double(const internal::Lazy_alpha_nt_2<Input_traits, mode, Weighted_tag>& a)
{
return to_double(a.approx());
}
} // namespace CGAL
#endif // CGAL_INTERNAL_LAZY_ALPHA_NT_2_H