mirror of https://github.com/CGAL/cgal
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:
parent
3e81fd1b6b
commit
1b7555826a
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue