Merge branch 'Triangulation-add_regular_tri-cjamin_mglisse-old' into Triangulation-add_regular_tri-cjamin_mglisse

This commit is contained in:
Clement Jamin 2017-06-16 11:09:07 +02:00
commit 5b9562ea84
90 changed files with 5163 additions and 1017 deletions

View File

@ -151997,3 +151997,17 @@ pages = {179--189}
year={1998}, year={1998},
organization={Blackwell Publishers} organization={Blackwell Publishers}
} }
@inproceedings{boissonnat2009Delaunay,
TITLE = {{Incremental construction of the Delaunay graph in medium dimension}},
AUTHOR = {Boissonnat, Jean-Daniel and Devillers, Olivier and Hornus, Samuel},
URL = {https://hal.inria.fr/inria-00412437},
BOOKTITLE = {{Annual Symposium on Computational Geometry}},
ADDRESS = {Aarhus, Denmark},
PAGES = {208-216},
YEAR = {2009},
MONTH = Jun,
PDF = {https://hal.inria.fr/inria-00412437/file/socg09.pdf},
HAL_ID = {inria-00412437},
HAL_VERSION = {v1},
}

View File

@ -37,6 +37,9 @@ icc 15 work.
\cgalModels `Kernel_d` \cgalModels `Kernel_d`
\cgalModels `DelaunayTriangulationTraits` \cgalModels `DelaunayTriangulationTraits`
\cgalModels `RegularTriangulationTraits`
\cgalModels `SearchTraits`
\cgalModels `RangeSearchTraits`
\sa `CGAL::Cartesian_d<FieldNumberType>` \sa `CGAL::Cartesian_d<FieldNumberType>`
\sa `CGAL::Homogeneous_d<RingNumberType>` \sa `CGAL::Homogeneous_d<RingNumberType>`
@ -74,9 +77,25 @@ Cartesian_const_iterator_d cartesian_begin()const;
Cartesian_const_iterator_d cartesian_end()const; Cartesian_const_iterator_d cartesian_end()const;
}; };
/*!
represents a weighted point in the Euclidean space
\cgalModels `DefaultConstructible`
\cgalModels `Assignable`
*/
class Weighted_point_d {
public:
/*! introduces a weighted point with point p and weight w. */
Weighted_point_d(const Point_d& p, const double& w);
/*! extracts the point of a weighted point. */
Point_d point() const;
/*! extracts the weight of a weighted point. */
double weight() const;
};
/*! \cgalModels `Kernel_d::Center_of_sphere_d` /*! \cgalModels `Kernel_d::Center_of_sphere_d`
*/ */
struct Construct_circumcenter_d { class Construct_circumcenter_d {
public:
/*! returns the center of the sphere defined by `A=tuple[first,last)`. The sphere is centered in the affine hull of A and passes through all the points of A. The order of the points of A does not matter. /*! returns the center of the sphere defined by `A=tuple[first,last)`. The sphere is centered in the affine hull of A and passes through all the points of A. The order of the points of A does not matter.
\pre A is affinely independant. \pre A is affinely independant.
\tparam ForwardIterator has `Epick_d::Point_d` as value type. \tparam ForwardIterator has `Epick_d::Point_d` as value type.
@ -84,7 +103,8 @@ struct Construct_circumcenter_d {
template<typename ForwardIterator> template<typename ForwardIterator>
Point_d operator()(ForwardIterator first, ForwardIterator last); Point_d operator()(ForwardIterator first, ForwardIterator last);
}; };
struct Compute_squared_radius_d { class Compute_squared_radius_d {
public:
/*! returns the radius of the sphere defined by `A=tuple[first,last)`. The sphere is centered in the affine hull of A and passes through all the points of A. The order of the points of A does not matter. /*! returns the radius of the sphere defined by `A=tuple[first,last)`. The sphere is centered in the affine hull of A and passes through all the points of A. The order of the points of A does not matter.
\pre A is affinely independant. \pre A is affinely independant.
\tparam ForwardIterator has `Epick_d::Point_d` as value type. \tparam ForwardIterator has `Epick_d::Point_d` as value type.
@ -94,7 +114,8 @@ Point_d operator()(ForwardIterator first, ForwardIterator last);
}; };
/*! \cgalModels `Kernel_d::Side_of_bounded_sphere_d` /*! \cgalModels `Kernel_d::Side_of_bounded_sphere_d`
*/ */
struct Side_of_bounded_sphere_d { class Side_of_bounded_sphere_d {
public:
/*! returns the relative position of point p to the sphere defined by `A=tuple[first,last)`. The sphere is centered in the affine hull of A and passes through all the points of A. The order of the points of A does not matter. /*! returns the relative position of point p to the sphere defined by `A=tuple[first,last)`. The sphere is centered in the affine hull of A and passes through all the points of A. The order of the points of A does not matter.
\pre A is affinely independant. \pre A is affinely independant.
\tparam ForwardIterator has `Epick_d::Point_d` as value type. \tparam ForwardIterator has `Epick_d::Point_d` as value type.

View File

@ -6,4 +6,4 @@ Circulator
Stream_support Stream_support
Number_types Number_types
Triangulation Triangulation
Spatial_searching

View File

@ -0,0 +1,53 @@
// Copyright (c) 2014
// INRIA Saclay-Ile de France (France)
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
// Author(s) : Marc Glisse
#ifndef CGAL_EPECK_D_H
#define CGAL_EPECK_D_H
#include <CGAL/NewKernel_d/Cartesian_base.h>
#include <CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h>
#include <CGAL/NewKernel_d/Kernel_d_interface.h>
#include <CGAL/internal/Exact_type_selector.h>
namespace CGAL {
#define CGAL_BASE \
Cartesian_base_d<internal::Exact_field_selector<double>::Type, Dim>
template<class Dim>
struct Epeck_d_help1
: CGAL_BASE
{
CGAL_CONSTEXPR Epeck_d_help1(){}
CGAL_CONSTEXPR Epeck_d_help1(int d):CGAL_BASE(d){}
};
#undef CGAL_BASE
#define CGAL_BASE \
Kernel_d_interface< \
Cartesian_wrap< \
Epeck_d_help1<Dim>, \
Epeck_d<Dim> > >
template<class Dim>
struct Epeck_d
: CGAL_BASE
{
CGAL_CONSTEXPR Epeck_d(){}
CGAL_CONSTEXPR Epeck_d(int d):CGAL_BASE(d){}
};
#undef CGAL_BASE
}
#endif

View File

@ -26,6 +26,7 @@
#include <CGAL/NewKernel_d/Kernel_d_interface.h> #include <CGAL/NewKernel_d/Kernel_d_interface.h>
#include <CGAL/internal/Exact_type_selector.h> #include <CGAL/internal/Exact_type_selector.h>
#include <CGAL/Interval_nt.h> #include <CGAL/Interval_nt.h>
#include <CGAL/NewKernel_d/Types/Weighted_point.h>
namespace CGAL { namespace CGAL {

View File

@ -86,6 +86,7 @@ struct Cartesian_LA_base_d : public Dimension_base<Dim_>
::add<Segment_tag>::type ::add<Segment_tag>::type
::add<Hyperplane_tag>::type ::add<Hyperplane_tag>::type
::add<Sphere_tag>::type ::add<Sphere_tag>::type
::add<Weighted_point_tag>::type
Object_list; Object_list;
typedef typeset< Point_cartesian_const_iterator_tag>::type typedef typeset< Point_cartesian_const_iterator_tag>::type

View File

@ -30,7 +30,7 @@ namespace CGAL {
template < typename Base_, typename AK_, typename EK_ > template < typename Base_, typename AK_, typename EK_ >
struct Cartesian_filter_K : public Base_, struct Cartesian_filter_K : public Base_,
private Store_kernel<AK_>, private Store_kernel2<EK_> private Store_kernel<AK_>, private Store_kernel2<EK_>
{ {
CGAL_CONSTEXPR Cartesian_filter_K(){} CGAL_CONSTEXPR Cartesian_filter_K(){}
CGAL_CONSTEXPR Cartesian_filter_K(int d):Base_(d){} CGAL_CONSTEXPR Cartesian_filter_K(int d):Base_(d){}
@ -61,11 +61,11 @@ struct Cartesian_filter_K : public Base_,
template<class T> struct Type : Get_type<Kernel_base,T> {}; template<class T> struct Type : Get_type<Kernel_base,T> {};
template<class T,class D=void,class=typename Get_functor_category<Cartesian_filter_K,T>::type> struct Functor : template<class T,class D=void,class=typename Get_functor_category<Cartesian_filter_K,T>::type> struct Functor :
Inherit_functor<Kernel_base,T,D> {}; Inherit_functor<Kernel_base,T,D> {};
template<class T,class D> struct Functor<T,D,Predicate_tag> { template<class T,class D> struct Functor<T,D,Predicate_tag> {
typedef typename Get_functor<AK, T>::type AP; typedef typename Get_functor<AK, T>::type AP;
typedef typename Get_functor<EK, T>::type EP; typedef typename Get_functor<EK, T>::type EP;
typedef Filtered_predicate2<EP,AP,C2E,C2A> type; typedef Filtered_predicate2<EP,AP,C2E,C2A> type;
}; };
// TODO: // TODO:
// template<class T> struct Functor<T,No_filter_tag,Predicate_tag> : // template<class T> struct Functor<T,No_filter_tag,Predicate_tag> :

View File

@ -89,6 +89,7 @@ template<class R_> struct Construct_flat_orientation : private Store_kernel<R_>
std::vector<int>& rest=o.rest; rest.reserve(dim+1); std::vector<int>& rest=o.rest; rest.reserve(dim+1);
for(int i=0; i<dim+1; ++i) rest.push_back(i); for(int i=0; i<dim+1; ++i) rest.push_back(i);
for( ; f != e ; ++col, ++f ) { for( ; f != e ; ++col, ++f ) {
//std::cerr << "(*f)[0]=" << (*f)[0] << std::endl;
Point const&p=*f; Point const&p=*f;
// use a coordinate iterator instead? // use a coordinate iterator instead?
for(int i=0; i<dim; ++i) coord(col, i) = ccc(p, i); for(int i=0; i<dim; ++i) coord(col, i) = ccc(p, i);
@ -268,11 +269,61 @@ template<class R_> struct In_flat_side_of_oriented_sphere : private Store_kernel
} }
}; };
template<class R_> struct In_flat_power_side_of_power_sphere_raw : private Store_kernel<R_> {
CGAL_FUNCTOR_INIT_STORE(In_flat_power_side_of_power_sphere_raw)
typedef R_ R;
typedef typename Get_type<R, FT_tag>::type FT;
typedef typename Get_type<R, Point_tag>::type Point;
typedef typename Get_type<R, Orientation_tag>::type result_type;
typedef typename Increment_dimension<typename R::Default_ambient_dimension,2>::type D1;
typedef typename Increment_dimension<typename R::Max_ambient_dimension,2>::type D2;
typedef typename R::LA::template Rebind_dimension<D1,D2>::Other LA;
typedef typename LA::Square_matrix Matrix;
template<class Iter, class IterW, class Wt>
result_type operator()(Flat_orientation const&o, Iter f, Iter e, IterW fw, Point const&x, Wt const&w) const {
// TODO: can't work in the projection, but we should at least remove the row of 1s.
typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
int d=pd(*f);
Matrix m(d+2,d+2);
int i=0;
for(;f!=e;++f,++fw,++i) {
Point const& p=*f;
m(i,0)=1;
m(i,d+1)=-*fw;
for(int j=0;j<d;++j){
m(i,j+1)=c(p,j);
m(i,d+1)+=CGAL_NTS square(m(i,j+1));
}
}
for(std::vector<int>::const_iterator it = o.rest.begin(); it != o.rest.end() /* i<d+1 */; ++i, ++it) {
m(i,0)=1;
for(int j=0;j<d;++j){
m(i,j+1)=0; // unneeded if the matrix is initialized to 0
}
if(*it != d) m(i,d+1)=m(i,1+*it)=1;
else m(i,d+1)=0;
}
m(d+1,0)=1;
m(d+1,d+1)=-w;
for(int j=0;j<d;++j){
m(d+1,j+1)=c(x,j);
m(d+1,d+1)+=CGAL_NTS square(m(d+1,j+1));
}
result_type ret = -LA::sign_of_determinant(CGAL_MOVE(m));
if(o.reverse) ret=-ret;
return ret;
}
};
} }
CGAL_KD_DEFAULT_TYPE(Flat_orientation_tag,(CGAL::CartesianDKernelFunctors::Flat_orientation),(),()); CGAL_KD_DEFAULT_TYPE(Flat_orientation_tag,(CGAL::CartesianDKernelFunctors::Flat_orientation),(),());
CGAL_KD_DEFAULT_FUNCTOR(In_flat_orientation_tag,(CartesianDKernelFunctors::In_flat_orientation<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag)); CGAL_KD_DEFAULT_FUNCTOR(In_flat_orientation_tag,(CartesianDKernelFunctors::In_flat_orientation<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag));
CGAL_KD_DEFAULT_FUNCTOR(In_flat_side_of_oriented_sphere_tag,(CartesianDKernelFunctors::In_flat_side_of_oriented_sphere<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag)); CGAL_KD_DEFAULT_FUNCTOR(In_flat_side_of_oriented_sphere_tag,(CartesianDKernelFunctors::In_flat_side_of_oriented_sphere<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag));
CGAL_KD_DEFAULT_FUNCTOR(In_flat_power_side_of_power_sphere_raw_tag,(CartesianDKernelFunctors::In_flat_power_side_of_power_sphere_raw<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag));
CGAL_KD_DEFAULT_FUNCTOR(Construct_flat_orientation_tag,(CartesianDKernelFunctors::Construct_flat_orientation<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag,In_flat_orientation_tag)); CGAL_KD_DEFAULT_FUNCTOR(Construct_flat_orientation_tag,(CartesianDKernelFunctors::Construct_flat_orientation<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag,In_flat_orientation_tag));
CGAL_KD_DEFAULT_FUNCTOR(Contained_in_affine_hull_tag,(CartesianDKernelFunctors::Contained_in_affine_hull<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag)); CGAL_KD_DEFAULT_FUNCTOR(Contained_in_affine_hull_tag,(CartesianDKernelFunctors::Contained_in_affine_hull<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag));
} }

View File

@ -97,7 +97,7 @@ class KernelD_converter_
//typedef typename KOC::argument_type K1_Obj; //typedef typename KOC::argument_type K1_Obj;
//typedef typename KOC::result_type K2_Obj; //typedef typename KOC::result_type K2_Obj;
public: public:
using Base::operator(); // don't use directly, just make it accessible to the next level using Base::operator(); // don't use directly, just make it accessible to the next level
K2_Obj helper(K1_Obj const& o,CGAL_BOOSTD true_type)const{ K2_Obj helper(K1_Obj const& o,CGAL_BOOSTD true_type)const{
return KOC()(this->myself().kernel(),this->myself().kernel2(),this->myself(),o); return KOC()(this->myself().kernel(),this->myself().kernel2(),this->myself(),o);
} }

View File

@ -54,6 +54,7 @@ template <class Base_> struct Kernel_d_interface : public Base_ {
typedef typename Get_type<Base, Ray_tag>::type Ray_d; typedef typename Get_type<Base, Ray_tag>::type Ray_d;
typedef typename Get_type<Base, Iso_box_tag>::type Iso_box_d; typedef typename Get_type<Base, Iso_box_tag>::type Iso_box_d;
typedef typename Get_type<Base, Aff_transformation_tag>::type Aff_transformation_d; typedef typename Get_type<Base, Aff_transformation_tag>::type Aff_transformation_d;
typedef typename Get_type<Base, Weighted_point_tag>::type Weighted_point_d;
typedef typename Get_functor<Base, Compute_point_cartesian_coordinate_tag>::type Compute_coordinate_d; typedef typename Get_functor<Base, Compute_point_cartesian_coordinate_tag>::type Compute_coordinate_d;
typedef typename Get_functor<Base, Compare_lexicographically_tag>::type Compare_lexicographically_d; typedef typename Get_functor<Base, Compare_lexicographically_tag>::type Compare_lexicographically_d;
typedef typename Get_functor<Base, Equal_points_tag>::type Equal_d; typedef typename Get_functor<Base, Equal_points_tag>::type Equal_d;
@ -64,16 +65,61 @@ template <class Base_> struct Kernel_d_interface : public Base_ {
typedef typename Get_functor<Base, Less_point_cartesian_coordinate_tag>::type Less_coordinate_d; typedef typename Get_functor<Base, Less_point_cartesian_coordinate_tag>::type Less_coordinate_d;
typedef typename Get_functor<Base, Point_dimension_tag>::type Point_dimension_d; typedef typename Get_functor<Base, Point_dimension_tag>::type Point_dimension_d;
typedef typename Get_functor<Base, Side_of_oriented_sphere_tag>::type Side_of_oriented_sphere_d; typedef typename Get_functor<Base, Side_of_oriented_sphere_tag>::type Side_of_oriented_sphere_d;
typedef typename Get_functor<Base, Power_side_of_power_sphere_tag>::type Power_side_of_power_sphere_d;
typedef typename Get_functor<Base, Power_center_tag>::type Power_center_d;
typedef typename Get_functor<Base, Power_distance_tag>::type Power_distance_d;
typedef typename Get_functor<Base, Contained_in_affine_hull_tag>::type Contained_in_affine_hull_d; typedef typename Get_functor<Base, Contained_in_affine_hull_tag>::type Contained_in_affine_hull_d;
typedef typename Get_functor<Base, Construct_flat_orientation_tag>::type Construct_flat_orientation_d; typedef typename Get_functor<Base, Construct_flat_orientation_tag>::type Construct_flat_orientation_d;
typedef typename Get_functor<Base, In_flat_orientation_tag>::type In_flat_orientation_d; typedef typename Get_functor<Base, In_flat_orientation_tag>::type In_flat_orientation_d;
typedef typename Get_functor<Base, In_flat_side_of_oriented_sphere_tag>::type In_flat_side_of_oriented_sphere_d; typedef typename Get_functor<Base, In_flat_side_of_oriented_sphere_tag>::type In_flat_side_of_oriented_sphere_d;
typedef typename Get_functor<Base, In_flat_power_side_of_power_sphere_tag>::type In_flat_power_side_of_power_sphere_d;
typedef typename Get_functor<Base, Point_to_vector_tag>::type Point_to_vector_d; typedef typename Get_functor<Base, Point_to_vector_tag>::type Point_to_vector_d;
typedef typename Get_functor<Base, Vector_to_point_tag>::type Vector_to_point_d; typedef typename Get_functor<Base, Vector_to_point_tag>::type Vector_to_point_d;
typedef typename Get_functor<Base, Translated_point_tag>::type Translated_point_d;
typedef typename Get_functor<Base, Scaled_vector_tag>::type Scaled_vector_d; typedef typename Get_functor<Base, Scaled_vector_tag>::type Scaled_vector_d;
typedef typename Get_functor<Base, Difference_of_vectors_tag>::type Difference_of_vectors_d; typedef typename Get_functor<Base, Difference_of_vectors_tag>::type Difference_of_vectors_d;
typedef typename Get_functor<Base, Difference_of_points_tag>::type Difference_of_points_d; typedef typename Get_functor<Base, Difference_of_points_tag>::type Difference_of_points_d;
typedef typename Get_functor<Base, Construct_ttag<Point_tag> >::type Construct_point_d; //typedef typename Get_functor<Base, Construct_ttag<Point_tag> >::type Construct_point_d;
struct Construct_point_d : private Store_kernel<Kernel> {
typedef Kernel R_; // for the macro
CGAL_FUNCTOR_INIT_STORE(Construct_point_d)
typedef typename Get_functor<Base, Construct_ttag<Point_tag> >::type CP;
typedef Point_d result_type;
Point_d operator()(Weighted_point_d const&wp)const{
return typename Get_functor<Base, Point_drop_weight_tag>::type(this->kernel())(wp);
}
#ifdef CGAL_CXX11
Point_d operator()(Weighted_point_d &wp)const{
return typename Get_functor<Base, Point_drop_weight_tag>::type(this->kernel())(wp);
}
Point_d operator()(Weighted_point_d &&wp)const{
return typename Get_functor<Base, Point_drop_weight_tag>::type(this->kernel())(std::move(wp));
}
Point_d operator()(Weighted_point_d const&&wp)const{
return typename Get_functor<Base, Point_drop_weight_tag>::type(this->kernel())(std::move(wp));
}
template<class...T>
# if __cplusplus >= 201402L
decltype(auto)
# else
Point_d
# endif
operator()(T&&...t)const{
return CP(this->kernel())(std::forward<T>(t)...);
//return CP(this->kernel())(t...);
}
#else
# define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> \
Point_d operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t))const{ \
return CP(this->kernel())(BOOST_PP_ENUM_PARAMS(N,t)); \
}
BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_)
# undef CGAL_CODE
Point_d operator()()const{ \
return CP(this->kernel())(); \
}
#endif
};
typedef typename Get_functor<Base, Construct_ttag<Vector_tag> >::type Construct_vector_d; typedef typename Get_functor<Base, Construct_ttag<Vector_tag> >::type Construct_vector_d;
typedef typename Get_functor<Base, Construct_ttag<Segment_tag> >::type Construct_segment_d; typedef typename Get_functor<Base, Construct_ttag<Segment_tag> >::type Construct_segment_d;
typedef typename Get_functor<Base, Construct_ttag<Sphere_tag> >::type Construct_sphere_d; typedef typename Get_functor<Base, Construct_ttag<Sphere_tag> >::type Construct_sphere_d;
@ -83,6 +129,7 @@ template <class Base_> struct Kernel_d_interface : public Base_ {
typedef typename Get_functor<Base, Construct_ttag<Ray_tag> >::type Construct_ray_d; typedef typename Get_functor<Base, Construct_ttag<Ray_tag> >::type Construct_ray_d;
typedef typename Get_functor<Base, Construct_ttag<Iso_box_tag> >::type Construct_iso_box_d; typedef typename Get_functor<Base, Construct_ttag<Iso_box_tag> >::type Construct_iso_box_d;
typedef typename Get_functor<Base, Construct_ttag<Aff_transformation_tag> >::type Construct_aff_transformation_d; typedef typename Get_functor<Base, Construct_ttag<Aff_transformation_tag> >::type Construct_aff_transformation_d;
typedef typename Get_functor<Base, Construct_ttag<Weighted_point_tag> >::type Construct_weighted_point_d;
typedef typename Get_functor<Base, Midpoint_tag>::type Midpoint_d; typedef typename Get_functor<Base, Midpoint_tag>::type Midpoint_d;
struct Component_accessor_d : private Store_kernel<Kernel> { struct Component_accessor_d : private Store_kernel<Kernel> {
typedef Kernel R_; // for the macro typedef Kernel R_; // for the macro
@ -156,6 +203,7 @@ template <class Base_> struct Kernel_d_interface : public Base_ {
typedef typename Get_functor<Base, Side_of_bounded_circumsphere_tag>::type Side_of_bounded_sphere_d; typedef typename Get_functor<Base, Side_of_bounded_circumsphere_tag>::type Side_of_bounded_sphere_d;
typedef typename Get_functor<Base, Center_of_sphere_tag>::type Center_of_sphere_d; typedef typename Get_functor<Base, Center_of_sphere_tag>::type Center_of_sphere_d;
typedef Center_of_sphere_d Construct_center_d; // RangeSearchTraits
typedef typename Get_functor<Base, Construct_circumcenter_tag>::type Construct_circumcenter_d; typedef typename Get_functor<Base, Construct_circumcenter_tag>::type Construct_circumcenter_d;
typedef typename Get_functor<Base, Value_at_tag>::type Value_at_d; typedef typename Get_functor<Base, Value_at_tag>::type Value_at_d;
typedef typename Get_functor<Base, Point_of_sphere_tag>::type Point_of_sphere_d; typedef typename Get_functor<Base, Point_of_sphere_tag>::type Point_of_sphere_d;
@ -164,6 +212,9 @@ template <class Base_> struct Kernel_d_interface : public Base_ {
typedef typename Get_functor<Base, Construct_min_vertex_tag>::type Construct_min_vertex_d; typedef typename Get_functor<Base, Construct_min_vertex_tag>::type Construct_min_vertex_d;
typedef typename Get_functor<Base, Construct_max_vertex_tag>::type Construct_max_vertex_d; typedef typename Get_functor<Base, Construct_max_vertex_tag>::type Construct_max_vertex_d;
typedef typename Get_functor<Base, Point_weight_tag>::type Compute_weight_d;
typedef typename Get_functor<Base, Point_drop_weight_tag>::type Point_drop_weight_d;
//TODO: //TODO:
//typedef ??? Intersect_d; //typedef ??? Intersect_d;
@ -180,6 +231,9 @@ template <class Base_> struct Kernel_d_interface : public Base_ {
Point_dimension_d point_dimension_d_object()const{ return Point_dimension_d(*this); } Point_dimension_d point_dimension_d_object()const{ return Point_dimension_d(*this); }
Point_of_sphere_d point_of_sphere_d_object()const{ return Point_of_sphere_d(*this); } Point_of_sphere_d point_of_sphere_d_object()const{ return Point_of_sphere_d(*this); }
Side_of_oriented_sphere_d side_of_oriented_sphere_d_object()const{ return Side_of_oriented_sphere_d(*this); } Side_of_oriented_sphere_d side_of_oriented_sphere_d_object()const{ return Side_of_oriented_sphere_d(*this); }
Power_side_of_power_sphere_d power_side_of_power_sphere_d_object()const{ return Power_side_of_power_sphere_d(*this); }
Power_center_d power_center_d_object()const{ return Power_center_d(*this); }
Power_distance_d power_distance_d_object()const{ return Power_distance_d(*this); }
Side_of_bounded_sphere_d side_of_bounded_sphere_d_object()const{ return Side_of_bounded_sphere_d(*this); } Side_of_bounded_sphere_d side_of_bounded_sphere_d_object()const{ return Side_of_bounded_sphere_d(*this); }
Contained_in_affine_hull_d contained_in_affine_hull_d_object()const{ return Contained_in_affine_hull_d(*this); } Contained_in_affine_hull_d contained_in_affine_hull_d_object()const{ return Contained_in_affine_hull_d(*this); }
Contained_in_linear_hull_d contained_in_linear_hull_d_object()const{ return Contained_in_linear_hull_d(*this); } Contained_in_linear_hull_d contained_in_linear_hull_d_object()const{ return Contained_in_linear_hull_d(*this); }
@ -187,8 +241,10 @@ template <class Base_> struct Kernel_d_interface : public Base_ {
Construct_flat_orientation_d construct_flat_orientation_d_object()const{ return Construct_flat_orientation_d(*this); } Construct_flat_orientation_d construct_flat_orientation_d_object()const{ return Construct_flat_orientation_d(*this); }
In_flat_orientation_d in_flat_orientation_d_object()const{ return In_flat_orientation_d(*this); } In_flat_orientation_d in_flat_orientation_d_object()const{ return In_flat_orientation_d(*this); }
In_flat_side_of_oriented_sphere_d in_flat_side_of_oriented_sphere_d_object()const{ return In_flat_side_of_oriented_sphere_d(*this); } In_flat_side_of_oriented_sphere_d in_flat_side_of_oriented_sphere_d_object()const{ return In_flat_side_of_oriented_sphere_d(*this); }
In_flat_power_side_of_power_sphere_d in_flat_power_side_of_power_sphere_d_object()const{ return In_flat_power_side_of_power_sphere_d(*this); }
Point_to_vector_d point_to_vector_d_object()const{ return Point_to_vector_d(*this); } Point_to_vector_d point_to_vector_d_object()const{ return Point_to_vector_d(*this); }
Vector_to_point_d vector_to_point_d_object()const{ return Vector_to_point_d(*this); } Vector_to_point_d vector_to_point_d_object()const{ return Vector_to_point_d(*this); }
Translated_point_d translated_point_d_object()const{ return Translated_point_d(*this); }
Scaled_vector_d scaled_vector_d_object()const{ return Scaled_vector_d(*this); } Scaled_vector_d scaled_vector_d_object()const{ return Scaled_vector_d(*this); }
Difference_of_vectors_d difference_of_vectors_d_object()const{ return Difference_of_vectors_d(*this); } Difference_of_vectors_d difference_of_vectors_d_object()const{ return Difference_of_vectors_d(*this); }
Difference_of_points_d difference_of_points_d_object()const{ return Difference_of_points_d(*this); } Difference_of_points_d difference_of_points_d_object()const{ return Difference_of_points_d(*this); }
@ -221,6 +277,10 @@ template <class Base_> struct Kernel_d_interface : public Base_ {
Construct_aff_transformation_d construct_aff_transformation_d_object()const{ return Construct_aff_transformation_d(*this); } Construct_aff_transformation_d construct_aff_transformation_d_object()const{ return Construct_aff_transformation_d(*this); }
Construct_min_vertex_d construct_min_vertex_d_object()const{ return Construct_min_vertex_d(*this); } Construct_min_vertex_d construct_min_vertex_d_object()const{ return Construct_min_vertex_d(*this); }
Construct_max_vertex_d construct_max_vertex_d_object()const{ return Construct_max_vertex_d(*this); } Construct_max_vertex_d construct_max_vertex_d_object()const{ return Construct_max_vertex_d(*this); }
Construct_weighted_point_d construct_weighted_point_d_object()const{ return Construct_weighted_point_d(*this); }
Compute_weight_d compute_weight_d_object()const{ return Compute_weight_d(*this); }
Point_drop_weight_d point_drop_weight_d_object()const{ return Point_drop_weight_d(*this); }
// Dummies for those required functors missing a concept. // Dummies for those required functors missing a concept.
typedef Null_functor Position_on_line_d; typedef Null_functor Position_on_line_d;

View File

@ -118,5 +118,17 @@ template <class K1, class K2> struct KO_converter<Sphere_tag,K1,K2>{
} }
}; };
template <class K1, class K2> struct KO_converter<Weighted_point_tag,K1,K2>{
typedef typename Get_type<K1, Weighted_point_tag>::type argument_type;
typedef typename Get_type<K2, Weighted_point_tag>::type result_type;
template <class C>
result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& s) const {
typename Get_functor<K1, Point_drop_weight_tag>::type pdw(k1);
typename Get_functor<K1, Point_weight_tag>::type pw(k1);
typename Get_functor<K2, Construct_ttag<Weighted_point_tag> >::type cwp(k2);
return cwp(conv(pdw(s)),conv(pw(s)));
}
};
} }
#endif #endif

View File

@ -52,7 +52,6 @@ template <class R_> struct Construct_sphere : Store_kernel<R_> {
} }
template <class Iter> template <class Iter>
result_type operator()(Iter f, Iter e)const{ result_type operator()(Iter f, Iter e)const{
typedef typename Get_type<R_, Point_tag>::type Point;
typename Get_functor<R_, Construct_circumcenter_tag>::type cc(this->kernel()); typename Get_functor<R_, Construct_circumcenter_tag>::type cc(this->kernel());
typename Get_functor<R_, Squared_distance_tag>::type sd(this->kernel()); typename Get_functor<R_, Squared_distance_tag>::type sd(this->kernel());

View File

@ -0,0 +1,205 @@
// Copyright (c) 2014
// INRIA Saclay-Ile de France (France)
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
// Author(s) : Marc Glisse
#ifndef CGAL_KD_TYPE_WP_H
#define CGAL_KD_TYPE_WP_H
#include <CGAL/NewKernel_d/store_kernel.h>
#include <boost/iterator/counting_iterator.hpp>
namespace CGAL {
namespace KerD {
template <class R_> class Weighted_point {
typedef typename Get_type<R_, FT_tag>::type FT_;
typedef typename Get_type<R_, Point_tag>::type Point_;
Point_ c_;
FT_ w_;
public:
Weighted_point(Point_ const&p, FT_ const&w): c_(p), w_(w) {}
// TODO: Add a piecewise constructor?
Point_ const& point()const{return c_;}
FT_ const& weight()const{return w_;}
};
}
namespace CartesianDKernelFunctors {
template <class R_> struct Construct_weighted_point : Store_kernel<R_> {
CGAL_FUNCTOR_INIT_STORE(Construct_weighted_point)
typedef typename Get_type<R_, Weighted_point_tag>::type result_type;
typedef typename Get_type<R_, Point_tag>::type Point;
typedef typename Get_type<R_, FT_tag>::type FT;
result_type operator()(Point const&a, FT const&b)const{
return result_type(a,b);
}
// Not really needed
result_type operator()()const{
typename Get_functor<R_, Construct_ttag<Point_tag> >::type cp(this->kernel());
return result_type(cp(),0);
}
};
template <class R_> struct Point_drop_weight {
CGAL_FUNCTOR_INIT_IGNORE(Point_drop_weight)
typedef typename Get_type<R_, Weighted_point_tag>::type argument_type;
typedef typename Get_type<R_, Point_tag>::type const& result_type;
// Returning a reference is fragile
result_type operator()(argument_type const&s)const{
return s.point();
}
};
template <class R_> struct Point_weight {
CGAL_FUNCTOR_INIT_IGNORE(Point_weight)
typedef typename Get_type<R_, Weighted_point_tag>::type argument_type;
typedef typename Get_type<R_, FT_tag>::type result_type;
result_type operator()(argument_type const&s)const{
return s.weight();
}
};
template <class R_> struct Power_distance : private Store_kernel<R_> {
CGAL_FUNCTOR_INIT_STORE(Power_distance)
typedef typename Get_type<R_, Weighted_point_tag>::type first_argument_type;
typedef first_argument_type second_argument_type;
typedef typename Get_type<R_, FT_tag>::type result_type;
result_type operator()(first_argument_type const&a, second_argument_type const&b)const{
typename Get_functor<R_, Point_drop_weight_tag>::type pdw(this->kernel());
typename Get_functor<R_, Point_weight_tag>::type pw(this->kernel());
typename Get_functor<R_, Squared_distance_tag>::type sd(this->kernel());
return sd(pdw(a),pdw(b))-pw(a)-pw(b);
}
};
template <class R_> struct Power_distance_to_point : private Store_kernel<R_> {
CGAL_FUNCTOR_INIT_STORE(Power_distance_to_point)
typedef typename Get_type<R_, Weighted_point_tag>::type first_argument_type;
typedef typename Get_type<R_, Point_tag>::type second_argument_type;
typedef typename Get_type<R_, FT_tag>::type result_type;
result_type operator()(first_argument_type const&a, second_argument_type const&b)const{
typename Get_functor<R_, Point_drop_weight_tag>::type pdw(this->kernel());
typename Get_functor<R_, Point_weight_tag>::type pw(this->kernel());
typename Get_functor<R_, Squared_distance_tag>::type sd(this->kernel());
return sd(pdw(a),b)-pw(a);
}
};
template<class R_> struct Power_side_of_power_sphere : private Store_kernel<R_> {
CGAL_FUNCTOR_INIT_STORE(Power_side_of_power_sphere)
typedef R_ R;
typedef typename Get_type<R, Oriented_side_tag>::type result_type;
template<class Iter, class Pt>
result_type operator()(Iter const& f, Iter const& e, Pt const& p0) const {
typename Get_functor<R, Power_side_of_power_sphere_raw_tag>::type ptr(this->kernel());
typename Get_functor<R, Point_drop_weight_tag>::type pdw(this->kernel());
typename Get_functor<R, Point_weight_tag>::type pw(this->kernel());
return ptr (
make_transforming_iterator (f, pdw),
make_transforming_iterator (e, pdw),
make_transforming_iterator (f, pw),
pdw (p0),
pw (p0));
}
};
template<class R_> struct In_flat_power_side_of_power_sphere : private Store_kernel<R_> {
CGAL_FUNCTOR_INIT_STORE(In_flat_power_side_of_power_sphere)
typedef R_ R;
typedef typename Get_type<R, Oriented_side_tag>::type result_type;
template<class Fo, class Iter, class Pt>
result_type operator()(Fo const& fo, Iter const& f, Iter const& e, Pt const& p0) const {
typename Get_functor<R, In_flat_power_side_of_power_sphere_raw_tag>::type ptr(this->kernel());
typename Get_functor<R, Point_drop_weight_tag>::type pdw(this->kernel());
typename Get_functor<R, Point_weight_tag>::type pw(this->kernel());
return ptr (
fo,
make_transforming_iterator (f, pdw),
make_transforming_iterator (e, pdw),
make_transforming_iterator (f, pw),
pdw (p0),
pw (p0));
}
};
// Construct a point at (weighted) distance 0 from all the input
template <class R_> struct Power_center : Store_kernel<R_> {
CGAL_FUNCTOR_INIT_STORE(Power_center)
typedef typename Get_type<R_, Weighted_point_tag>::type WPoint;
typedef WPoint result_type;
typedef typename Get_type<R_, Point_tag>::type Point;
typedef typename Get_type<R_, FT_tag>::type FT;
template <class Iter>
result_type operator()(Iter f, Iter e)const{
// 2*(x-y).c == (x^2-wx^2)-(y^2-wy^2)
typedef typename R_::LA LA;
typedef typename LA::Square_matrix Matrix;
typedef typename LA::Vector Vec;
typedef typename LA::Construct_vector CVec;
typename Get_functor<R_, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
typename Get_functor<R_, Construct_ttag<Point_tag> >::type cp(this->kernel());
typename Get_functor<R_, Point_dimension_tag>::type pd(this->kernel());
typename Get_functor<R_, Squared_distance_to_origin_tag>::type sdo(this->kernel());
typename Get_functor<R_, Power_distance_to_point_tag>::type pdp(this->kernel());
typename Get_functor<R_, Point_drop_weight_tag>::type pdw(this->kernel());
typename Get_functor<R_, Point_weight_tag>::type pw(this->kernel());
typename Get_functor<R_, Construct_ttag<Weighted_point_tag> >::type cwp(this->kernel());
WPoint const& wp0 = *f;
Point const& p0 = pdw(wp0);
int d = pd(p0);
FT const& n0 = sdo(p0) - pw(wp0);
Matrix m(d,d);
Vec b = typename CVec::Dimension()(d);
// Write the point coordinates in lines.
int i;
for(i=0; ++f!=e; ++i) {
WPoint const& wp=*f;
Point const& p=pdw(wp);
FT const& np = sdo(p) - pw(wp);
for(int j=0;j<d;++j) {
m(i,j)=2*(c(p,j)-c(p0,j));
b[i] = np - n0;
}
}
CGAL_assertion (i == d);
Vec res = typename CVec::Dimension()(d);;
//std::cout << "Mat: " << m << "\n Vec: " << one << std::endl;
LA::solve(res, CGAL_MOVE(m), CGAL_MOVE(b));
//std::cout << "Sol: " << res << std::endl;
Point center = cp(d,LA::vector_begin(res),LA::vector_end(res));
FT const& r2 = pdp (wp0, center);
return cwp(CGAL_MOVE(center), r2);
}
};
}
CGAL_KD_DEFAULT_TYPE(Weighted_point_tag,(CGAL::KerD::Weighted_point<K>),(Point_tag),());
CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Weighted_point_tag>,(CartesianDKernelFunctors::Construct_weighted_point<K>),(Weighted_point_tag,Point_tag),());
CGAL_KD_DEFAULT_FUNCTOR(Point_drop_weight_tag,(CartesianDKernelFunctors::Point_drop_weight<K>),(Weighted_point_tag,Point_tag),());
CGAL_KD_DEFAULT_FUNCTOR(Point_weight_tag,(CartesianDKernelFunctors::Point_weight<K>),(Weighted_point_tag,Point_tag),());
CGAL_KD_DEFAULT_FUNCTOR(Power_side_of_power_sphere_tag,(CartesianDKernelFunctors::Power_side_of_power_sphere<K>),(Weighted_point_tag),(Power_side_of_power_sphere_raw_tag,Point_drop_weight_tag,Point_weight_tag));
CGAL_KD_DEFAULT_FUNCTOR(In_flat_power_side_of_power_sphere_tag,(CartesianDKernelFunctors::In_flat_power_side_of_power_sphere<K>),(Weighted_point_tag),(In_flat_power_side_of_power_sphere_raw_tag,Point_drop_weight_tag,Point_weight_tag));
CGAL_KD_DEFAULT_FUNCTOR(Power_distance_tag,(CartesianDKernelFunctors::Power_distance<K>),(Weighted_point_tag,Point_tag),(Squared_distance_tag,Point_drop_weight_tag,Point_weight_tag));
CGAL_KD_DEFAULT_FUNCTOR(Power_distance_to_point_tag,(CartesianDKernelFunctors::Power_distance_to_point<K>),(Weighted_point_tag,Point_tag),(Squared_distance_tag,Point_drop_weight_tag,Point_weight_tag));
CGAL_KD_DEFAULT_FUNCTOR(Power_center_tag,(CartesianDKernelFunctors::Power_center<K>),(Weighted_point_tag,Point_tag),(Compute_point_cartesian_coordinate_tag,Construct_ttag<Point_tag>,Construct_ttag<Weighted_point_tag>,Point_dimension_tag,Squared_distance_to_origin_tag,Point_drop_weight_tag,Point_weight_tag,Power_distance_to_point_tag));
} // namespace CGAL
#endif

View File

@ -33,6 +33,7 @@
#include <CGAL/NewKernel_d/Wrapper/Segment_d.h> #include <CGAL/NewKernel_d/Wrapper/Segment_d.h>
#include <CGAL/NewKernel_d/Wrapper/Sphere_d.h> #include <CGAL/NewKernel_d/Wrapper/Sphere_d.h>
#include <CGAL/NewKernel_d/Wrapper/Hyperplane_d.h> #include <CGAL/NewKernel_d/Wrapper/Hyperplane_d.h>
#include <CGAL/NewKernel_d/Wrapper/Weighted_point_d.h>
#include <CGAL/NewKernel_d/Wrapper/Ref_count_obj.h> #include <CGAL/NewKernel_d/Wrapper/Ref_count_obj.h>
@ -111,6 +112,7 @@ CGAL_REGISTER_OBJECT_WRAPPER(Vector);
CGAL_REGISTER_OBJECT_WRAPPER(Segment); CGAL_REGISTER_OBJECT_WRAPPER(Segment);
CGAL_REGISTER_OBJECT_WRAPPER(Sphere); CGAL_REGISTER_OBJECT_WRAPPER(Sphere);
CGAL_REGISTER_OBJECT_WRAPPER(Hyperplane); CGAL_REGISTER_OBJECT_WRAPPER(Hyperplane);
CGAL_REGISTER_OBJECT_WRAPPER(Weighted_point);
#undef CGAL_REGISTER_OBJECT_WRAPPER #undef CGAL_REGISTER_OBJECT_WRAPPER
// Note: this tends to be an all or nothing thing currently, wrapping // Note: this tends to be an all or nothing thing currently, wrapping

View File

@ -0,0 +1,129 @@
// Copyright (c) 2014
// INRIA Saclay-Ile de France (France)
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
// Author(s) : Marc Glisse
#ifndef CGAL_WRAPPER_WEIGHTED_POINT_D_H
#define CGAL_WRAPPER_WEIGHTED_POINT_D_H
#include <CGAL/representation_tags.h>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
#include <CGAL/Kernel/Return_base_tag.h>
#include <CGAL/Dimension.h>
#ifndef CGAL_CXX11
#include <boost/preprocessor/repetition.hpp>
#endif
#include <boost/utility/result_of.hpp>
namespace CGAL {
namespace Wrap {
template <class R_>
class Weighted_point_d : public Get_type<typename R_::Kernel_base, Weighted_point_tag>::type
{
typedef typename Get_type<R_, FT_tag>::type FT_;
typedef typename R_::Kernel_base Kbase;
typedef typename Get_type<R_, Point_tag>::type Point_;
typedef typename Get_functor<Kbase, Construct_ttag<Weighted_point_tag> >::type CWPBase;
typedef typename Get_functor<Kbase, Point_drop_weight_tag>::type PDWBase;
typedef typename Get_functor<Kbase, Point_weight_tag>::type PWBase;
typedef Weighted_point_d Self;
BOOST_STATIC_ASSERT((boost::is_same<Self, typename Get_type<R_, Weighted_point_tag>::type>::value));
public:
typedef Tag_true Is_wrapper;
typedef typename R_::Default_ambient_dimension Ambient_dimension;
typedef Dimension_tag<0> Feature_dimension;
typedef typename Get_type<Kbase, Weighted_point_tag>::type Rep;
const Rep& rep() const
{
return *this;
}
Rep& rep()
{
return *this;
}
typedef R_ R;
#ifdef CGAL_CXX11
template<class...U,class=typename std::enable_if<!std::is_same<std::tuple<typename std::decay<U>::type...>,std::tuple<Weighted_point_d> >::value>::type> explicit Weighted_point_d(U&&...u)
: Rep(CWPBase()(std::forward<U>(u)...)){}
// // called from Construct_point_d
// template<class...U> explicit Point_d(Eval_functor&&,U&&...u)
// : Rep(Eval_functor(), std::forward<U>(u)...){}
template<class F,class...U> explicit Weighted_point_d(Eval_functor&&,F&&f,U&&...u)
: Rep(std::forward<F>(f)(std::forward<U>(u)...)){}
#if 0
// the new standard may make this necessary
Point_d(Point_d const&)=default;
Point_d(Point_d &);//=default;
Point_d(Point_d &&)=default;
#endif
// try not to use these
Weighted_point_d(Rep const& v) : Rep(v) {}
Weighted_point_d(Rep& v) : Rep(static_cast<Rep const&>(v)) {}
Weighted_point_d(Rep&& v) : Rep(std::move(v)) {}
#else
Weighted_point_d() : Rep(CWPBase()()) {}
Weighted_point_d(Rep const& v) : Rep(v) {} // try not to use it
#define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> \
explicit Weighted_point_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
: Rep(CWPBase()( \
BOOST_PP_ENUM_PARAMS(N,t))) {} \
\
template<class F,BOOST_PP_ENUM_PARAMS(N,class T)> \
Weighted_point_d(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
: Rep(f(BOOST_PP_ENUM_PARAMS(N,t))) {}
/*
template<BOOST_PP_ENUM_PARAMS(N,class T)> \
Point_d(Eval_functor,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
: Rep(Eval_functor(), BOOST_PP_ENUM_PARAMS(N,t)) {}
*/
BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_)
#undef CGAL_CODE
#endif
//TODO: use references?
Point_ point()const{
return Point_(Eval_functor(),PDWBase(),rep());
}
FT_ weight()const{
return PWBase()(rep());
}
};
} //namespace Wrap
} //namespace CGAL
#endif // CGAL_WRAPPER_SPHERE_D_H

View File

@ -554,6 +554,60 @@ template<class R_> struct Orientation<R_,false> : private Store_kernel<R_> {
} }
#endif #endif
namespace CartesianDKernelFunctors {
template<class R_> struct Power_side_of_power_sphere_raw : private Store_kernel<R_> {
CGAL_FUNCTOR_INIT_STORE(Power_side_of_power_sphere_raw)
typedef R_ R;
typedef typename Get_type<R, RT_tag>::type RT;
typedef typename Get_type<R, FT_tag>::type FT;
typedef typename Get_type<R, Point_tag>::type Point;
typedef typename Get_type<R, Oriented_side_tag>::type result_type;
typedef typename Increment_dimension<typename R::Default_ambient_dimension>::type D1;
typedef typename Increment_dimension<typename R::Max_ambient_dimension>::type D2;
typedef typename R::LA::template Rebind_dimension<D1,D2>::Other LA;
typedef typename LA::Square_matrix Matrix;
template<class IterP, class IterW, class Pt, class Wt>
result_type operator()(IterP f, IterP const& e, IterW fw, Pt const& p0, Wt const& w0) const {
typedef typename Get_functor<R, Squared_distance_to_origin_tag>::type Sqdo;
typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
int d=pd(p0);
Matrix m(d+1,d+1);
if(CGAL::Is_stored<Sqdo>::value) {
Sqdo sqdo(this->kernel());
FT const& h0 = sqdo(p0) - w0;
for(int i=0;f!=e;++f,++fw,++i) {
Point const& p=*f;
for(int j=0;j<d;++j){
RT const& x=c(p,j);
m(i,j)=x-c(p0,j);
}
m(i,d) = sqdo(p) - *fw - h0;
}
} else {
for(int i=0;f!=e;++f,++fw,++i) {
Point const& p=*f;
m(i,d) = w0 - *fw;
for(int j=0;j<d;++j){
RT const& x=c(p,j);
m(i,j)=x-c(p0,j);
m(i,d)+=CGAL::square(m(i,j));
}
}
}
if(d%2)
return -LA::sign_of_determinant(CGAL_MOVE(m));
else
return LA::sign_of_determinant(CGAL_MOVE(m));
}
};
}
CGAL_KD_DEFAULT_FUNCTOR(Power_side_of_power_sphere_raw_tag,(CartesianDKernelFunctors::Power_side_of_power_sphere_raw<K>),(Point_tag),(Point_dimension_tag,Squared_distance_to_origin_tag,Compute_point_cartesian_coordinate_tag));
// TODO: make Side_of_oriented_sphere call Power_side_of_power_sphere_raw
namespace CartesianDKernelFunctors { namespace CartesianDKernelFunctors {
template<class R_> struct Side_of_oriented_sphere : private Store_kernel<R_> { template<class R_> struct Side_of_oriented_sphere : private Store_kernel<R_> {
CGAL_FUNCTOR_INIT_STORE(Side_of_oriented_sphere) CGAL_FUNCTOR_INIT_STORE(Side_of_oriented_sphere)

View File

@ -172,6 +172,7 @@ namespace CGAL {
CGAL_DECL_OBJ(Iso_box, Object); CGAL_DECL_OBJ(Iso_box, Object);
CGAL_DECL_OBJ(Bbox, Object); CGAL_DECL_OBJ(Bbox, Object);
CGAL_DECL_OBJ(Aff_transformation, Object); CGAL_DECL_OBJ(Aff_transformation, Object);
CGAL_DECL_OBJ(Weighted_point, Object);
#undef CGAL_DECL_OBJ_ #undef CGAL_DECL_OBJ_
#undef CGAL_DECL_OBJ #undef CGAL_DECL_OBJ
@ -214,6 +215,9 @@ namespace CGAL {
CGAL_DECL_COMPUTE(Scalar_product); CGAL_DECL_COMPUTE(Scalar_product);
CGAL_DECL_COMPUTE(Hyperplane_translation); CGAL_DECL_COMPUTE(Hyperplane_translation);
CGAL_DECL_COMPUTE(Value_at); CGAL_DECL_COMPUTE(Value_at);
CGAL_DECL_COMPUTE(Point_weight);
CGAL_DECL_COMPUTE(Power_distance);
CGAL_DECL_COMPUTE(Power_distance_to_point);
#undef CGAL_DECL_COMPUTE #undef CGAL_DECL_COMPUTE
#define CGAL_DECL_ITER_OBJ(X,Y,Z,C) struct X##_tag {}; \ #define CGAL_DECL_ITER_OBJ(X,Y,Z,C) struct X##_tag {}; \
@ -266,6 +270,8 @@ namespace CGAL {
CGAL_DECL_CONSTRUCT(Construct_min_vertex,Point); CGAL_DECL_CONSTRUCT(Construct_min_vertex,Point);
CGAL_DECL_CONSTRUCT(Construct_max_vertex,Point); CGAL_DECL_CONSTRUCT(Construct_max_vertex,Point);
CGAL_DECL_CONSTRUCT(Construct_circumcenter,Point); CGAL_DECL_CONSTRUCT(Construct_circumcenter,Point);
CGAL_DECL_CONSTRUCT(Point_drop_weight,Point);
CGAL_DECL_CONSTRUCT(Power_center,Weighted_point);
#undef CGAL_DECL_CONSTRUCT #undef CGAL_DECL_CONSTRUCT
#if 0 #if 0
#define CGAL_DECL_ITER_CONSTRUCT(X,Y) struct X##_tag {}; \ #define CGAL_DECL_ITER_CONSTRUCT(X,Y) struct X##_tag {}; \
@ -306,6 +312,10 @@ namespace CGAL {
CGAL_DECL_PREDICATE(Affinely_independent); CGAL_DECL_PREDICATE(Affinely_independent);
CGAL_DECL_PREDICATE(Contained_in_linear_hull); CGAL_DECL_PREDICATE(Contained_in_linear_hull);
CGAL_DECL_PREDICATE(Contained_in_simplex); CGAL_DECL_PREDICATE(Contained_in_simplex);
CGAL_DECL_PREDICATE(Power_side_of_power_sphere_raw);
CGAL_DECL_PREDICATE(Power_side_of_power_sphere);
CGAL_DECL_PREDICATE(In_flat_power_side_of_power_sphere_raw);
CGAL_DECL_PREDICATE(In_flat_power_side_of_power_sphere);
#undef CGAL_DECL_PREDICATE #undef CGAL_DECL_PREDICATE
#define CGAL_DECL_MISC(X) struct X##_tag {}; \ #define CGAL_DECL_MISC(X) struct X##_tag {}; \

View File

@ -22,6 +22,10 @@
#include <boost/iterator/iterator_adaptor.hpp> #include <boost/iterator/iterator_adaptor.hpp>
#include <boost/utility/result_of.hpp> #include <boost/utility/result_of.hpp>
#include <boost/type_traits/is_empty.hpp> #include <boost/type_traits/is_empty.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/or.hpp>
#include <CGAL/Default.h> #include <CGAL/Default.h>
#include <utility> #include <utility>
@ -54,23 +58,31 @@ template<class T> struct Functor_as_base<T,true> : public T {
template <typename Derived, typename F, typename Iter, typename Ref, typename Val> template <typename Derived, typename F, typename Iter, typename Ref, typename Val>
class transforming_iterator_helper class transforming_iterator_helper
{ {
typedef std::iterator_traits<Iter> Iter_traits;
typedef typename Iter_traits::reference Iter_ref;
typedef typename Default::Get<Ref, typedef typename Default::Get<Ref,
#ifdef CGAL_CXX11 #ifdef CGAL_CXX11
decltype(std::declval<F>()(std::declval<typename std::iterator_traits<Iter>::reference>())) decltype(std::declval<F>()(std::declval<Iter_ref>()))
#else #else
typename boost::result_of<F(typename std::iterator_traits<Iter>::value_type)>::type typename boost::result_of<F(typename Iter_traits::value_type)>::type
// should be reference instead of value_type // should be reference instead of value_type
#endif #endif
>::type reference; >::type reference_;
typedef typename Default::Get<Val,typename boost::remove_cv<typename boost::remove_reference<reference>::type>::type>::type value_type; typedef typename Default::Get<Val,typename boost::remove_cv<typename boost::remove_reference<reference_>::type>::type>::type value_type;
// Crappy heuristic. If we have *it that returns a Weighted_point and F that returns a reference to the Point contained in the Weighted_point it takes as argument, we do NOT want the transformed iterator to return a reference to the temporary *it. On the other hand, if *it returns an int n, and F returns a reference to array[n] it is not so good to lose the reference. This probably should be done elsewhere and should at least be made optional...
typedef typename boost::mpl::if_<
boost::mpl::or_<boost::is_reference<Iter_ref>,
boost::is_integral<Iter_ref> >,
reference_, value_type>::type reference;
public: public:
typedef boost::iterator_adaptor< typedef boost::iterator_adaptor<
Derived, Derived,
Iter, Iter,
value_type, value_type,
typename std::iterator_traits<Iter>::iterator_category, typename Iter_traits::iterator_category,
reference reference
> type; > type;
}; };

View File

@ -24,6 +24,8 @@ int main()
#include <CGAL/use.h> #include <CGAL/use.h>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <CGAL/NewKernel_d/Types/Weighted_point.h>
#include <cmath>
//typedef CGAL::Cartesian_base_d<double,CGAL::Dimension_tag<2> > K0; //typedef CGAL::Cartesian_base_d<double,CGAL::Dimension_tag<2> > K0;
//typedef CGAL::Cartesian_base_d<CGAL::Interval_nt_advanced,CGAL::Dimension_tag<2> > KA; //typedef CGAL::Cartesian_base_d<CGAL::Interval_nt_advanced,CGAL::Dimension_tag<2> > KA;
@ -84,6 +86,7 @@ void test2(){
typedef typename K1::Ray_d R; typedef typename K1::Ray_d R;
typedef typename K1::Iso_box_d IB; typedef typename K1::Iso_box_d IB;
typedef typename K1::Flat_orientation_d FO; typedef typename K1::Flat_orientation_d FO;
typedef typename K1::Weighted_point_d WP;
//typedef K1::Construct_point CP; //typedef K1::Construct_point CP;
typedef typename K1::Construct_point_d CP; typedef typename K1::Construct_point_d CP;
@ -135,6 +138,14 @@ void test2(){
typedef typename K1::Construct_min_vertex_d CmV; typedef typename K1::Construct_min_vertex_d CmV;
typedef typename K1::Construct_max_vertex_d CMV; typedef typename K1::Construct_max_vertex_d CMV;
typedef typename K1::Compute_squared_radius_d SR; typedef typename K1::Compute_squared_radius_d SR;
typedef typename K1::Translated_point_d TP;
typedef typename K1::Power_center_d PC;
typedef typename K1::Power_distance_d PoD;
typedef typename K1::Weighted_point_d WP;
typedef typename K1::Construct_weighted_point_d CWP;
//typedef typename K1::Point_drop_weight_d PDW;
typedef CP PDW;
typedef typename K1::Compute_weight_d PW;
CGAL_USE_TYPE(AT); CGAL_USE_TYPE(AT);
CGAL_USE_TYPE(D); CGAL_USE_TYPE(D);
@ -196,6 +207,13 @@ void test2(){
CmV cmv Kinit(construct_min_vertex_d_object); CmV cmv Kinit(construct_min_vertex_d_object);
CMV cMv Kinit(construct_max_vertex_d_object); CMV cMv Kinit(construct_max_vertex_d_object);
SR sr Kinit(compute_squared_radius_d_object); SR sr Kinit(compute_squared_radius_d_object);
TP tp Kinit(translated_point_d_object);
PC pc Kinit(power_center_d_object);
CWP cwp Kinit(construct_weighted_point_d_object);
//PDW pdw Kinit(point_drop_weight_d_object);
PDW const& pdw = cp;
PW pw Kinit(compute_weight_d_object);
PoD pod Kinit(power_distance_d_object);
CGAL_USE(bc); CGAL_USE(bc);
CGAL_USE(pol); CGAL_USE(pol);
@ -203,11 +221,12 @@ void test2(){
CGAL_USE(cd); CGAL_USE(cd);
CGAL_USE(cli); CGAL_USE(cli);
CGAL_USE(cr); CGAL_USE(cr);
using std::abs;
P a=cp(3,4); P a=cp(3,4);
assert(pd(a)==2); assert(pd(a)==2);
assert(pv(a)[1]==4); assert(pv(a)[1]==4);
P b=vp(cv(5,6,7)); P b=vp(cv(5,6,7));
assert(fabs(b[0]-5./7)<.0001); assert(abs(b[0]-5./7)<.0001);
assert(lc(b,a,1)); assert(lc(b,a,1));
assert(!lc(a,b,0)); assert(!lc(a,b,0));
int rr[]={3,5,2}; int rr[]={3,5,2};
@ -221,8 +240,8 @@ void test2(){
assert(cl(a,c)==CGAL::SMALLER); assert(cl(a,c)==CGAL::SMALLER);
assert(ll(b,c)); assert(ll(b,c));
assert(cl(c,b)==CGAL::LARGER); assert(cl(c,b)==CGAL::LARGER);
assert(fabs(m(a,c)[0]-3)<.0001); assert(abs(m(a,c)[0]-3)<.0001);
assert(fabs(m(a,c)[1]-4.5)<.0001); assert(abs(m(a,c)[1]-4.5)<.0001);
P d=cp(r,r+3,CGAL::Homogeneous_tag()); P d=cp(r,r+3,CGAL::Homogeneous_tag());
S s=cs(c,d); S s=cs(c,d);
std::cout << cc(a,1) << std::endl; std::cout << cc(a,1) << std::endl;
@ -277,9 +296,9 @@ void test2(){
assert(v.size()==1); assert(v.size()==1);
assert(lr(tab3+0,tab3+2)==1); assert(lr(tab3+0,tab3+2)==1);
H h=ch(tab2+1,tab2+3,tab2[0]); H h=ch(tab2+1,tab2+3,tab2[0]);
assert(fabs(va(h,x2)-1)<.0001); assert(abs(va(h,x2)-1)<.0001);
assert(fabs(va(h,x3)-1)<.0001); assert(abs(va(h,x3)-1)<.0001);
assert(fabs(va(h,x1)+1)<.0001); assert(abs(va(h,x1)+1)<.0001);
H h2=ch(tab2+1,tab2+3,x1,CGAL::ON_POSITIVE_SIDE); H h2=ch(tab2+1,tab2+3,x1,CGAL::ON_POSITIVE_SIDE);
assert(hops(h2,x1)); assert(hops(h2,x1));
assert(os(h2,x1)==CGAL::ON_POSITIVE_SIDE); assert(os(h2,x1)==CGAL::ON_POSITIVE_SIDE);
@ -340,20 +359,35 @@ void test2(){
Sp sp = csp(tabz+0,tabz+3); Sp sp = csp(tabz+0,tabz+3);
P cent0=cos(sp); P cent0=cos(sp);
P cent1=cos(tabz+0,tabz+3); P cent1=cos(tabz+0,tabz+3);
assert(fabs(cent0[0]-2)<.0001); assert(abs(cent0[0]-2)<.0001);
assert(fabs(cent0[1]+3)<.0001); assert(abs(cent0[1]+3)<.0001);
assert(fabs(cent1[0]-2)<.0001); assert(abs(cent1[0]-2)<.0001);
assert(fabs(cent1[1]+3)<.0001); assert(abs(cent1[1]+3)<.0001);
assert(fabs(sp.squared_radius()-25)<.0001); assert(abs(sp.squared_radius()-25)<.0001);
#if 1
// Fails for an exact kernel
P psp0=ps(sp,0); P psp0=ps(sp,0);
P psp1=ps(sp,1); P psp1=ps(sp,1);
P psp2=ps(sp,2); P psp2=ps(sp,2);
assert(!ed(psp0,psp1)); assert(!ed(psp0,psp1));
assert(!ed(psp0,psp2)); assert(!ed(psp0,psp2));
assert(!ed(psp2,psp1)); assert(!ed(psp2,psp1));
assert(fabs(sd(cent0,psp0)-25)<.0001); assert(abs(sd(cent0,psp0)-25)<.0001);
assert(fabs(sd(cent0,psp1)-25)<.0001); assert(abs(sd(cent0,psp1)-25)<.0001);
assert(fabs(sd(cent0,psp2)-25)<.0001); assert(abs(sd(cent0,psp2)-25)<.0001);
#endif
P x2py1 = tp(x2,y1);
assert(x2py1[1]==-2);
WP tw[]={cwp(cp(5,0),1.5),cwp(cp(2,std::sqrt(3)),1),cwp(cp(2,-std::sqrt(3)),1)};
WP xw=pc(tw+0,tw+3);
assert(abs(pod(xw,tw[0]))<.0001);
assert(abs(pod(xw,tw[1]))<.0001);
assert(abs(pod(xw,tw[2]))<.0001);
assert(pdw(xw)[0]<2.95);
assert(pdw(xw)[0]>2.5);
assert(pw(xw)<2.95);
assert(pw(xw)>2.5);
P tl=cp(2,5); P tl=cp(2,5);
P br=cp(4,-1); P br=cp(4,-1);
@ -459,6 +493,7 @@ void test3(){
PD pd Kinit(point_dimension_d_object); PD pd Kinit(point_dimension_d_object);
AI ai Kinit(affinely_independent_d_object); AI ai Kinit(affinely_independent_d_object);
SBDS sbds Kinit(side_of_bounded_sphere_d_object); SBDS sbds Kinit(side_of_bounded_sphere_d_object);
using std::abs;
P a; // Triangulation needs this :-( P a; // Triangulation needs this :-(
a=cp(2,3,4); a=cp(2,3,4);
assert(pd(a)==3); assert(pd(a)==3);
@ -482,7 +517,7 @@ void test3(){
std::cout << *i << ' '; std::cout << *i << ' ';
std::cout << '\n'; std::cout << '\n';
P e=cp(-2,3,0); P e=cp(-2,3,0);
assert(fabs(sd(e,a)-32)<.0001); assert(abs(sd(e,a)-32)<.0001);
P tab[]={a,b,c,d,e}; P tab[]={a,b,c,d,e};
std::cout << po (&tab[0],tab+4) << ' '; std::cout << po (&tab[0],tab+4) << ' ';
std::cout << sos(&tab[0],tab+5) << ' '; std::cout << sos(&tab[0],tab+5) << ' ';
@ -535,6 +570,7 @@ void test3(){
P x4=cp(0,0,1); P x4=cp(0,0,1);
P x5=cp(0,0,0); P x5=cp(0,0,0);
P x6=cp(0,0,-1); P x6=cp(0,0,-1);
assert(!ed(x1,x2));
P tab2[]={x1,x2,x3,x4,x5}; P tab2[]={x1,x2,x3,x4,x5};
assert(cis(tab2+0,tab2+4,x5)); assert(cis(tab2+0,tab2+4,x5));
assert(po(tab2+0,tab2+4)==CGAL::POSITIVE); assert(po(tab2+0,tab2+4)==CGAL::POSITIVE);
@ -592,6 +628,28 @@ void test3(){
assert(sbds(t1+0,t1+2,cp(2,2,3.415)) == CGAL::ON_UNBOUNDED_SIDE); assert(sbds(t1+0,t1+2,cp(2,2,3.415)) == CGAL::ON_UNBOUNDED_SIDE);
assert(sbds(t1+0,t1+3,cp(2.1,3.5,1.9)) == CGAL::ON_BOUNDED_SIDE); assert(sbds(t1+0,t1+3,cp(2.1,3.5,1.9)) == CGAL::ON_BOUNDED_SIDE);
assert(sbds(t1+0,t1+3,cp(10,10,10)) == CGAL::ON_UNBOUNDED_SIDE); assert(sbds(t1+0,t1+3,cp(10,10,10)) == CGAL::ON_UNBOUNDED_SIDE);
typedef typename K1::Weighted_point_d WP;
typedef typename K1::Construct_weighted_point_d CWP;
//typedef typename K1::Point_drop_weight_d PDW;
typedef CP_ PDW;
typedef typename K1::Compute_weight_d PW;
typedef typename K1::Power_side_of_power_sphere_d PT;
typedef typename K1::In_flat_power_side_of_power_sphere_d IFPT;
CWP cwp Kinit(construct_weighted_point_d_object);
//PDW pdw Kinit(point_drop_weight_d_object);
PDW const& pdw = cp_;
PW pw Kinit(compute_weight_d_object);
PT pt Kinit(power_side_of_power_sphere_d_object);
IFPT ifpt Kinit(in_flat_power_side_of_power_sphere_d_object);
WP wp;
wp = cwp (x1, 2);
WP xw6 = cwp (x6, 0);
assert (pw(wp) == 2);
assert (ed(pdw(wp), x1));
WP tabw[]={cwp(x1,0),cwp(x2,0),cwp(x3,0),cwp(x4,0),cwp(x5,0)};
assert(pt(tabw+0,tabw+4,tabw[4])==CGAL::ON_POSITIVE_SIDE);
assert(ifpt(fo4,tabw+0,tabw+3,xw6)==CGAL::ON_POSITIVE_SIDE);
} }
template struct CGAL::Epick_d<CGAL::Dimension_tag<2> >; template struct CGAL::Epick_d<CGAL::Dimension_tag<2> >;
template struct CGAL::Epick_d<CGAL::Dimension_tag<3> >; template struct CGAL::Epick_d<CGAL::Dimension_tag<3> >;

View File

@ -156,6 +156,17 @@ namespace Eigen {
MulCost = 100 MulCost = 100
}; };
}; };
namespace internal {
template<>
struct significant_decimals_impl<CGAL::Gmpq>
{
static inline int run()
{
return 0;
}
};
}
} }
//since types are included by Gmp_coercion_traits.h: //since types are included by Gmp_coercion_traits.h:

View File

@ -1284,6 +1284,13 @@ namespace Eigen {
MulCost = 10 MulCost = 10
}; };
}; };
namespace internal {
template<class> struct significant_decimals_impl;
template<bool b>
struct significant_decimals_impl<CGAL::Interval_nt<b> >
: significant_decimals_impl<typename CGAL::Interval_nt<b>::value_type> { };
}
} }
#endif // CGAL_INTERVAL_NT_H #endif // CGAL_INTERVAL_NT_H

View File

@ -10,6 +10,7 @@ range search queries in a model of `SpatialTree`.
\cgalHasModel `CGAL::Cartesian_d<FT>` \cgalHasModel `CGAL::Cartesian_d<FT>`
\cgalHasModel `CGAL::Homogeneous_d<RT>` \cgalHasModel `CGAL::Homogeneous_d<RT>`
\cgalHasModel `CGAL::Epick_d<DimensionTag>`
\cgalHasModel `CGAL::Search_traits_2<Kernel>` \cgalHasModel `CGAL::Search_traits_2<Kernel>`
\cgalHasModel `CGAL::Search_traits_3<Kernel>` \cgalHasModel `CGAL::Search_traits_3<Kernel>`

View File

@ -7,6 +7,7 @@ parameter of the search classes.
\cgalHasModel `CGAL::Cartesian_d<FT>` \cgalHasModel `CGAL::Cartesian_d<FT>`
\cgalHasModel `CGAL::Homogeneous_d<RT>` \cgalHasModel `CGAL::Homogeneous_d<RT>`
\cgalHasModel `CGAL::Epick_d<DimensionTag>`
\cgalHasModel `CGAL::Search_traits_2<Kernel>` \cgalHasModel `CGAL::Search_traits_2<Kernel>`
\cgalHasModel `CGAL::Search_traits_3<Kernel>` \cgalHasModel `CGAL::Search_traits_3<Kernel>`
\cgalHasModel `CGAL::Search_traits_d<Kernel,Dim>` \cgalHasModel `CGAL::Search_traits_d<Kernel,Dim>`

View File

@ -105,6 +105,17 @@ public:
typename Base_traits::Cartesian_const_iterator_d operator()(const Point_with_info& p, int) const typename Base_traits::Cartesian_const_iterator_d operator()(const Point_with_info& p, int) const
{ return Base::operator() (get(ppmap,p),0); } { return Base::operator() (get(ppmap,p),0); }
// These 2 additional operators forward the call to Base_traits.
// This is needed because of an undocumented requirement of
// Orthogonal_k_neighbor_search and Orthogonal_incremental_neighbor_search:
// Traits::Construct_cartesian_const_iterator should be callable
// on the query point type
typename Base_traits::Cartesian_const_iterator_d operator()(const typename Base_traits::Point_d& p) const
{ return Base::operator() (p); }
typename Base_traits::Cartesian_const_iterator_d operator()(const typename Base_traits::Point_d& p, int) const
{ return Base::operator() (p,0); }
}; };
struct Construct_iso_box_d: public Base::Construct_iso_box_d{ struct Construct_iso_box_d: public Base::Construct_iso_box_d{

View File

@ -1,258 +1,3 @@
--------------------------------------------------
Problems to be solved from Sam's reading (september 2012)
--------------------------------------------------
*) Substitute iterator : it seems to be comparing the point directly, instead
of comparing the iterator. That look like a big performance killer.
*) I have marked with 'FIXME' all the lines where the code assumes, or seems to
assume that the vertex at infinity is at index 0 in the full cell. The code is
still working because the vertex at infinity is indeed at index 0, but this is
no more a requirement from the documentation, so that the code (Tr.h and
Delaunay_tr.h) should be changed. OR, we re-document 0 as the index of the
vertex at infinity.
ALL Remarks below are done or not important
--------------------------------------------------
Problems to be solved from the reviews (beginning 2012)
--------------------------------------------------
example delaunay does not execute properly
SAM: seems to be a compiler bug --> low priority.
OD: I am afraid that it is still some strange bug in the code that show up only in
some compilation circumstances.
running both delaunay compiled debug/release, the diverges after the 6th insertion (in 2d round)
in Triangulation_data_structure :
put a default value for dim in the constructor
(does not work, I do not understand why). OK done.
SAM: I've modified the Concept constructor's documentation to reflect this.
If it is not satisfying, we might remove this doc. from the Concept and
move it to the class documentation.
check that the perturbation scheme is independant of the order of insertion
SAM: It is your and Monique's scheme. It should be independent, which
is a requirement anyway for the Delaunay::remove() function to work
properly.
OD: seems ok, lexicographic order.
Add a template parameter Location_policy
ambient dim vs max dim
OD: global replace done, remains to get the dim from the traits (and not from the point of the traits)
check all is_valid function, precise in the doc what they are doing.
(do sth like 2/3 d)
SAM: I suggest that the documentation of the function in the concepts only
states that "any validity check can be performed here (see model doc. for
details)", and that we re document the same function in the class documentation
with details on what exactly is performed by the implementation.
OD: seems reasonable
SAM: I've changed my mind a little. We need some easy mandatory checks in
concepts T...DSFullCell and T...DSVertex so that we can rely on these tests in
the implementation of T.._data_structure, instead of having to re-implement them.
So : the concepts lists simple validity checks taht must be present, and refers
to the documentation of the models for possible additional validity checks
that are implemented.
--> This scheme is done (code&doc) for TDS TDSFullCell and TDSVertex and Triangulation.
--> ALL DONE.
small feature with iterator "all tuples"
make the code and doc agree on Flat_* stuff (orientation in a flat)
iterator on points in concept TriangulationVertex should be removed to keep requirements minimal
REMOVED: But this makes the concept TriangulationFullCell empty and useless.
make doc of TDS-FullCellStoragePolicy in user manual
DONE.
missing figures : Triangulation/fig/detail.png Triangulation/fig/illustration.png
--------------------------------------------------
Old todo list (beginning 2011)
--------------------------------------------------
Les premiers points meritent d'etre examinés
Je me replonge dans Triangulation en dim d
ma liste de trucs à faire ou questions à résoudre:
--- Constructeur de triangulation
prévoir un constructeur qui prends d+1 points en position générale
--- Doc 1.5 à faire
--- mirror_index
- policy a ajouter dans le user manual
- le code ne fait pas ce qui est dit dans la doc (ça ne retourne pas -1)
PS: Samuel tu as benché la policy ? ça vaut vraiment la peine de s'embeter avec ça ?
--- Face
- pourquoi une face ne pourrait pas être de pleine dimension ?
c'est pas la peine d'avoir un truc générique pour les faces de toutes dim sauf un
OD: J'ai propose de viré cette restriction dans la doc, mais il faudrait vérifier le code.
--- TriangulationTraits et DelaunayTraits
lower dimensional predicates
le truc de l'orientation "consistante"est quand même un peu délicat
- d'une part, je proposerai un truc du genre: le noyau doit fournir un iterateur
de points en position générale
(un truc fixe, ça donne toujours les mêmes points e.g. l'origine et les points
avec une coordonnée à 1 et les autres à 0).
Ce générateur permet donc de compléter tout ensemble de points pour obtenir
des points en position générale.
- d'autre part ???? il faut un minimum en plus pour qu'on comprenne que
l'orientation du sous-espace est stocké qq part.
--- TriangulationTraits has models
... il faut voir ce que l'on met vraiment.
--- Marque visité.
elle devrait etre dans le concept TDSFullCell
--------------------------------------------------
ci dessous les points ont deja etes traites
--- Index du sommet à l'infini.
Il est en ce moment prévu que le sommet à l'infini est l'index 0 dans les full
cell où il apparraît. Ça me semble très discutable, en particulier la tds ne sait
pas qui est à l'infini, et donc comment peut-elle garantir dans une manipulation
que toutes les cellules crées ou modifiées vont préserver cette position.
je suis donc pour virer ce truc ce qui implique des modifs dans la doc
(1.3 - ? p54) et dans le code.
en plus il y a des trucs pas cohérent, i.e. p. 50 dans la doc de locate
l'infini est en dernier, pas en premier.
finite_vertex_iterator marche pas
SAM: J'ai corrigé le problème, mais c'est pas super propre. Le problème
vient de boost::filter_iterator qui suppose que le prédicat de filtrage
prend en argument |const value_type &| plutôt que |iterator|. Mais
quand on veut tester si un sommet est infini, on a envie de comparer
les iterator (ou handle)... ce qui n'est pas possible avec le
filter_iterator de boost. (Le filter_iterator de CGAL appele le
prédicat de filtrage sur l'itérateur, et non pas sur la valeur vers
lequel il pointe, comme le fait boost. Mais je ne sais pas si le filtre
d'iterateur de CGAL est destiné à durer)
--- Orientation des cellules.
les cellules sont orientées positivement par convention
- le dire dans la doc (deux full cell partagent une facet, elles doivent avoir
des orientation complémentaires
- dans Triangulation, il faut virer la méthode "orientation"
(ou au minimum, la mettre advanced)
--- Triangulation is_infinite
j'avais viré les préconditions, et je maintiens.
en dim 0 on a une full cell finie et une infinie
en dim 1 on a 2 full cell infinie, 1 vertex/facet infini
et ok, en d=0, facet n'a pas de sens, mais l'utilisateur aura du mal a en avoir une
--- Triangulation fonctions incident_* et star
est-il nécessaire de reprendre leur doc? (on pourrait pointer sur celle de TDS)
au moins pour incident_upper_faces
--- dans Triangulation_data_structure.h insert_in_tagged_hole
on a l'air de supposer que full_cell(f) est marqué visité
(pourquoi ça serait pas l'autre représentation de la Facet f ?)
la doc de TDS::insert_in_hole est maintenant claire
Older todo list (2010 ?)
__________________________________________________________________________RENAMING
*) doc :
--------
*) code not done :
------------------
bring part of Delaunay::remove into TDS (see comments in Delaunay_triangulation.h, and item FUTURE below)
__________________________________________________________________________ALL
*) FUTURE: better system for simplex's flags to know if we can use them or not
in Delaunay_triangulation::remove(Vertex_handle)
_________________________________________________TRIANGULATION_DATA_STRUCTURE
*) Un-recursify insert_in_tagged_hole : crashed in dimension 8 : stack overflow.
*) TriangulationDataStructure:
- Should we put >> and << in the documentation of the class
Triangulation_data_structure ?
*) Triangulation_data_structure.h:
- Ensure that it is topologically possible to collapse the Face in
collapse_face(Face)
*) TriangulationDSVertex
- Should we put >> and << in the documentation of the class
Triangulation_ds_vertex instead of in that of the concept ?
*) TDSFullCellStoragePolicy
what is it ? => see the doc.
it is undocumented. => it is documented (Triangulation_ds_full_cell)
if the aim is to choose between "full representation" and "1-skeleton"
I would prefer a different TDS class, at least the doc has to rewriten a sentence
like "class TDS explicitely stores its vertices and full cells"
does not apply to 1-skeleton representation
=> no, this has nothing to do with 1-skeleton.
*) default dim parameter in constructor (especially in the static case)
done
________________________________________________________________TRIANGULATION
*) default dim parameter in constructor (especially in the static case)
done
*) Why vertex at infinity should have index 0 in all cells it appears ?
This is a convention that is enforced throughout the code. Makes it faster
to check for an infinite cell.
The "old" package "Convex_hull_d" does the same.
done
_______________________________________________________DELAUNAY_TRIANGULATION
________________________________________________________REGULAR_TRIANGULATION
*) write Regular_triangulation.h (!)
*) write RegularTriangulationTraits.tex
*) write Regular_triangulation.tex
------------------------------------------------------- -------------------------------------------------------
RANDOM DESIGN IDEAS extracted from Convex_hull.h RANDOM DESIGN IDEAS extracted from Convex_hull.h
------------------------------------------------------- -------------------------------------------------------
@ -263,4 +8,3 @@ ________________________________________________________REGULAR_TRIANGULATION
In this second case, we must keeps the points that are inserted in the hull, In this second case, we must keeps the points that are inserted in the hull,
as they may become part of the boundary later on, when some points are removed. as they may become part of the boundary later on, when some points are removed.
- Constructor with range argument uses quickhull. - Constructor with range argument uses quickhull.
*/

View File

@ -0,0 +1,69 @@
# Created by the script cgal_create_cmake_script_with_options
# This is the CMake script for compiling a set of CGAL applications.
project( Triangulation_apps )
cmake_minimum_required(VERSION 2.6.2)
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 2.6)
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3)
cmake_policy(VERSION 2.8.4)
else()
cmake_policy(VERSION 2.6)
endif()
endif()
set( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true )
if ( COMMAND cmake_policy )
cmake_policy( SET CMP0003 NEW )
endif()
# CGAL and its components
find_package( CGAL QUIET COMPONENTS )
if ( NOT CGAL_FOUND )
message(STATUS "This project requires the CGAL library, and will not be compiled.")
return()
endif()
# include helper file
include( ${CGAL_USE_FILE} )
# Boost and its components
find_package( Boost REQUIRED )
if ( NOT Boost_FOUND )
message(STATUS "This project requires the Boost library, and will not be compiled.")
return()
endif()
find_package(Eigen3 3.1.0)
if (EIGEN3_FOUND)
include( ${EIGEN3_USE_FILE} )
endif()
# include for local directory
include_directories( BEFORE include )
# include for local package
include_directories( BEFORE ../../include )
# Creating entries for all .cpp/.C files with "main" routine
# ##########################################################
include( CGAL_CreateSingleSourceCGALProgram )
create_single_source_cgal_program( "points_to_RT_to_off.cpp" )
create_single_source_cgal_program( "points_to_DT_to_off.cpp" )

View File

@ -0,0 +1,11 @@
2
0.0071 1.6899 0
0.3272 1.3694 0.05
1.3697 1.8296 0.1
0.6722 0.3012 0.15
1.1726 0.1899 0.2
0.4374 2.8541 100.25
2.5923 0.1904 0.3
1.3083 2.5462 200.35
1.4981 1.3929 0.4
2.1304 2.055 0.45

View File

@ -0,0 +1,20 @@
2
0 0 6.28953
-2.85086 -0.471442 6.12896
1.90972 0.101219 0.988689
0.637771 2.59367 5.80372
2.22209 0.903198 2.19478
-0.487202 -2.71506 4.90996
1.1193 -1.91787 2.99626
1.54714 0.109831 0
0.44556 -2.73047 4.48142
0.427936 1.28495 6.23624
-2.67212 0.766674 5.29623
1.5763 -1.59828 2.58905
-0.476603 2.2546 6.04797
1.57172 -0.514711 6.11405
1.84528 2.10139 5.53936
-2.99827 -0.101677 5.92246
-0.482122 -2.39584 4.44264
-2.25558 -1.492 6.23448
0.128475 -1.75125 3.18916

View File

@ -0,0 +1,11 @@
3
0.0071 1.6899 2.521 0
0.3272 1.3694 3.15 0.05
1.3697 1.8296 2.654 0.1
-10.6722 0.3012 0.1548 1000.15
1.1726 0.1899 0.3658 0.2
0.4374 20.8541 1.45894 2000.25
2.5923 0.1904 0.6971 0.3
10.3083 2.5462 1.3658 1000.35
1.4981 1.3929 2.949 0.4
2.1304 2.055 0.6597455 1.45

View File

@ -0,0 +1,11 @@
3
0.0071 1.6899 2.521 0
0.3272 1.3694 3.15 0
1.3697 1.8296 2.654 0
-10.6722 0.3012 0.1548 0
1.1726 0.1899 0.3658 0
0.4374 20.8541 1.45894 0
2.5923 0.1904 0.6971 0
10.3083 2.5462 1.3658 0
1.4981 1.3929 2.949 0
2.1304 2.055 0.6597455 0

View File

@ -0,0 +1,11 @@
3
0.0071 1.6899 2.521 0
0.3272 1.3694 3.15 0.05
1.3697 1.8296 2.654 0.1
-10.6722 0.3012 0.1548 1000.15
1.1726 0.1899 0.3658 0.2
0.4374 20.8541 1.45894 2000.25
2.5923 0.1904 0.6971 0.3
10.3083 2.5462 1.3658 1000.35
1.4981 1.3929 2.949 0.4
2.1304 2.055 0.6597455 1.45

View File

@ -0,0 +1,42 @@
#include <CGAL/Epick_d.h>
#include <CGAL/Delaunay_triangulation.h>
#include <CGAL/IO/Triangulation_off_ostream.h>
#include <fstream>
typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K;
typedef CGAL::Delaunay_triangulation<K> DT;
void test(int dim)
{
std::stringstream input_filename;
input_filename << "data/points_" << dim << ".cin";
std::ifstream in(input_filename.str());
DT::Point p;
std::vector<DT::Point> points;
int dim_from_file;
in >> dim_from_file;
while(in >> p)
points.push_back(p);
// Build the Regular Triangulation
DT dt(dim_from_file);
dt.insert(points.begin(), points.end());
CGAL_assertion(dt.is_valid(true));
// Export
std::stringstream output_filename;
output_filename << "data/dt_dim" << dim << ".off";
std::ofstream off_stream(output_filename.str());
CGAL::export_triangulation_to_off(off_stream, dt);
}
int main()
{
//test(2);
//test(3);
test(10);
return 0;
}

View File

@ -0,0 +1,41 @@
#include <CGAL/Epick_d.h>
#include <CGAL/Regular_triangulation.h>
#include <CGAL/IO/Triangulation_off_ostream.h>
#include <fstream>
typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K;
typedef CGAL::Regular_triangulation<K> RT;
void test(int dim)
{
std::stringstream input_filename;
input_filename << "data/points_" << dim << ".cin";
std::ifstream in(input_filename.str());
RT::Weighted_point wp;
std::vector<RT::Weighted_point> wpoints;
int dim_from_file;
in >> dim_from_file;
while(in >> wp)
wpoints.push_back(wp);
// Build the Regular Triangulation
RT rt(dim_from_file);
rt.insert(wpoints.begin(), wpoints.end());
CGAL_assertion(rt.is_valid(true));
// Export
std::stringstream output_filename;
output_filename << "data/rt_dim" << dim << ".off";
std::ofstream off_stream(output_filename.str());
CGAL::export_triangulation_to_off(off_stream, rt);
}
int main()
{
test(2);
test(3);
return 0;
}

View File

@ -21,6 +21,7 @@ if ( CGAL_FOUND )
include_directories (BEFORE "../../include") include_directories (BEFORE "../../include")
include_directories (BEFORE "include") include_directories (BEFORE "include")
create_single_source_cgal_program( "delaunay.cpp" ) create_single_source_cgal_program( "delaunay.cpp" )
create_single_source_cgal_program( "Td_vs_T2_and_T3.cpp" )
else() else()
message(STATUS "NOTICE: Some of the executables in this directory need Eigen 3.1 (or greater) and will not be compiled.") message(STATUS "NOTICE: Some of the executables in this directory need Eigen 3.1 (or greater) and will not be compiled.")

View File

@ -0,0 +1,267 @@
// To deactivate statics filters in the 2D/3D case
//#define CGAL_NO_STATIC_FILTERS
#include <CGAL/Epick_d.h>
#include <CGAL/Delaunay_triangulation.h>
#include <CGAL/Regular_triangulation.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Regular_triangulation_euclidean_traits_2.h>
#include <CGAL/Regular_triangulation_filtered_traits_2.h>
#include <CGAL/Regular_triangulation_euclidean_traits_3.h>
#include <CGAL/Regular_triangulation_filtered_traits_3.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/Delaunay_triangulation_3.h>
#include <CGAL/Regular_triangulation_2.h>
#include <CGAL/Regular_triangulation_3.h>
#include <CGAL/point_generators_2.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/point_generators_d.h>
#include <CGAL/Timer.h>
#include <CGAL/algorithm.h>
#include <vector>
#include <string>
#include "console_color.h"
template <typename DT_>
struct Stats_getter;
// T2 specialization
template <typename K>
struct Stats_getter<CGAL::Delaunay_triangulation_2<K> >
{
typedef CGAL::Delaunay_triangulation_2<K> DT;
Stats_getter(DT const& dt) : m_dt(dt) {}
std::size_t number_of_vertices() { return m_dt.number_of_vertices(); }
std::size_t number_of_finite_cells() { return m_dt.number_of_faces(); }
DT m_dt;
};
// RT2 specialization
template <typename K>
struct Stats_getter<CGAL::Regular_triangulation_2<K> >
{
typedef CGAL::Regular_triangulation_2<K> DT;
Stats_getter(DT const& dt) : m_dt(dt) {}
std::size_t number_of_vertices() { return m_dt.number_of_vertices(); }
std::size_t number_of_finite_cells() { return m_dt.number_of_faces(); }
DT m_dt;
};
// T3 specialization
template <typename K>
struct Stats_getter<CGAL::Delaunay_triangulation_3<K> >
{
typedef CGAL::Delaunay_triangulation_3<K> DT;
Stats_getter(DT const& dt) : m_dt(dt) {}
std::size_t number_of_vertices() { return m_dt.number_of_vertices(); }
std::size_t number_of_finite_cells() { return m_dt.number_of_finite_cells(); }
DT m_dt;
};
// RT3 specialization
template <typename K>
struct Stats_getter<CGAL::Regular_triangulation_3<K> >
{
typedef CGAL::Regular_triangulation_3<K> DT;
Stats_getter(DT const& dt) : m_dt(dt) {}
std::size_t number_of_vertices() { return m_dt.number_of_vertices(); }
std::size_t number_of_finite_cells() { return m_dt.number_of_finite_cells(); }
DT m_dt;
};
template<typename DT_d, typename DT_23,
typename Pt_d_range, typename Pt_23_range>
void test(
int d, int N, Pt_d_range const& points_d, Pt_23_range const& points_23,
std::string const& DTd_static_or_dyn)
{
// Td
{
DT_d dt(d);
CGAL::Timer timer;
timer.start();
dt.insert(points_d.begin(), points_d.end());
std::cerr << " * Td: " << yellow << timer.time() << " s"
<< white << std::endl;
std::cerr << " " << dt.number_of_vertices() << " vertices, "
<< dt.number_of_finite_full_cells() << " finite cells."
<< std::endl;
}
// T2 or T3
{
CGAL::Timer timer;
timer.start();
DT_23 dt;
dt.insert(points_23.begin(), points_23.end());
std::cerr << " * T" << d << ": " << yellow << timer.time() << " s"
<< white << std::endl;
Stats_getter<DT_23> sg(dt);
std::cerr << " " << sg.number_of_vertices() << " vertices, "
<< sg.number_of_finite_cells() << " finite cells."
<< std::endl;
}
}
template< int D, typename Dim_tag >
void go(const int N)
{
CGAL_assertion(D == 2 || D == 3);
// Generate points (in a common "array" format)
std::vector<CGAL::cpp11::array<double, D> > coords;
coords.reserve(N);
for (int i = 0; i < N; ++i)
{
CGAL::cpp11::array<double, D> pt;
for (int j = 0; j < D; ++j)
pt[j] = CGAL::default_random.get_double(-1., 1.);
coords.push_back(pt);
}
// Generate weights
std::vector<double> weights;
weights.reserve(N);
for (int i = 0; i < N; ++i)
weights.push_back(CGAL::default_random.get_double(-10., 10.));
// DTd
typedef CGAL::Epick_d<Dim_tag> Kd;
typedef CGAL::Delaunay_triangulation<Kd> DT_d;
typedef typename DT_d::Point Point_d;
std::vector<Point_d> points_d;
points_d.reserve(N);
for (int i = 0; i < N; ++i)
points_d.push_back(Point_d(D, coords[i].begin(), coords[i].end()));
// RTd
typedef CGAL::Regular_triangulation<Kd> RT_d;
typedef typename RT_d::Bare_point Bare_point_d;
typedef typename RT_d::Point WPoint_d;
std::vector<WPoint_d> wpoints_d;
wpoints_d.reserve(N);
for (int i = 0; i < N; ++i)
{
wpoints_d.push_back(WPoint_d(
Bare_point_d(D, coords[i].begin(), coords[i].end()),
weights[i]));
}
// T2 or T3
typedef CGAL::Exact_predicates_inexact_constructions_kernel K23;
if (D == 2)
{
// Delaunay
typedef CGAL::Delaunay_triangulation_2<K23> DT_2;
typedef typename DT_2::Point Point;
std::vector<Point> points;
points.reserve(N);
for (int i = 0; i < N; ++i)
points.push_back(Point(coords[i][0], coords[i][1]));
std::cerr << std::endl << "DELAUNAY - dim " << D << " - "
<< N << " points." << std::endl;
test<DT_d, DT_2>(D, N, points_d, points, "static");
// Regular
typedef CGAL::Regular_triangulation_filtered_traits_2<K23> Traits_2;
typedef CGAL::Regular_triangulation_2<Traits_2> RT_2;
typedef typename RT_2::Bare_point Bare_point;
typedef typename RT_2::Point WPoint;
std::vector<WPoint> wpoints;
wpoints.reserve(N);
for (int i = 0; i < N; ++i)
{
wpoints.push_back(WPoint(
Bare_point(coords[i][0], coords[i][1]),
weights[i]));
}
std::cerr << std::endl << "REGULAR - dim " << D << " - "
<< N << " points." << std::endl;
test<RT_d, RT_2>(D, N, wpoints_d, wpoints, "static");
}
else if (D == 3)
{
typedef CGAL::Delaunay_triangulation_3<K23> DT_3;
typedef typename DT_3::Point Point;
std::vector<Point> points;
points.reserve(N);
for (int i = 0; i < N; ++i)
points.push_back(Point(coords[i][0], coords[i][1], coords[i][2]));
std::cerr << std::endl << "DELAUNAY - dim " << D << " - "
<< N << " points." << std::endl;
test<DT_d, DT_3>(D, N, points_d, points, "static");
// Regular
typedef CGAL::Regular_triangulation_filtered_traits_3<K23> Traits_3;
typedef CGAL::Regular_triangulation_3<Traits_3> RT_3;
typedef typename RT_3::Bare_point Bare_point;
typedef typename RT_3::Point WPoint;
std::vector<WPoint> wpoints;
wpoints.reserve(N);
for (int i = 0; i < N; ++i)
{
wpoints.push_back(WPoint(
Bare_point(coords[i][0], coords[i][1], coords[i][2]),
weights[i]));
}
std::cerr << std::endl << "REGULAR - dim " << D << " - "
<< N << " points." << std::endl;
test<RT_d, RT_3>(D, N, wpoints_d, wpoints, "static");
}
}
int main(int argc, char **argv)
{
srand(static_cast<unsigned int>(time(NULL)));
#ifdef _DEBUG
int N = 100;
#else
int N = 100000;
#endif
if (argc > 1) N = atoi(argv[1]);
std::cerr << "-----------------------------------------" << std::endl;
std::cerr << "-- STATIC --" << std::endl;
std::cerr << "-----------------------------------------" << std::endl;
go<2, CGAL::Dimension_tag<2> >(N);
go<3, CGAL::Dimension_tag<3> >(N);
std::cerr << std::endl;
std::cerr << "-----------------------------------------" << std::endl;
std::cerr << "-- DYNAMIC --" << std::endl;
std::cerr << "-----------------------------------------" << std::endl;
go<2, CGAL::Dynamic_dimension_tag>(N);
go<3, CGAL::Dynamic_dimension_tag>(N);
std::cerr << std::endl;
return 0;
}

View File

@ -0,0 +1,68 @@
#ifndef CONSOLE_COLOR_H_
#define CONSOLE_COLOR_H_
#include <iostream>
#if defined(WIN32)
#include <windows.h>
#endif
inline std::ostream& blue(std::ostream &s)
{
#if defined(WIN32)
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,
FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY);
#else
s << "\x1b[0;34m";
#endif
return s;
}
inline std::ostream& red(std::ostream &s)
{
#if defined(WIN32)
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout, FOREGROUND_RED|FOREGROUND_INTENSITY);
#else
s << "\x1b[0;31m";
#endif
return s;
}
inline std::ostream& green(std::ostream &s)
{
#if defined(WIN32)
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout, FOREGROUND_GREEN|FOREGROUND_INTENSITY);
#else
s << "\x1b[0;32m";
#endif
return s;
}
inline std::ostream& yellow(std::ostream &s)
{
#if defined(WIN32)
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,
FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY);
#else
s << "\x1b[0;33m";
#endif
return s;
}
inline std::ostream& white(std::ostream &s)
{
#if defined(WIN32)
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,
FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
#else
s << "\x1b[0;37m";
#endif
return s;
}
#endif

View File

@ -1,70 +1,128 @@
#include <CGAL/Epick_d.h> #include <CGAL/Epick_d.h>
#include <CGAL/Delaunay_triangulation.h> #include <CGAL/Delaunay_triangulation.h>
#include <CGAL/IO/Triangulation_off_ostream.h>
#include <CGAL/point_generators_d.h> #include <CGAL/point_generators_d.h>
#include <CGAL/Timer.h> #include <CGAL/Timer.h>
#include <CGAL/algorithm.h> #include <CGAL/algorithm.h>
#include <CGAL/Memory_sizer.h>
#include <vector> #include <vector>
#include <string> #include <string>
#include <fstream> #include <fstream>
#include <cstdlib> #include <cstdlib>
#include <algorithm> #include <algorithm>
//#define USE_DYNAMIC_KERNEL
#define OUTPUT_STATS_IN_CSV
//#define EXPORT_POINTS_TO_A_FILE
template<typename DT> #ifdef OUTPUT_STATS_IN_CSV
void test(const int d, const std::string & type, const int N) static std::ofstream csv_file("stats.csv");
#endif
// Return the number of Bytes used
template<int D>
std::size_t compute_triangulation(std::size_t N)
{ {
typedef typename DT::Vertex Vertex; #ifdef USE_DYNAMIC_KERNEL
typedef typename DT::Vertex_handle Vertex_handle; typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K;
typedef typename DT::Full_cell Full_cell; #else
typedef typename DT::Full_cell_handle Full_cell_handle; typedef CGAL::Epick_d<CGAL::Dimension_tag<D> > K;
typedef typename DT::Facet Facet; #endif
typedef typename DT::Point Point; typedef CGAL::Delaunay_triangulation<K> DT;
typedef typename DT::Geom_traits::RT RT;
typedef typename DT::Finite_full_cell_const_iterator Finite_full_cell_const_iterator;
typedef CGAL::Random_points_in_cube_d<Point> Random_points_iterator; typedef typename DT::Vertex Vertex;
CGAL::Timer cost; // timer typedef typename DT::Vertex_handle Vertex_handle;
typedef typename DT::Full_cell Full_cell;
typedef typename DT::Full_cell_handle Full_cell_handle;
typedef typename DT::Facet Facet;
typedef typename DT::Point Point;
typedef typename DT::Geom_traits::RT RT;
typedef typename DT::Finite_full_cell_const_iterator Finite_full_cell_const_iterator;
DT dt(d); typedef CGAL::Random_points_in_cube_d<Point> Random_points_iterator;
assert(dt.empty()); CGAL::Timer cost; // timer
std::vector<Point> points; // Generate points
CGAL::Random rng; std::vector<Point> points;
Random_points_iterator rand_it(d, 2.0, rng); CGAL::Random rng;
CGAL::cpp11::copy_n(rand_it, N, std::back_inserter(points)); Random_points_iterator rand_it(D, 2.0, rng);
cost.reset();cost.start(); CGAL::cpp11::copy_n(rand_it, N, std::back_inserter(points));
std::cout << " Delaunay triangulation of "<<N<<" points in dim "<<d<< std::flush;
dt.insert(points.begin(), points.end()); #ifdef EXPORT_POINTS_TO_A_FILE
std::cout << " done in "<<cost.time()<<" seconds." << std::endl; std::ofstream os("points.txt");
std::size_t nbfc= dt.number_of_finite_full_cells(); for (auto const& p : points)
std::size_t nbc= dt.number_of_full_cells(); {
std::cout << dt.number_of_vertices() << " vertices, " CGAL::Triangulation_IO::output_point(os, K(), p);
<< nbfc << " finite simplices and " os << std::endl;
<< (nbc-nbfc) << " convex hull Facets." }
<< std::endl; #endif
std::size_t mem_before = CGAL::Memory_sizer().virtual_size();
cost.reset();
cost.start();
std::cout << "Delaunay triangulation of " << N <<
" points in dim " << D << ":" << std::endl;
DT dt(D);
dt.insert(points.begin(), points.end());
std::size_t mem = CGAL::Memory_sizer().virtual_size() - mem_before;
double timing = cost.time();
std::cout << " Done in " << timing << " seconds." << std::endl;
std::cout << " Memory consumption: " << (mem >> 10) << " KB.\n";
std::size_t nbfc= dt.number_of_finite_full_cells();
std::size_t nbc= dt.number_of_full_cells();
std::cout << " " << dt.number_of_vertices() << " vertices, "
<< nbfc << " finite simplices and "
<< (nbc-nbfc) << " convex hull Facets."
<< std::endl;
#ifdef OUTPUT_STATS_IN_CSV
csv_file
<< D << ";"
<< N << ";"
<< timing << ";"
<< mem << ";"
<< nbfc << "\n"
<< std::flush;
#endif
return mem;
} }
template< int D > // Will compute triangulations of i*num_points_steps points,
void go(const int N) // with i in [1, 2...], stopping after the last computation that takes
// more memory than mem_threshold_in_bytes
template<int D>
void go(
std::size_t num_points_increment,
std::size_t mem_threshold_in_MB = (3 << 10)) // 3 GB
{ {
typedef CGAL::Epick_d<CGAL::Dimension_tag<D> > K; std::size_t mem = 0;
//typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K; for (std::size_t i = 1 ; mem < (mem_threshold_in_MB << 20) ; ++i)
typedef CGAL::Delaunay_triangulation<K> Triangulation; {
test<Triangulation>(D, "static", N); mem = compute_triangulation<D>(i*num_points_increment);
}
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
srand(static_cast<unsigned int>(time(NULL))); srand(static_cast<unsigned int>(time(NULL)));
int N = 100; if( argc > 1 ) N = atoi(argv[1]); //int N = 100; if( argc > 1 ) N = atoi(argv[1]);
go<2>(N); go<2>(5000000);
go<3>(N); //go<3>(1000000);
go<4>(N); //go<4>(300000);
go<5>(N); //go<5>(50000);
go<6>(N); //go<6>(5000);
go<7>(N); //go<7>(1000);
go<8>(N); //go<8>(300);
//go<9>(100);
//go<10>(30);
//go<11>(20);
//go<12>(15);
return 0;
return 0;
} }

View File

@ -7,7 +7,7 @@ namespace CGAL {
This class is used to maintain the This class is used to maintain the
Delaunay triangulation of a set of points in \f$ \mathbb{R}^D \f$. Delaunay triangulation of a set of points in \f$ \mathbb{R}^D \f$.
It permits point insertion and It permits point insertion and
removal. The dimension \f$ D\f$ can be specified at compile-time or removal. The maximal dimension \f$ D\f$ can be specified at compile-time or
run-time. It should be kept reasonably small, run-time. It should be kept reasonably small,
see the performance section in the user manual for what reasonable see the performance section in the user manual for what reasonable
means. means.
@ -20,35 +20,32 @@ A <I>circumscribing ball</I> of a simplex is a ball
having all vertices of the simplex on its boundary. having all vertices of the simplex on its boundary.
\tparam DelaunayTriangulationTraits is the geometric traits class that provides the geometric types \tparam DelaunayTriangulationTraits_ is the geometric traits class that provides the geometric types
and predicates needed by Delaunay triangulations. `DelaunayTriangulationTraits` must be a model of and predicates needed by Delaunay triangulations. `DelaunayTriangulationTraits_` must be a model of
the concept `DelaunayTriangulationTraits`. the concept `DelaunayTriangulationTraits`.
\tparam TriangulationDataStructure must be a model of the concept \tparam TriangulationDataStructure_ must be a model of the concept
`TriangulationDataStructure`. This model is used to store `TriangulationDataStructure`. This model is used to store
the faces of the triangulation. The parameter `TriangulationDataStructure` defaults to the faces of the triangulation. The parameter `TriangulationDataStructure_` defaults to
`Triangulation_data_structure` whose template parameters are instantiated as `Triangulation_data_structure` whose template parameters are instantiated as
follows: follows:
<UL> <UL>
<LI>`DelaunayTriangulationTraits::Dimension`</LI> <LI>`DelaunayTriangulationTraits_::Dimension`</LI>
<LI>`Triangulation_vertex<DelaunayTriangulationTraits>`</LI> <LI>`Triangulation_vertex<DelaunayTriangulationTraits_>`</LI>
<LI>`Triangulation_full_cell<DelaunayTriangulationTraits>`.</LI> <LI>`Triangulation_full_cell<DelaunayTriangulationTraits_>`.</LI>
</UL> </UL>
The class template `Delaunay_triangulation` can \tparam Delaunay_triangulation can
be defined by specifying only the first parameter, or by using the be defined by specifying only the first parameter, or by using the
tag `CGAL::Default` as the second parameter. tag `CGAL::Default` as the second parameter.
The class `Delaunay_triangulation<DelaunayTriangulationTraits, TriangulationDataStructure>` inherits all the types \sa `Regular_triangulation`
defined in the base class `Triangulation<DelaunayTriangulationTraits, TriangulationDataStructure>`. Additionally, it \sa `Triangulation_data_structure`
defines or overloads the following methods:
\sa `Triangulation_data_structure<Dimensionality, TriangulationDSVertex, TriangulationDSFullCell>`
*/ */
template< typename DelaunayTriangulationTraits, typename TriangulationDataStructure > template< typename DelaunayTriangulationTraits_, typename TriangulationDataStructure_ >
class Delaunay_triangulation class Delaunay_triangulation
: public Triangulation<DelaunayTriangulationTraits, TriangulationDataStructure> : public Triangulation<DelaunayTriangulationTraits_, TriangulationDataStructure_>
{ {
public: public:
@ -62,7 +59,7 @@ at infinity). See the description of the inherited nested type
the use of the parameter `dim`. The complex stores a copy of the geometric the use of the parameter `dim`. The complex stores a copy of the geometric
traits `gt`. traits `gt`.
*/ */
Delaunay_triangulation(const int dim, const Geom_traits gt = Geom_traits()); Delaunay_triangulation(int dim, const Geom_traits &gt = Geom_traits());
/// @} /// @}
@ -118,7 +115,6 @@ Same as above but uses a vertex as starting place for the search.
Vertex_handle insert(const Point & p, Vertex_handle hint); Vertex_handle insert(const Point & p, Vertex_handle hint);
/*! /*!
\cgalAdvancedBegin
Inserts the point `p` in the Delaunay triangulation Inserts the point `p` in the Delaunay triangulation
and ensures that the empty-ball property is preserved. and ensures that the empty-ball property is preserved.
Returns a handle to the Returns a handle to the
@ -128,44 +124,19 @@ value of `lt`:
<DL> <DL>
<DT><B>`OUTSIDE_AFFINE_HULL`</B><DD> Point <DT><B>`OUTSIDE_AFFINE_HULL`</B><DD> Point
`p` is inserted so as to increase the current dimension of the Delaunay `p` is inserted so as to increase the current dimension of the Delaunay
triangulation. The method `dt`.`insert_outside_affine_hull()` is called. triangulation.
<DT><B>`ON_VERTEX`</B><DD> The position of the vertex `v` described by `f` <DT><B>`ON_VERTEX`</B><DD> The position of the vertex `v` described by `f`
is set to `p`. `v` is returned. <DT><B>Anything else</B><DD> The point `p` is set to `p`. `v` is returned. <DT><B>Anything else</B><DD> The point `p`
is inserted. the full cell `c` <I>is assumed</I> to be in conflict is inserted. the full cell `c` <I>is assumed</I> to be in conflict
with `p`. with `p`.
(Roughly speaking, the method `dt`.`insert_in_conflicting_cell()`
is called.)
</DL> </DL>
The parameters `lt`, `f`, `ft` The parameters `lt`, `f`, `ft`
and `c` must be consistent with the localization of point `p` in the and `c` must be consistent with the localization of point `p` in the
Delaunay triangulation e.g. by a call to Delaunay triangulation e.g. by a call to
`c = locate(p, lt, f, ft)`. `Triangulation::locate(const Point &, Locate_type &, Face &, Vertex_handle) const`.
\cgalAdvancedEnd
*/ */
Vertex_handle insert(const Point & p, const Locate_type lt, Vertex_handle insert(const Point & p, Locate_type lt,
const Face & f, const Facet & ft, const Full_cell_handle c); const Face & f, const Facet & ft, Full_cell_handle c);
/*!
\cgalAdvancedBegin
Inserts the point `p` in the Delaunay triangulation. Returns a handle to the
(possibly newly created) vertex at that position.
\pre The point `p`
must lie outside the affine hull of the Delaunay triangulation. This implies that
`dt`.`current_dimension()` must be less that
`dt`.`maximal_dimension()`.
\cgalAdvancedEnd
*/
Vertex_handle insert_outside_affine_hull(const Point & p);
/*!
\cgalAdvancedBegin
Inserts the point `p` in the Delaunay triangulation. Returns a handle to the
(possibly newly created) vertex at that position.
\pre The point `p` must be in conflict with the full cell `c`.
\cgalAdvancedEnd
*/
Vertex_handle insert_in_conflicting_cell(const Point & p, const
Full_cell_handle c);
/// @} /// @}
@ -177,25 +148,20 @@ Returns `true` if and only if the point `p` is in (Delaunay)
conflict with full cell `c` (i.e., the circumscribing ball of conflict with full cell `c` (i.e., the circumscribing ball of
\f$ c\f$ contains \f$ p\f$ in its interior). \f$ c\f$ contains \f$ p\f$ in its interior).
*/ */
bool is_in_conflict(const Point & p, Full_cell_const_handle c) bool is_in_conflict(const Point & p, Full_cell_const_handle c) const;
const;
/*! /*!
\cgalAdvancedBegin Outputs handles to the full cells in conflict with
Outputs handles to the full cells in confict with
point `p` into the `OutputIterator out`. The full cell `c` is used point `p` into the `OutputIterator out`. The full cell `c` is used
as a starting point for gathering the full cells in conflict with as a starting point for gathering the full cells in conflict with
`p`. `p`.
A facet `(cc,i)` on the boundary of the conflict zone with A facet `(cc,i)` on the boundary of the conflict zone with
`cc` in conflict is returned. `cc` in conflict is returned.
\pre `c` is in conflict \pre `c` is in conflict with `p` and `dt`.`current_dimension()`\f$ \geq2\f$.
with `p`.
`dt`.`current_dimension()`\f$ \geq2\f$.
\cgalAdvancedEnd
*/ */
template< typename OutputIterator > template< typename OutputIterator >
Facet compute_conflict_zone(const Point & p, const Full_cell_handle c, Facet compute_conflict_zone(const Point & p, Full_cell_handle c,
OutputIterator out) const; OutputIterator out) const;
/// @} /// @}

View File

@ -0,0 +1,171 @@
namespace CGAL {
/*!
\ingroup PkgTriangulationsTriangulationClasses
This class is used to maintain the
regular triangulation -- also known as weighted Delaunay triangulation --
of a set of weighted points in \f$ \mathbb{R}^D \f$.
The maximal dimension \f$ D\f$ can be specified at compile-time or
run-time. It should be kept reasonably small -- see the performance
section in the user manual for what reasonable means.
\warning The removal of points is not supported yet.
\tparam RegularTriangulationTraits_ is the geometric traits class that provides the
geometric types and predicates needed by regular triangulations.
`RegularTriangulationTraits_` must be a model of the concept
`RegularTriangulationTraits`.
\tparam TriangulationDataStructure_ must be a model of the concept
`TriangulationDataStructure`. This model is used to store
the faces of the triangulation. The parameter `TriangulationDataStructure_`
defaults to `Triangulation_data_structure` whose template parameters are
instantiated as follows:
<UL>
<LI>`RegularTriangulationTraits_::Dimension`</LI>
<LI>`Triangulation_vertex<CGAL::Regular_triangulation_traits_adapter<RegularTriangulationTraits_> >`</LI>
<LI>`Triangulation_full_cell<CGAL::Regular_triangulation_traits_adapter<RegularTriangulationTraits_> >`.</LI>
</UL>
`Regular_triangulation` can
be defined by specifying only the first parameter, or by using the
tag `CGAL::Default` as the second parameter.
\sa `Delaunay_triangulation`
\sa `Triangulation_data_structure`
\sa `Regular_triangulation_traits_adapter`
*/
template< typename RegularTriangulationTraits_, typename TriangulationDataStructure_ >
class Regular_triangulation
: public Triangulation<Regular_triangulation_traits_adapter<RegularTriangulationTraits_>, TriangulationDataStructure_>
{
public:
/// \name Types
/// @{
/*!
A point in Euclidean space with an associated weight.
*/
typedef RegularTriangulationTraits_::Weighted_point_d Weighted_point;
/// @}
/// \name Creation
/// @{
/*!
Instantiates a regular triangulation with one vertex (the vertex
at infinity). See the description of the inherited nested type
`Triangulation::Maximal_dimension` for an explanation of
the use of the parameter `dim`. The triangulation stores a copy of the
geometric traits `gt`.
*/
Regular_triangulation(int dim, const Geom_traits &gt = Geom_traits());
/// @}
/// \name Point Insertion
/// @{
/*!
Inserts weighted point `p` in the triangulation and returns the corresponding
vertex.
If this insertion creates a vertex, this vertex is returned.
If `p` coincides with an existing vertex and has a greater weight,
then the existing weighted point becomes hidden and `p` replaces it as vertex
of the triangulation.
If `p` coincides with an already existing vertex (both point and
weights being equal), then this vertex is returned and the triangulation
remains unchanged.
Otherwise if `p` does not appear as a vertex of the triangulation,
then it is stored as a hidden point and this method returns the default
constructed handle.
Prior to the actual insertion, `p` is located in the triangulation;
`hint` is used as a starting place for locating `p`.
*/
Vertex_handle insert(const Weighted_point & p, Full_cell_handle hint
= Full_cell_handle());
/*!
Same as above but uses a vertex as starting place for the search.
*/
Vertex_handle insert(const Weighted_point & p, Vertex_handle hint);
/*!
Inserts weighted point `p` in the triangulation.
Similar to the above `insert()` function, but takes as additional
parameter the return values of a previous location query. See description of
`Triangulation::locate()`.
*/
Vertex_handle insert(const Weighted_point & p, Locate_type lt,
const Face & f, const Facet & ft, Full_cell_handle c);
/*!
Inserts the weighted points found in range `[s,e)` in the regular triangulation.
Returns the difference between the number of vertices after and before
the insertions (it may be negative due to hidden points).
Note that this function is not guaranteed to insert the points
following the order of `ForwardIterator` because `spatial_sort()`
is used to improve efficiency.
\tparam ForwardIterator must be an input iterator with the value
type `Weighted_point`.
*/
template< typename ForwardIterator >
std::ptrdiff_t insert(ForwardIterator s, ForwardIterator e);
/// @}
/// \name Queries
/// @{
/*!
Returns `true` if and only if the point `p` is in
conflict with full cell `c` (A weighted point `p` is said to be in conflict
with a cell `c` if it has a negative power distance to the power sphere of `c`.)
*/
bool is_in_conflict(const Weighted_point & p, Full_cell_const_handle c)
const;
/*!
Outputs handles to the full cells in conflict with
point `p` into the `OutputIterator out`. The full cell `c` is used
as a starting point for gathering the full cells in conflict with
`p`.
A facet `(cc,i)` on the boundary of the conflict zone with
`cc` in conflict is returned.
\pre `c` is in conflict with `p` and `rt`.`current_dimension()`\f$ \geq 1\f$.
*/
template< typename OutputIterator >
Facet compute_conflict_zone(const Weighted_point & p, Full_cell_handle c,
OutputIterator out) const;
/// @}
/// \name Access Functions
/// @{
/*!
Returns the number of finite vertices that are not hidden.
*/
size_type number_of_vertices() const;
/*!
Returns the number of hidden vertices.
*/
size_type number_of_hidden_vertices() const;
/// @}
}; /* end regular_triangulation */
} /* end namespace CGAL */

View File

@ -0,0 +1,62 @@
namespace CGAL {
/*!
\ingroup PkgTriangulationsTraitsClasses
The class `Regular_triangulation_traits_adapter` is used internally by the
class `Regular_triangulation` to wrap its first template parameter
(`RegularTriangulationTraits_`)
so that the base class `Triangulation` manipulates weighted points instead
of bare points.
\tparam K must be a model of the `RegularTriangulationTraits` concept.
In addition to the types described below, the following predicates and functors
are adapted so that they can be called
with weighted points instead of bare points as parameters.
In practice, the functors from the base class `K` are called,
ignoring the weights.
- `Orientation_d`
- `Construct_flat_orientation_d`
- `In_flat_orientation_d`
- `Contained_in_affine_hull_d`
- `Compare_lexicographically_d`
- `Compute_coordinate_d`
- `Point_dimension_d`
- `Less_coordinate_d`
*/
template <typename K>
class Regular_triangulation_traits_adapter : public K {
public:
/// \name Types
/// @{
/*!
The weighted point type.
*/
typedef typename K::Weighted_point_d Point_d;
/*!
The (un-weighted) point type.
*/
typedef typename K::Point_d Bare_point_d;
/// @}
/// \name Creation
/// @{
/*!
The default constructor.
*/
Regular_triangulation_traits_adapter();
/// @}
};
} /* end namespace CGAL */

View File

@ -4,7 +4,7 @@ namespace CGAL {
/*! /*!
\ingroup PkgTriangulationsTriangulationClasses \ingroup PkgTriangulationsTriangulationClasses
This class implements triangulations of point sets in dimensions \f$ d \f$. This class implements triangulations of point sets in dimension \f$ d \f$.
The triangulation covers the convex hull of the input points The triangulation covers the convex hull of the input points
(the embedded vertices of the triangulation). (the embedded vertices of the triangulation).
@ -17,25 +17,25 @@ incident to the infinite vertex and to an \f$ (i-1)\f$-simplex of the
convex hull boundary. convex hull boundary.
\tparam TriangulationTraits is the geometric traits class that provides the geometric types \tparam TriangulationTraits_ is the geometric traits class that provides the geometric types
and predicates needed by triangulations. `TriangulationTraits` must be a model of the and predicates needed by triangulations. `TriangulationTraits_` must be a model of the
concept `TriangulationTraits`. concept `TriangulationTraits`.
\tparam TriangulationDataStructure must be a model of the concept \tparam TriangulationDataStructure_ must be a model of the concept
`TriangulationDataStructure`. This model is used to store `TriangulationDataStructure`. This model is used to store
the faces of the triangulation. The parameter `TriangulationDataStructure` defaults to the faces of the triangulation. The parameter `TriangulationDataStructure_` defaults to
`Triangulation_data_structure` whose template parameters are instantiated as `Triangulation_data_structure` whose template parameters are instantiated as
follows: follows:
<UL> <UL>
<LI>`DelaunayTriangulationTraits::Dimension`</LI> <LI>`TriangulationTraits_::Dimension`</LI>
<LI>`Triangulation_vertex<DelaunayTriangulationTraits>`</LI> <LI>`Triangulation_vertex<TriangulationTraits_>`</LI>
<LI>`Triangulation_full_cell<DelaunayTriangulationTraits>`.</LI> <LI>`Triangulation_full_cell<TriangulationTraits_>`.</LI>
</UL> </UL>
The triangulation deduces its maximal dimension from the type The triangulation deduces its maximal dimension from the type
`TriangulationTraits::Dimension`. This dimension has to match `TriangulationTraits_::Dimension`. This dimension has to match
the dimension returned by the dimension returned by
`TriangulationDataStructure::maximal_dimension()`. `TriangulationDataStructure_::maximal_dimension()`.
Input/Output Input/Output
-------------- --------------
@ -47,62 +47,64 @@ full cell, plus the non-combinatorial information about each full cell, then the
indices of the neighbors of each full cell, where the index corresponds to the indices of the neighbors of each full cell, where the index corresponds to the
preceding list of full cells. preceding list of full cells.
\sa `Triangulation_data_structure<Dimensionality, TriangulationDSVertex, TriangulationDSFullCell>` \sa `Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`
\sa `Delaunay_triangulation<DelaunayTriangulationTraits, TriangulationDataStructure>` \sa `Delaunay_triangulation<DelaunayTriangulationTraits_, TriangulationDataStructure_>`
*/ */
template< typename TriangulationTraits, typename TriangulationDataStructure > template< typename TriangulationTraits_, typename TriangulationDataStructure_>
class Triangulation { class Triangulation {
public: public:
/// \name Types /// \name Types
/// @{ /// @{
/*! /*!
Type for the model of the `TriangulationTraits` concept. Type for the model of the `TriangulationTraits_` concept.
*/ */
typedef TriangulationTraits Geom_traits; typedef TriangulationTraits_ Geom_traits;
/*! /*!
A point in Euclidean space. A point in Euclidean space. Note that in the context of a
`Regular_triangulation` class (which derives from this class),
`TriangulationTraits_::Point_d` is a weighted point.
*/ */
typedef TriangulationTraits::Point_d Point; typedef TriangulationTraits_::Point_d Point;
/*! /*!
This indicates whether the maximal dimension is static This indicates whether the maximal dimension is static
(i.e.\ if the type of `Maximal_dimension` is `CGAL::Dimension_tag<int dim>`) (i.e.\ if the type of `Maximal_dimension` is `CGAL::Dimension_tag<int dim>`)
or dynamic (i.e.\ if the type of `Maximal_dimension` is or dynamic (i.e.\ if the type of `Maximal_dimension` is
`CGAL::Dynamic_dimension_tag`). `CGAL::Dynamic_dimension_tag`).
In the latter case, the `dim` parameter passed to the class's constructor In the latter case, the `dim` parameter passed to the constructor
is used. of the class is used.
*/ */
typedef TriangulationTraits::Dimension Maximal_dimension; typedef TriangulationTraits_::Dimension Maximal_dimension;
/*! /*!
The second template parameter: the triangulation data structure. The second template parameter: the triangulation data structure.
*/ */
typedef TriangulationDataStructure Triangulation_ds; typedef TriangulationDataStructure_ Triangulation_ds;
/*! /*!
A model of the concept `TriangulationVertex`. A model of the concept `TriangulationVertex`.
*/ */
typedef TriangulationDataStructure::Vertex Vertex; typedef TriangulationDataStructure_::Vertex Vertex;
/*! /*!
A model of the concept A model of the concept
`TriangulationFullCell`. `TriangulationFullCell`.
*/ */
typedef TriangulationDataStructure::Full_cell Full_cell; typedef TriangulationDataStructure_::Full_cell Full_cell;
/*! /*!
The facet The facet
class class
*/ */
typedef TriangulationDataStructure::Facet Facet; typedef TriangulationDataStructure_::Facet Facet;
/*! /*!
A model of the concept `TriangulationDSFace`. A model of the concept `TriangulationDSFace`.
*/ */
typedef TriangulationDataStructure::Face Face; typedef TriangulationDataStructure_::Face Face;
/// @} /// @}
@ -122,25 +124,25 @@ typedef TriangulationDataStructure::Face Face;
/*! /*!
handle to a a vertex handle to a a vertex
*/ */
typedef TriangulationDataStructure::Vertex_handle typedef TriangulationDataStructure_::Vertex_handle
Vertex_handle; Vertex_handle;
/*! /*!
const handle to a a vertex const handle to a a vertex
*/ */
typedef TriangulationDataStructure::Vertex_const_handle typedef TriangulationDataStructure_::Vertex_const_handle
Vertex_const_handle; Vertex_const_handle;
/*! /*!
iterator over all vertices (including the infinite one) iterator over all vertices (including the infinite one)
*/ */
typedef TriangulationDataStructure::Vertex_iterator typedef TriangulationDataStructure_::Vertex_iterator
Vertex_iterator; Vertex_iterator;
/*! /*!
const iterator over all vertices (including the infinite one) const iterator over all vertices (including the infinite one)
*/ */
typedef TriangulationDataStructure::Vertex_const_iterator typedef TriangulationDataStructure_::Vertex_const_iterator
Vertex_const_iterator; Vertex_const_iterator;
/*! /*!
@ -156,27 +158,27 @@ typedef unspecified_type Finite_vertex_const_iterator;
/*! /*!
handle to a full cell handle to a full cell
*/ */
typedef TriangulationDataStructure::Full_cell_handle typedef TriangulationDataStructure_::Full_cell_handle
Full_cell_handle; Full_cell_handle;
/*! /*!
const handle to a full cell const handle to a full cell
*/ */
typedef TriangulationDataStructure::Full_cell_const_handle typedef TriangulationDataStructure_::Full_cell_const_handle
Full_cell_const_handle; Full_cell_const_handle;
/*! /*!
iterator over all full cells (including the infinite ones) iterator over all full cells (including the infinite ones)
*/ */
typedef typedef
TriangulationDataStructure::Full_cell_iterator TriangulationDataStructure_::Full_cell_iterator
Full_cell_iterator; Full_cell_iterator;
/*! /*!
const iterator over all full cells (including the infinite ones) const iterator over all full cells (including the infinite ones)
*/ */
typedef typedef
TriangulationDataStructure::Full_cell_const_iterator TriangulationDataStructure_::Full_cell_const_iterator
Full_cell_const_iterator; Full_cell_const_iterator;
/*! /*!
@ -192,7 +194,7 @@ typedef unspecified_type Finite_full_cell_const_iterator;
/*! /*!
iterator over all facets (including the infinite ones) iterator over all facets (including the infinite ones)
*/ */
typedef TriangulationDataStructure::Facet_iterator typedef TriangulationDataStructure_::Facet_iterator
Facet_iterator; Facet_iterator;
/*! /*!
@ -201,19 +203,19 @@ iterator over finite facets
typedef unspecified_type Finite_facet_iterator; typedef unspecified_type Finite_facet_iterator;
/*! /*!
Size type (an unsigned integral size type (an unsigned integral type)
type).
*/ */
typedef TriangulationDataStructure::size_type size_type; typedef TriangulationDataStructure_::size_type size_type;
/*! /*!
Difference difference
type (a signed integral type). type (a signed integral type)
*/ */
typedef TriangulationDataStructure::difference_type difference_type; typedef TriangulationDataStructure_::difference_type difference_type;
/*! /*!
specifies which case occurs when locating a point in the triangulation. \enum Locate_type
\brief Used by `Triangulation` to specify which case occurs when locating a point in the triangulation.
*/ */
enum Locate_type { ON_VERTEX=0, /*!< when the located point coincides with a vertex of the triangulation */ enum Locate_type { ON_VERTEX=0, /*!< when the located point coincides with a vertex of the triangulation */
IN_FACE, /*!< when the point is in the interior of a face of dimension equal or less than `maximal_dimension()` - 2 */ IN_FACE, /*!< when the point is in the interior of a face of dimension equal or less than `maximal_dimension()` - 2 */
@ -234,8 +236,7 @@ description of the nested type `Maximal_dimension` above for an
explanation of the use of the parameter `dim`. The triangulation stores a copy explanation of the use of the parameter `dim`. The triangulation stores a copy
of the geometric traits `gt`. of the geometric traits `gt`.
*/ */
Triangulation(const int dim, const Geom_traits & gt = Triangulation(int dim, const Geom_traits & gt = Geom_traits());
Geom_traits());
/*! /*!
The copy constructor. The copy constructor.
@ -248,15 +249,15 @@ Triangulation(const Triangulation & t2);
/// @{ /// @{
/*! /*!
\cgalAdvancedBegin
Returns a const reference to the underlying triangulation data structure. Returns a const reference to the underlying triangulation data structure.
\cgalAdvancedEnd
*/ */
const Triangulation_ds & tds() const; const Triangulation_ds & tds() const;
/*! /*!
\cgalAdvancedBegin
Returns a non-const Returns a non-const
reference to the underlying triangulation data structure. reference to the underlying triangulation data structure.
\cgalAdvancedEnd
*/ */
Triangulation_ds & tds(); Triangulation_ds & tds();
@ -322,13 +323,13 @@ size_type number_of_finite_full_cells() const;
/*! /*!
Returns `true` if and only if the vertex `v` is the infinite vertex. Returns `true` if and only if the vertex `v` is the infinite vertex.
*/ */
bool is_infinite(const Vertex_handle v) const; bool is_infinite(Vertex_handle v) const;
/*! /*!
Returns `true` if and only if `c` is incident to the infinite vertex. Returns `true` if and only if `c` is incident to the infinite vertex.
*/ */
bool is_infinite(const Full_cell_handle c) const; bool is_infinite(Full_cell_handle c) const;
/*! /*!
Returns `true` if and only if facet `ft` is incident to the infinite Returns `true` if and only if facet `ft` is incident to the infinite
@ -454,7 +455,7 @@ p_1, p_2, \ldots, p_d, \infty\}\f$ is returned such that the full cell \f$ (p_1,
on the other side of facet \f$ (p_1, p_2, \ldots, p_d)\f$). on the other side of facet \f$ (p_1, p_2, \ldots, p_d)\f$).
*/ */
Full_cell_handle locate(const Point & query, Full_cell_handle locate(const Point & query,
Full_cell_handle hint = Full_cell_handle()) const; Full_cell_const_handle hint = Full_cell_handle()) const;
/*! /*!
Same as above but `hint` is a vertex and not a full cell. Same as above but `hint` is a vertex and not a full cell.
@ -505,7 +506,7 @@ The parameter `hint` is ignored if it is a default constructed
*/ */
Full_cell_handle Full_cell_handle
locate(const Point & query, Locate_type & loc_type, locate(const Point & query, Locate_type & loc_type,
Face & f, Vertex_handle hint) const; Face & f, Vertex_handle hint) const;
/// @} /// @}
@ -513,13 +514,11 @@ Face & f, Vertex_handle hint) const;
/// @{ /// @{
/*! /*!
\cgalAdvancedBegin
Contracts the `Face f` to a single vertex at Contracts the `Face f` to a single vertex at
position `p`. Returns a handle to that vertex. position `p`. Returns a handle to that vertex.
\pre The boundary of the union of full cells incident to `f` must be a triangulation of a \pre The boundary of the union of full cells incident to `f` must be a triangulation of a
sphere of dimension `tr`.`current_dimension()`). sphere of dimension `tr`.`current_dimension()`).
\cgalAdvancedEnd
*/ */
Vertex_handle collapse_face(const Point & p, const Face & f); Vertex_handle collapse_face(const Point & p, const Face & f);
@ -544,16 +543,15 @@ Inserts point `p` in the triangulation. Returns a
Prior to the actual insertion, `p` is located in the triangulation; Prior to the actual insertion, `p` is located in the triangulation;
`hint` is used as a starting place for locating `p`. `hint` is used as a starting place for locating `p`.
*/ */
Vertex_handle insert(const Point p, Full_cell_handle hint = Vertex_handle insert(const Point &p, Full_cell_handle hint =
Full_cell_handle()); Full_cell_handle());
/*! /*!
Same as above but uses a vertex `hint` as the starting place for the search. Same as above but uses a vertex `hint` as the starting place for the search.
*/ */
Vertex_handle insert(const Point p, Vertex_handle hint); Vertex_handle insert(const Point &p, Vertex_handle hint);
/*! /*!
\cgalAdvancedBegin
Inserts point `p` into the triangulation and returns a handle to the Inserts point `p` into the triangulation and returns a handle to the
`Vertex` at that position. The action taken depends on the value of `Vertex` at that position. The action taken depends on the value of
`loc_type`: `loc_type`:
@ -567,12 +565,10 @@ of `loc_type`, using the full cell `c`.
</DL> </DL>
This method is used internally by the other `insert()` methods. This method is used internally by the other `insert()` methods.
\cgalAdvancedEnd
*/ */
Vertex_handle insert(const Point p, Locate_type loc_type, Face & f, Facet & ft, Full_cell_handle c); Vertex_handle insert(const Point &p, Locate_type loc_type, Face & f, Facet & ft, Full_cell_handle c);
/*! /*!
\cgalAdvancedBegin
Removes the full cells in the range \f$ C=\f$`[s, e)`, inserts a vertex Removes the full cells in the range \f$ C=\f$`[s, e)`, inserts a vertex
at position `p` and fills the hole by connecting at position `p` and fills the hole by connecting
each face of the boundary to `p`. each face of the boundary to `p`.
@ -582,62 +578,49 @@ defining full cell, `tr`.`full_cell(ft)` must lie inside \f$ C\f$. Handles
to the newly created full cells are output in the `out` output iterator. to the newly created full cells are output in the `out` output iterator.
\pre \f$C\f$ must be a topological ball, must contain `p` in its \pre \f$C\f$ must be a topological ball, must contain `p` in its
interior and must not contain any vertex of the triangulation. interior and must not contain any vertex of the triangulation.
\cgalAdvancedEnd
*/ */
template < typename ForwardIterator, typename OutputIterator > template < typename ForwardIterator, typename OutputIterator >
Vertex_handle insert_in_hole(const Point & p, ForwardIterator s, Vertex_handle insert_in_hole(const Point & p, ForwardIterator s,
ForwardIterator e, const Facet & ft, OutputIterator out); ForwardIterator e, const Facet & ft, OutputIterator out);
/*! /*!
\cgalAdvancedBegin
Same as above, but the newly created full cells are not Same as above, but the newly created full cells are not
retrieved. retrieved.
\cgalAdvancedEnd
*/ */
template < typename ForwardIterator > Vertex_handle template < typename ForwardIterator > Vertex_handle
insert_in_hole(const Point & p, ForwardIterator s, ForwardIterator e, const insert_in_hole(const Point & p, ForwardIterator s, ForwardIterator e, const
Facet & ft); Facet & ft);
/*! /*!
\cgalAdvancedBegin
Inserts point `p` in the triangulation. Inserts point `p` in the triangulation.
\pre `p` must lie in the relative interior of `f`. \pre `p` must lie in the relative interior of `f`.
\cgalAdvancedEnd
*/ */
Vertex_handle insert_in_face(const Point & p, const Face & f); Vertex_handle insert_in_face(const Point & p, const Face & f);
/*! /*!
\cgalAdvancedBegin
Inserts point `p` in the triangulation. Inserts point `p` in the triangulation.
\pre `p` must lie in the relative interior of `ft`. \pre `p` must lie in the relative interior of `ft`.
\cgalAdvancedEnd
*/ */
Vertex_handle insert_in_facet(const Point & p, const Facet & ft); Vertex_handle insert_in_facet(const Point & p, const Facet & ft);
/*! /*!
\cgalAdvancedBegin
Inserts point `p` in the triangulation. \pre `p` must lie in the Inserts point `p` in the triangulation. \pre `p` must lie in the
interior of `c`. interior of `c`.
\cgalAdvancedEnd
*/ */
Vertex_handle insert_in_full_cell(const Point & p, Full_cell_handle Vertex_handle insert_in_full_cell(const Point & p, Full_cell_handle
c); c);
/*! /*!
\cgalAdvancedBegin
Inserts point `p` in the triangulation. Inserts point `p` in the triangulation.
\pre `p` must lie outside the convex hull of `tr`. The half-space \pre `p` must lie outside the convex hull of `tr`. The half-space
defined by the infinite full cell `c` must contain `p`. defined by the infinite full cell `c` must contain `p`.
\cgalAdvancedEnd
*/ */
Vertex_handle insert_outside_convex_hull(const Point &, Vertex_handle insert_outside_convex_hull(const Point &,
Full_cell_handle c); Full_cell_handle c);
/*! /*!
\cgalAdvancedBegin
Inserts point `p` in the triangulation. Inserts point `p` in the triangulation.
\pre `p` must lie outside the affine hull of `tr`. \pre `p` must lie outside the affine hull of `tr`.
\cgalAdvancedEnd
*/ */
Vertex_handle insert_outside_affine_hull(const Point &); Vertex_handle insert_outside_affine_hull(const Point &);

View File

@ -9,29 +9,29 @@ of dimension \f$ d\leq D\f$ (`D` is the maximal dimension).
\tparam Dimensionality can be either <UL> \tparam Dimensionality can be either <UL>
<LI>CGAL::`Dimension_tag<D>` for some integer `D`. This <LI>`CGAL::Dimension_tag<D>` for some integer `D`. This
indicates that the triangulation data structure can store simplices (full cells) of dimension at most indicates that the triangulation data structure can store simplices (full cells) of dimension at most
`D`. The maximal dimension `D` is known by the compiler, which `D`. The maximal dimension `D` is known by the compiler, which
triggers some optimizations. Or triggers some optimizations. Or
<LI>CGAL::`Dynamic_dimension_tag`. In this case, the maximum <LI>`CGAL::Dynamic_dimension_tag`. In this case, the maximum
dimension of the simplices (full cells) is passed as an integer argument to an instance dimension of the simplices (full cells) is passed as an integer argument to an instance
constructor (see `TriangulationDataStructure`).</UL> constructor (see `TriangulationDataStructure`).</UL>
\tparam TriangulationDSVertex stands for a class to \tparam `TriangulationDSVertex_` stands for a class to
be used as the base `Vertex` type in the triangulation data structure. be used as the base `Vertex` type in the triangulation data structure.
It must be a model of the concept It must be a model of the concept
`TriangulationDSVertex`. The class template `Triangulation_data_structure` can be `TriangulationDSVertex`. The class template `Triangulation_data_structure` can be
defined by specifying defined by specifying
only the first parameter. It also accepts the tag `CGAL::Default` as only the first parameter. It also accepts the tag `CGAL::Default` as
second parameter. In both cases, `TriangulationDSVertex` defaults to second parameter. In both cases, `TriangulationDSVertex_` defaults to
`CGAL::Triangulation_ds_vertex<>`. `CGAL::Triangulation_ds_vertex<>`.
\tparam TriangulationDSFullCell stands for a class to \tparam `TriangulationDSFullCell_` stands for a class to
be used as the base `Full_cell` type in the triangulation data structure. be used as the base `Full_cell` type in the triangulation data structure.
It must be a model of the concept It must be a model of the concept
`TriangulationDSFullCell`. The class template `Triangulation_data_structure` accepts that no `TriangulationDSFullCell`. The class template `Triangulation_data_structure` accepts that no
third parameter be specified. It also accepts the tag `CGAL::Default` as third parameter be specified. It also accepts the tag `CGAL::Default` as
third parameter. In both cases, `TriangulationDSFullCell` defaults to third parameter. In both cases, `TriangulationDSFullCell_` defaults to
`CGAL::Triangulation_ds_full_cell<>`. `CGAL::Triangulation_ds_full_cell<>`.
\cgalModels `TriangulationDataStructure`. In addition, the class \cgalModels `TriangulationDataStructure`. In addition, the class
@ -41,7 +41,7 @@ methods.
\sa `Triangulation_ds_vertex` \sa `Triangulation_ds_vertex`
\sa `Triangulation_ds_full_cell` \sa `Triangulation_ds_full_cell`
*/ */
template< typename Dimensionality, typename TriangulationDSVertex, typename TriangulationDSFullCell > template< typename Dimensionality, typename TriangulationDSVertex_, typename TriangulationDSFullCell_ >
class Triangulation_data_structure { class Triangulation_data_structure {
public: public:

View File

@ -17,7 +17,7 @@ This class can be used directly or can serve as a base to derive other classes
with some additional attributes tuned for a specific application. with some additional attributes tuned for a specific application.
\tparam TriangulationDataStructure must be a model of the \tparam `TriangulationDataStructure_` must be a model of the
`TriangulationDataStructure` concept. `TriangulationDataStructure` concept.
\tparam TriangulationDSFullCellStoragePolicy indicates whether or not \tparam TriangulationDSFullCellStoragePolicy indicates whether or not
@ -49,11 +49,11 @@ Rebind mechanism
In case of derivation from that class, the nested class In case of derivation from that class, the nested class
`Rebind_TDS` need to be provided in the derived class. `Rebind_TDS` need to be provided in the derived class.
\sa `Triangulation_ds_vertex<TriangulationDataStructure>` \sa `Triangulation_ds_vertex<TriangulationDataStructure_>`
\sa `Triangulation_data_structure<Dimensionality, TriangulationDSVertex, TriangulationDSFullCell>>` \sa `Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`
*/ */
template< typename TriangulationDataStructure, typename TriangulationDSFullCellStoragePolicy > template< typename TriangulationDataStructure_, typename TriangulationDSFullCellStoragePolicy >
class Triangulation_ds_full_cell { class Triangulation_ds_full_cell {
public: public:

View File

@ -5,7 +5,7 @@ namespace CGAL {
\ingroup PkgTriangulationsVertexCellClasses \ingroup PkgTriangulationsVertexCellClasses
The class `Triangulation_ds_vertex` serves as the default vertex template parameter in the The class `Triangulation_ds_vertex` serves as the default vertex template parameter in the
class `Triangulation_data_structure<Dimensionality, TriangulationDSVertex, TriangulationDSFullCell>`. class `Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`.
This class does not contain any geometric information but only combinatorial This class does not contain any geometric information but only combinatorial
(adjacency) information. Thus, if the `Triangulation_data_structure` is (adjacency) information. Thus, if the `Triangulation_data_structure` is
@ -18,7 +18,7 @@ with some additional attributes tuned for a specific application (a color for
example). example).
\tparam TriangulationDataStructure must be a model of the \tparam `TriangulationDataStructure_` must be a model of the
`TriangulationDataStructure` concept. `TriangulationDataStructure` concept.
\cgalModels `TriangulationDSVertex` \cgalModels `TriangulationDSVertex`
@ -29,11 +29,11 @@ Rebind Mechanism
In case of derivation from that class, the nested class In case of derivation from that class, the nested class
`Rebind_TDS` need to be provided in the derived class. `Rebind_TDS` need to be provided in the derived class.
\sa `Triangulation_ds_full_cell<TriangulationDataStructure, TriangulationDSFullCellStoragePolicy>` \sa `Triangulation_ds_full_cell<TriangulationDataStructure_, TriangulationDSFullCellStoragePolicy>`
\sa `Triangulation_data_structure<Dimensionality, TriangulationDSVertex, TriangulationDSFullCell>>` \sa `Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`
*/ */
template< typename TriangulationDataStructure > template< typename TriangulationDataStructure_ >
class Triangulation_ds_vertex { class Triangulation_ds_vertex {
public: public:

View File

@ -5,7 +5,7 @@ namespace CGAL {
A `Triangulation_face` is a model of the concept `TriangulationDSFace`. A `Triangulation_face` is a model of the concept `TriangulationDSFace`.
\tparam TriangulationDataStructure must be a model of the concept \tparam TriangulationDataStructure_ must be a model of the concept
`TriangulationDataStructure`. `TriangulationDataStructure`.
Actually, `Triangulation_face` needs only that this concept defines the types Actually, `Triangulation_face` needs only that this concept defines the types
`Full_cell_handle`, `Full_cell_handle`,
@ -18,7 +18,7 @@ Actually, `Triangulation_face` needs only that this concept defines the types
\sa `TriangulationDataStructure` \sa `TriangulationDataStructure`
*/ */
template< typename TriangulationDataStructure > template< typename TriangulationDataStructure_ >
class Triangulation_face { class Triangulation_face {
}; /* end Triangulation_face */ }; /* end Triangulation_face */

View File

@ -6,15 +6,15 @@ namespace CGAL {
The class `Triangulation_full_cell` is a model of the concept `TriangulationFullCell`. It The class `Triangulation_full_cell` is a model of the concept `TriangulationFullCell`. It
is used by default for representing full cells in the class is used by default for representing full cells in the class
`Triangulation<TriangulationTraits, TriangulationDataStructure>`. `Triangulation<TriangulationTraits_, TriangulationDataStructure_>`.
A `Triangulation_full_cell` stores handles to the vertices of the cell as well as handles A `Triangulation_full_cell` stores handles to the vertices of the cell as well as handles
to its adjacent cells. to its adjacent cells.
\tparam TriangulationTraits must be a model of the concept `TriangulationTraits`. It \tparam `TriangulationTraits_` must be a model of the concept `TriangulationTraits`. It
provides geometric types and predicates for use in the provides geometric types and predicates for use in the
`Triangulation<TriangulationTraits, TriangulationDataStructure>` class. `Triangulation<TriangulationTraits_, TriangulationDataStructure_>` class.
\tparam Data is an optional type of data to be stored in the full cell class. The \tparam Data is an optional type of data to be stored in the full cell class. The
class template `Triangulation_full_cell` accepts that no second parameter be specified. In class template `Triangulation_full_cell` accepts that no second parameter be specified. In
@ -31,13 +31,13 @@ cases, `TriangulationDSFullCell_` defaults to `CGAL::Triangulation_ds_full_cell<
`Triangulation_full_cell` provides the following types, `Triangulation_full_cell` provides the following types,
constructors and methods: constructors and methods:
\sa `Triangulation_vertex<TriangulationTraits, Data, TriangulationDSVertex>` \sa `Triangulation_vertex<TriangulationTraits_, Data, TriangulationDSVertex_>`
\sa `Triangulation_data_structure<Dimensionality, TriangulationDSVertex, TriangulationDSFullCell>` \sa `Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`
\sa `Triangulation<TriangulationTraits,TriangulationDataStructure>` \sa `Triangulation<TriangulationTraits_, TriangulationDataStructure_>`
\sa `Delaunay_triangulation<DelaunayTriangulationTraits, TriangulationDataStructure>` \sa `Delaunay_triangulation<DelaunayTriangulationTraits_, TriangulationDataStructure_>`
*/ */
template< typename TriangulationTraits, typename Data, typename TriangulationDSFullCell_ > template< typename TriangulationTraits_, typename Data, typename TriangulationDSFullCell_ >
class Triangulation_full_cell : public TriangulationDSFullCell_ { class Triangulation_full_cell : public TriangulationDSFullCell_ {
public: public:

View File

@ -6,14 +6,14 @@ namespace CGAL {
The class `Triangulation_vertex` is a model of the concept `TriangulationVertex`. It is The class `Triangulation_vertex` is a model of the concept `TriangulationVertex`. It is
used by default for representing vertices in the class used by default for representing vertices in the class
`Triangulation<TriangulationTraits, TriangulationDataStructure>`. `Triangulation<TriangulationTraits_, TriangulationDataStructure_>`.
A `Triangulation_vertex` stores a point and an incident full cell. A `Triangulation_vertex` stores a point and an incident full cell.
\tparam TriangulationTraits must be a model of the concept `TriangulationTraits`. It \tparam `TriangulationTraits_` must be a model of the concept `TriangulationTraits`. It
provides geometric types and predicates for use in the provides geometric types and predicates for use in the
`Triangulation<TriangulationTraits, TriangulationDataStructure>` class. It is of interest here for its `Triangulation<TriangulationTraits_, TriangulationDataStructure_>` class. It is of interest here for its
declaration of the `Point` type. declaration of the `Point` type.
\tparam Data is an optional type of data to be stored in the vertex class. The \tparam Data is an optional type of data to be stored in the vertex class. The
@ -22,27 +22,32 @@ this case, `Data` defaults to `CGAL::No_vertex_data`.
`CGAL::No_vertex_data` can be explicitely specified to allow to access the `CGAL::No_vertex_data` can be explicitely specified to allow to access the
third parameter. third parameter.
\tparam TriangulationDSVertex must be a model of the concept `TriangulationDSVertex`. The \tparam `TriangulationDSVertex_` must be a model of the concept `TriangulationDSVertex`. The
class template `Triangulation_vertex` accepts that no third parameter be specified. It class template `Triangulation_vertex` accepts that no third parameter be specified. It
also accepts the tag `CGAL::Default` as third parameter. In both cases, also accepts the tag `CGAL::Default` as third parameter. In both cases,
`TriangulationDSVertex` defaults to `CGAL::Triangulation_ds_vertex<>`. `TriangulationDSVertex_` defaults to `CGAL::Triangulation_ds_vertex<>`.
\cgalModels `TriangulationVertex` Additionally, the class \cgalModels `TriangulationVertex` Additionally, the class
`Triangulation_vertex` provides the following types, constructors `Triangulation_vertex` provides the following types, constructors
and methods: and methods:
\sa `Triangulation_full_cell<TriangulationTraits, Data, TriangulationDSFullCell>` \sa `Triangulation_full_cell<TriangulationTraits_, Data, TriangulationDSFullCell_>`
\sa `Triangulation_data_structure<Dimensionality, TriangulationDSVertex, TriangulationDSFullCell>` \sa `Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`
\sa `Triangulation<TriangulationTraits,TriangulationDataStructure>` \sa `Triangulation<TriangulationTraits_, TriangulationDataStructure_>`
\sa `Delaunay_triangulation<DelaunayTriangulationTraits, TriangulationDataStructure>` \sa `Delaunay_triangulation<DelaunayTriangulationTraits_, TriangulationDataStructure_>`
*/ */
template< typename TriangulationTraits, typename Data, typename TriangulationDSVertex > template< typename TriangulationTraits_, typename Data, typename TriangulationDSVertex_ >
class Triangulation_vertex { class Triangulation_vertex {
public: public:
/// \name Types /// \name Types
/// @{ /// @{
/*!
The point type.
*/
typedef TriangulationTraits_::Point_d Point;
/*! /*!
The type of the additional data stored in the The type of the additional data stored in the
vertex. If you read a `Triangulation_vertex` from a stream (a file) or write a `Triangulation_vertex` to a stream, then streaming operators `<<` and `>>` must be provided for this vertex. If you read a `Triangulation_vertex` from a stream (a file) or write a `Triangulation_vertex` to a stream, then streaming operators `<<` and `>>` must be provided for this

View File

@ -5,7 +5,7 @@
This concept describes the geometric types and predicates required to build This concept describes the geometric types and predicates required to build
a Delaunay triangulation. It corresponds to the first template parameter of the class a Delaunay triangulation. It corresponds to the first template parameter of the class
`CGAL::Delaunay_triangulation<DelaunayTriangulationTraits, TriangulationDataStructure>`. `CGAL::Delaunay_triangulation<DelaunayTriangulationTraits_, TriangulationDataStructure_>`.
\cgalRefines `TriangulationTraits` \cgalRefines `TriangulationTraits`
@ -32,7 +32,7 @@ defined by the points in range `[start,end)`.
If the simplex is positively If the simplex is positively
oriented, then the positive side of sphere corresponds geometrically oriented, then the positive side of sphere corresponds geometrically
to its bounded side. to its bounded side.
\pre If `Dimension`=`CGAL::``Dimension_tag<D>`, \pre If `Dimension`=`CGAL::Dimension_tag<D>`,
then `std::distance(start,end)=D+1`. then `std::distance(start,end)=D+1`.
The points in range The points in range
`[start,end)` must be affinely independent, i.e., the simplex must `[start,end)` must be affinely independent, i.e., the simplex must
@ -70,14 +70,16 @@ typedef unspecified_type In_flat_side_of_oriented_sphere_d;
/// @{ /// @{
/*! /*!
The default constructor. The default constructor (optional).
This is not required when an instance of the traits is provided
to the constructor of `CGAL::Delaunay_triangulation`.
*/ */
DelaunayTriangulationTraits(); DelaunayTriangulationTraits();
/// @} /// @}
/// \name Operations /// \name Operations
/// The following methods permit access to the traits class's predicates: /// The following methods permit access to the traits class's predicates and functors:
/// @{ /// @{
/*! /*!

View File

@ -0,0 +1,132 @@
/*!
\ingroup PkgTriangulationsConcepts
\cgalConcept
This concept describes the geometric types and predicates required to build
a regular triangulation. It corresponds to the first template parameter of the class
`CGAL::Regular_triangulation<RegularTriangulationTraits_, TriangulationDataStructure_>`.
\cgalRefines `TriangulationTraits`
\cgalHasModel `CGAL::Epick_d<Dim>`
\sa `TriangulationTraits`
*/
class RegularTriangulationTraits {
public:
/// \name Types
/// @{
/*!
A number type that is a model for `FieldNumberType`.
*/
typedef unspecified_type FT;
/*!
The weighted point type.
*/
typedef unspecified_type Weighted_point_d;
/*!
A function object that must provide the operator
`Point_d operator()(const Weighted_point_d & wp)`, returning
`wp` without its weight.
*/
typedef unspecified_type Construct_point_d;
/*!
A function object that must provide the operator
`FT operator()(const Weighted_point_d & wp)`, returning
the weight of `wp`.
*/
typedef unspecified_type Compute_weight_d;
/*!
A predicate object that must provide the templated operator
`template<typename ForwardIterator> Oriented_side operator()(ForwardIterator start, ForwardIterator end, const Weighted_point_d & p)`.
Let \f$ S \f$ be the power sphere of the weighted points in range `[start,end)`.
The operator returns:
- `ON_ORIENTED_BOUNDARY` if `p` is orthogonal to
\f$ S \f$,
- `ON_NEGATIVE_SIDE` if the power distance between `p` and \f$ S \f$ is
positive.
- `ON_POSITIVE_SIDE` otherwise.
\pre If `Dimension` is `CGAL::Dimension_tag<D>`,
then `std::distance(start,end)=D+1`.
The weighted points in range
`[start,end)` must be affinely independent, i.e., the simplex must
not be flat.
*/
typedef unspecified_type Power_side_of_power_sphere_d;
/*!
A predicate object that must provide the templated operator
`template<typename ForwardIterator> Oriented_side operator()(Flat_orientation_d orient, ForwardIterator start, ForwardIterator end, const Weighted_point_d & p)`.
The points in range `[start,end)` and `p` are supposed to belong to the lower-dimensional flat
whose orientation is given by `orient`.
Let \f$ S \f$ be the power sphere of the weighted points in range `[start,end)`
in this lower dimensional flat.
The operator returns:
- `ON_ORIENTED_BOUNDARY` if `p` is orthogonal to
\f$ S \f$,
- `ON_NEGATIVE_SIDE` if the power distance between `p` and \f$ S \f$ is
positive.
- `ON_POSITIVE_SIDE` otherwise.
\pre `std::distance(start,end)=k+1` where \f$ k\f$ is the number of
points used to construct `orient` (dimension of the flat).
The points in range `[start,end)` must be affinely independent.
`p` must be in the flat generated by these points.
*/
typedef unspecified_type In_flat_power_side_of_power_sphere_d;
/// @}
/// \name Creation
/// @{
/*!
The default constructor (optional).
This is not required when an instance of the traits is provided
to the constructor of `CGAL::Regular_triangulation`.
*/
RegularTriangulationTraits();
/// @}
/// \name Operations
/// The following methods permit access to the traits class's predicates and functors:
/// @{
/*!
*/
Construct_point_d construct_point_d_object() const;
/*!
*/
Compute_weight_d compute_weight_d_object() const;
/*!
*/
Power_side_of_power_sphere_d power_side_of_power_sphere_d_object() const;
/*!
*/
In_flat_power_side_of_power_sphere_d in_flat_power_side_of_power_sphere_d_object() const;
/// @}
}; /* end RegularTriangulationTraits */

View File

@ -15,7 +15,7 @@ The dimension of a face is implicitely set when
`TriangulationDSFace::set_index` is called two times to set the `TriangulationDSFace::set_index` is called two times to set the
first two vertices (`i = 0` and `i = 1`), then the dimension is 1. first two vertices (`i = 0` and `i = 1`), then the dimension is 1.
\cgalHasModel `CGAL::Triangulation_face<TriangulationDataStructure>` \cgalHasModel `CGAL::Triangulation_face<TriangulationDataStructure_>`
\sa `TriangulationDSFullCell` \sa `TriangulationDSFullCell`
\sa `TriangulationDSVertex` \sa `TriangulationDSVertex`

View File

@ -36,8 +36,8 @@ of `CGAL::Triangulation_data_structure::Vertex`.
\cgalRefines `TriangulationDataStructure::FullCell` \cgalRefines `TriangulationDataStructure::FullCell`
\cgalHasModel ` CGAL::Triangulation_ds_full_cell<TriangulationDataStructure,DSFullCellStoragePolicy>` \cgalHasModel `CGAL::Triangulation_ds_full_cell<TriangulationDataStructure_, DSFullCellStoragePolicy>`
\cgalHasModel `CGAL::Triangulation_full_cell<TriangulationTraits, Data, TriangulationDSFullCell>` \cgalHasModel `CGAL::Triangulation_full_cell<TriangulationTraits_, Data, TriangulationDSFullCell_>`
\sa `TriangulationDSVertex` \sa `TriangulationDSVertex`
\sa `TriangulationDSFace` \sa `TriangulationDSFace`

View File

@ -36,8 +36,8 @@ of `CGAL::Triangulation_data_structure::Vertex`.
\cgalRefines `TriangulationDataStructure::Vertex` \cgalRefines `TriangulationDataStructure::Vertex`
\cgalHasModel `CGAL::Triangulation_ds_vertex<TriangulationDataStructure>` \cgalHasModel `CGAL::Triangulation_ds_vertex<TriangulationDataStructure_>`
\cgalHasModel `CGAL::Triangulation_vertex<TriangulationTraits, Data, TriangulationDSVertex>` \cgalHasModel `CGAL::Triangulation_vertex<TriangulationTraits_, Data, TriangulationDSVertex_>`
\sa `TriangulationDSFullCell` \sa `TriangulationDSFullCell`
\sa `TriangulationDSFace` \sa `TriangulationDSFace`

View File

@ -26,8 +26,8 @@ which is also the unique vertex and the unique full cell in the
`TriangulationDataStructure`. `TriangulationDataStructure`.
In a In a
geometric realization of the `TriangulationDataStructure` (<I>e.g.</I>, in a geometric realization of the `TriangulationDataStructure` (<I>e.g.</I>, in a
`Triangulation<TriangulationTraits, TriangulationDataStructure>` or a `Triangulation<TriangulationTraits_, TriangulationDataStructure_>` or a
`Delaunay_triangulation<DelaunayTriangulationTraits, TriangulationDataStructure>`), this vertex `Delaunay_triangulation<DelaunayTriangulationTraits_, TriangulationDataStructure_>`), this vertex
corresponds to <I>the vertex at infinity</I>. corresponds to <I>the vertex at infinity</I>.
<DT><B>0</B><DD> This corresponds to two vertices, each incident to one \f$ 0\f$-face; <DT><B>0</B><DD> This corresponds to two vertices, each incident to one \f$ 0\f$-face;
@ -70,7 +70,7 @@ The classes `Vertex` and
`Full_cell` have to provide the relevant I/O operators `Full_cell` have to provide the relevant I/O operators
(possibly empty). (possibly empty).
\cgalHasModel `CGAL::Triangulation_data_structure<Dimensionality, TriangulationDSVertex, TriangulationDSFullCell>` \cgalHasModel `CGAL::Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`
\sa `TriangulationDataStructure::Vertex` \sa `TriangulationDataStructure::Vertex`
\sa `TriangulationDataStructure::FullCell` \sa `TriangulationDataStructure::FullCell`
@ -257,11 +257,13 @@ The predicate must return `true`
if the traversal of that `Facet` leads to a good full cell. if the traversal of that `Facet` leads to a good full cell.
All the good full cells are output into the last argument `out`. All the good full cells are output into the last argument `out`.
\pre `start != Full_cell_handle()` and `start` is a good cell.
Returns a facet on the boundary of the set of cells.
\pre `start != Full_cell_handle()` and `start` is a good cell.
*/ */
template< typename TraversalPredicate, typename OutputIterator > template< typename TraversalPredicate, typename OutputIterator >
void gather_full_cells(Full_cell_handle start, TraversalPredicate & tp, Facet gather_full_cells(Full_cell_handle start, TraversalPredicate & tp,
OutputIterator & out) const; OutputIterator & out) const;
/*! /*!
@ -656,8 +658,8 @@ It sets requirements of combinatorial nature
only, as geometry is not concerned here. In particular, we only require that only, as geometry is not concerned here. In particular, we only require that
the vertex holds a handle to a full cell incident to it in the triangulation. the vertex holds a handle to a full cell incident to it in the triangulation.
\cgalHasModel `CGAL::Triangulation_ds_vertex<TriangulationDataStructure>` \cgalHasModel `CGAL::Triangulation_ds_vertex<TriangulationDataStructure_>`
\cgalHasModel `CGAL::Triangulation_vertex<TriangulationTraits, Data, TriangulationDSVertex>` \cgalHasModel `CGAL::Triangulation_vertex<TriangulationTraits_, Data, TriangulationDSVertex_>`
\sa `TriangulationDataStructure::FullCell` \sa `TriangulationDataStructure::FullCell`
\sa `TriangulationDataStructure::Face` \sa `TriangulationDataStructure::Face`
@ -763,8 +765,8 @@ full cell as well as handles to the adjacent full cells. Two full cells
are said to be adjacent when they share a facet. Adjacent full cells are are said to be adjacent when they share a facet. Adjacent full cells are
called hereafter neighbors. called hereafter neighbors.
\cgalHasModel `CGAL::Triangulation_ds_full_cell<TriangulationDataStructure,DSFullCellStoragePolicy>` \cgalHasModel `CGAL::Triangulation_ds_full_cell<TriangulationDataStructure_, DSFullCellStoragePolicy>`
\cgalHasModel `CGAL::Triangulation_full_cell<TriangulationTraits, Data, TriangulationDSFullCell>` \cgalHasModel `CGAL::Triangulation_full_cell<TriangulationTraits_, Data, TriangulationDSFullCell_>`
\sa `TriangulationDataStructure::FullCell` \sa `TriangulationDataStructure::FullCell`
\sa `TriangulationDataStructure::Face` \sa `TriangulationDataStructure::Face`

View File

@ -4,17 +4,17 @@
\cgalConcept \cgalConcept
The concept `TriangulationFullCell` describes the requirements on the type used by the The concept `TriangulationFullCell` describes the requirements on the type used by the
class `CGAL::Triangulation<TriangulationTraits, TriangulationDataStructure>`, and its derived classes, to class `CGAL::Triangulation<TriangulationTraits_, TriangulationDataStructure_>`, and its derived classes, to
represent a full cell. represent a full cell.
\cgalRefines `TriangulationDSFullCell` We only list below the \cgalRefines `TriangulationDSFullCell` We only list below the
additional specific requirements of `TriangulationFullCell`. additional specific requirements of `TriangulationFullCell`.
\cgalHasModel `CGAL::Triangulation_full_cell<TriangulationTraits, TriangulationDSFullCell>` \cgalHasModel `CGAL::Triangulation_full_cell<TriangulationTraits_, TriangulationDSFullCell_>`
\sa `CGAL::Triangulation_full_cell<TriangulationTraits, Data, TriangulationDSFullCell>` \sa `CGAL::Triangulation_full_cell<TriangulationTraits_, Data, TriangulationDSFullCell_>`
\sa `TriangulationVertex` \sa `TriangulationVertex`
\sa `CGAL::Triangulation<TriangulationTraits, TriangulationDataStructure>` \sa `CGAL::Triangulation<TriangulationTraits_, TriangulationDataStructure_>`
*/ */

View File

@ -5,7 +5,7 @@
This concept describes the geometric types and predicates required to build This concept describes the geometric types and predicates required to build
a triangulation. It corresponds to the first template parameter of the class a triangulation. It corresponds to the first template parameter of the class
`CGAL::Triangulation<TriangulationTraits, TriangulationDataStructure>`. `CGAL::Triangulation<TriangulationTraits_, TriangulationDataStructure_>`.
\cgalRefines `SpatialSortingTraits_d` \cgalRefines `SpatialSortingTraits_d`
@ -30,8 +30,8 @@ A type representing the dimension of the predicates
(but not necessarily the one of `Point_d`). If \f$ n \f$ is the number of (but not necessarily the one of `Point_d`). If \f$ n \f$ is the number of
points required by the `Orientation_d` predicate, then points required by the `Orientation_d` predicate, then
`Dimension` \f$ = n - 1\f$. `Dimension` \f$ = n - 1\f$.
It can be static (`Dimension`=`CGAL::``Dimension_tag<int dim>`) or It can be static (`Dimension`=`CGAL::Dimension_tag<int dim>`) or
dynamic (`Dimension`=`CGAL::``Dynamic_dimension_tag`). dynamic (`Dimension`=`CGAL::Dynamic_dimension_tag`).
*/ */
typedef unspecified_type Dimension; typedef unspecified_type Dimension;
@ -48,7 +48,7 @@ templated operator
The operator returns the orientation of the simplex defined by the points The operator returns the orientation of the simplex defined by the points
in the range `[start, end)`; the value can be in the range `[start, end)`; the value can be
`CGAL::POSITIVE`, `CGAL::NEGATIVE` or `CGAL::COPLANAR`. `CGAL::POSITIVE`, `CGAL::NEGATIVE` or `CGAL::COPLANAR`.
\pre If `Dimension`=`CGAL::``Dimension_tag<D>`, then `std::distance(start,end)=D+1`. \pre If `Dimension`=`CGAL::Dimension_tag<D>`, then `std::distance(start,end)=D+1`.
*/ */
typedef unspecified_type Orientation_d; typedef unspecified_type Orientation_d;
@ -59,7 +59,7 @@ the templated operator
The operator returns `true` if and only if point `p` is The operator returns `true` if and only if point `p` is
contained in the affine space spanned by the points in the range `[start, end)`. That affine space is also called the <I>affine hull</I> of the points contained in the affine space spanned by the points in the range `[start, end)`. That affine space is also called the <I>affine hull</I> of the points
in the range. in the range.
\pre If `Dimension`=`CGAL::``Dimension_tag<D>`, \pre If `Dimension`=`CGAL::Dimension_tag<D>`,
then `std::distance(start,end)=D+1`. then `std::distance(start,end)=D+1`.
The points in the range The points in the range
must be affinely independent. Note that in the CGAL kernels, this predicate must be affinely independent. Note that in the CGAL kernels, this predicate
@ -97,7 +97,7 @@ the range `R=[start, end)` can be oriented in two different ways,
the operator the operator
returns an object that allow to orient that flat so that `R=[start, end)` returns an object that allow to orient that flat so that `R=[start, end)`
defines a positive simplex. defines a positive simplex.
\pre If `Dimension`=`CGAL::``Dimension_tag<D>`, \pre If `Dimension`=`CGAL::Dimension_tag<D>`,
then `std::distance(start,end)=D+1`. then `std::distance(start,end)=D+1`.
The points in range The points in range
`[start,end)` must be affinely independent. `[start,end)` must be affinely independent.
@ -137,7 +137,9 @@ typedef unspecified_type Compare_lexicographically_d;
/// @{ /// @{
/*! /*!
The default constructor. The default constructor (optional).
This is not required when an instance of the traits is provided
to the constructor of `CGAL::Triangulation`.
*/ */
TriangulationTraits(); TriangulationTraits();

View File

@ -4,7 +4,7 @@
\cgalConcept \cgalConcept
The concept `TriangulationVertex` describes the requirements on the type used by the The concept `TriangulationVertex` describes the requirements on the type used by the
class `CGAL::Triangulation<TriangulationTraits, TriangulationDataStructure>`, and its derived classes, to class `CGAL::Triangulation<TriangulationTraits_, TriangulationDataStructure_>`, and its derived classes, to
represent a vertex. represent a vertex.
\cgalRefines `TriangulationDSVertex` \cgalRefines `TriangulationDSVertex`
@ -12,7 +12,7 @@ We only list below the additional specific requirements of ::TriangulationVertex
Compared to ::TriangulationDSVertex, the main difference is the addition of Compared to ::TriangulationDSVertex, the main difference is the addition of
an association of the vertex with a geometric point. an association of the vertex with a geometric point.
\cgalHasModel `CGAL::Triangulation_vertex<TriangulationTraits, Data, TriangulationDSVertex> ` \cgalHasModel `CGAL::Triangulation_vertex<TriangulationTraits_, Data, TriangulationDSVertex_>`
Input/Output Input/Output
-------------- --------------
@ -20,9 +20,9 @@ Input/Output
These operators can be used directly and are called by the I/O These operators can be used directly and are called by the I/O
operator of class `Triangulation`. operator of class `Triangulation`.
\sa `CGAL::Triangulation_vertex<TriangulationTraits, Data, TriangulationDSVertex>` \sa `CGAL::Triangulation_vertex<TriangulationTraits_, Data, TriangulationDSVertex_>`
\sa `TriangulationFullCell` \sa `TriangulationFullCell`
\sa `CGAL::Triangulation<TriangulationTraits, TriangulationDataStructure>` \sa `CGAL::Triangulation<TriangulationTraits_, TriangulationDataStructure_>`
*/ */
@ -36,7 +36,7 @@ public:
The type of the point stored in the vertex. It must be The type of the point stored in the vertex. It must be
the same as the point type `TriangulationTraits::Point` (or its refined the same as the point type `TriangulationTraits::Point` (or its refined
concepts) when the `TriangulationVertex` is used in the class concepts) when the `TriangulationVertex` is used in the class
`Triangulation<TriangulationTraits, TriangulationDataStructure>` (or its derived classes). `Triangulation<TriangulationTraits_, TriangulationDataStructure_>` (or its derived classes).
*/ */
typedef unspecified_type Point; typedef unspecified_type Point;

View File

@ -5,6 +5,9 @@
/// \defgroup PkgTriangulationsTriangulationClasses Triangulation Classes /// \defgroup PkgTriangulationsTriangulationClasses Triangulation Classes
/// \ingroup PkgTriangulations /// \ingroup PkgTriangulations
/// \defgroup PkgTriangulationsTraitsClasses Traits Classes
/// \ingroup PkgTriangulations
/// \defgroup PkgTriangulationsVertexCellClasses Vertex, Face and Cell Classes /// \defgroup PkgTriangulationsVertexCellClasses Vertex, Face and Cell Classes
/// \ingroup PkgTriangulations /// \ingroup PkgTriangulations
@ -13,7 +16,7 @@
\cgalPkgDescriptionBegin{dD Triangulations,PkgTriangulationsSummary} \cgalPkgDescriptionBegin{dD Triangulations,PkgTriangulationsSummary}
\cgalPkgPicture{Hypertriangle.png} \cgalPkgPicture{Hypertriangle.png}
\cgalPkgSummaryBegin \cgalPkgSummaryBegin
\cgalPkgAuthors{Samuel Hornus, Olivier Devillers and Clément Jamin} \cgalPkgAuthors{Olivier Devillers, Samuel Hornus, and Clément Jamin}
\cgalPkgDesc{This package provides classes for manipulating \cgalPkgDesc{This package provides classes for manipulating
triangulations (pure simplicial complexes) in Euclidean spaces whose dimension triangulations (pure simplicial complexes) in Euclidean spaces whose dimension
can be specified at compile-time or at run-time. Specifically, it provides a can be specified at compile-time or at run-time. Specifically, it provides a
@ -84,6 +87,7 @@ is opposite to the vertex with the same index.
- `TriangulationTraits` - `TriangulationTraits`
- `DelaunayTriangulationTraits` - `DelaunayTriangulationTraits`
- `RegularTriangulationTraits`
- `TriangulationVertex` - `TriangulationVertex`
- `TriangulationFullCell` - `TriangulationFullCell`
@ -93,17 +97,22 @@ The latter two concepts are also abbreviated respectively as `TrVertex` and `TrF
## Triangulation Data Structure ## ## Triangulation Data Structure ##
- `CGAL::Triangulation_data_structure<Dimensionality, TriangulationDSVertex, TriangulationDSFullCell>` - `CGAL::Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`
- `CGAL::Triangulation_ds_vertex<TriangulationDataStructure>` - `CGAL::Triangulation_ds_vertex<TriangulationDataStructure_>`
- `CGAL::Triangulation_ds_full_cell<TriangulationDataStructure, TriangulationDSFullCellStoragePolicy>` - `CGAL::Triangulation_ds_full_cell<TriangulationDataStructure_, TriangulationDSFullCellStoragePolicy>`
- `CGAL::Triangulation_face<TriangulationDataStructure>` - `CGAL::Triangulation_face<TriangulationDataStructure_>`
## (Geometric) Triangulations ## ## (Geometric) Triangulations ##
- `CGAL::Triangulation<TriangulationTraits, TriangulationDataStructure>` - `CGAL::Triangulation<TriangulationTraits_, TriangulationDataStructure_>`
- `CGAL::Delaunay_triangulation<DelaunayTriangulationTraits, TriangulationDataStructure>` - `CGAL::Delaunay_triangulation<DelaunayTriangulationTraits_, TriangulationDataStructure_>`
- `CGAL::Triangulation_vertex<TriangulationTraits, Data, TriangulationDSVertex>` - `CGAL::Regular_triangulation<RegularTriangulationTraits_, TriangulationDataStructure_>`
- `CGAL::Triangulation_full_cell<TriangulationTraits, Data, TriangulationDSFullCell>` - `CGAL::Triangulation_vertex<TriangulationTraits_, Data, TriangulationDSVertex_>`
- `CGAL::Triangulation_full_cell<TriangulationTraits_, Data, TriangulationDSFullCell_>`
## Traits Classes ##
- `CGAL::Regular_triangulation_traits_adapter<K>`
## Enums ## ## Enums ##

View File

@ -6,17 +6,17 @@ namespace CGAL {
\anchor Chapter_Triangulations \anchor Chapter_Triangulations
\cgalAutoToc \cgalAutoToc
\authors Samuel Hornus, Olivier Devillers and Clément Jamin. \authors Olivier Devillers, Samuel Hornus, and Clément Jamin.
This package proposes data structures and algorithms to compute This package proposes data structures and algorithms to compute
triangulations of points in any dimensions. triangulations of points in any dimensions \cgalCite{boissonnat2009Delaunay}.
The `Triangulation_data_structure` handles the The `Triangulation_data_structure` handles the
combinatorial aspect of triangulations while the geometric classes combinatorial aspect of triangulations while the geometric classes
`Triangulation` and `Delaunay_triangulation` allows to `Triangulation`, `Delaunay_triangulation` and `Regular_triangulation` allow to
compute and maintain triangulations and Delaunay triangulations of compute and maintain triangulations, Delaunay triangulations, and
sets of points. regular triangulations of sets of points.
# Introduction # \section TriangulationSecIntro Introduction
## Some Definitions ## ## Some Definitions ##
@ -30,64 +30,28 @@ The sets in \f$ S\f$ (which are subsets of \f$ V\f$) are called
singular of which is <I>simplex</I>). singular of which is <I>simplex</I>).
A simplex \f$ s\in S\f$ is <I>maximal</I> if it is not a proper subset of some other A simplex \f$ s\in S\f$ is <I>maximal</I> if it is not a proper subset of some other
set in \f$ S\f$. set in \f$ S\f$.
A simplex having \f$ d+1 \f$ vertices is said of dimension \f$ d \f$. A simplex having \f$ k+1 \f$ vertices is said of dimension \f$ k \f$.
An \f$ k\f$-face denotes a \f$ k\f$-dimensional simplex, i.e., a simplex with \f$ k+1\f$
vertices.
The simplicial complex is <I>pure</I> if all the maximal simplices The simplicial complex is <I>pure</I> if all the maximal simplices
have the same dimension. have the same dimension.
A <i>triangulation</i> is a simplicial complex
that is pure, connected and without boundaries nor singularities. The
<i>dimension</i> of the triangulation is the dimension of its maximal
simplices.
<!--- cardinality, i.e., they have the same number of vertices.---> <!--- cardinality, i.e., they have the same number of vertices.--->
In the sequel, we will call these maximal simplices <I>full cells</I>. In the sequel, we will call these maximal simplices <I>full cells</I>.
A <I>face</I> of a simplex is a subset of this simplex. A <I>face</I> of a simplex is a subset of this simplex.
A <I>proper face</I> of a simplex is a strict subset of this simplex. A <I>proper face</I> of a simplex is a strict subset of this simplex.
Two faces \f$ \sigma\f$ and \f$ \sigma'\f$ are <I>incident</I> if and only if
\f$ \sigma'\f$ is a proper face of \f$ \sigma\f$ or <I>vice versa</I>.
A complex has <i>no boundaries</i> if any proper face of a simplex is also a A complex has <i>no boundaries</i> if any proper face of a simplex is also a
proper face of another simplex. proper face of another simplex.
If the vertices are embedded into Euclidean space \f$ \mathbb{R}^d\f$, If the triangulation is of dimension \f$ d \f$, we use the following terminology:<UL>
we deal with
<I>finite simplicial complexes</I> which have slightly different simplices
and additional requirements:
<UL>
<LI>vertices corresponds to points in space.
<LI>a simplex \f$ s\in S\f$ is the convex hull of its vertices.
<LI>the vertices of a simplex \f$ s\in S\f$ are affinely independent.
<LI>the intersection of any two simplices of \f$ S\f$ is a proper face of both
simplices (the empty set counts).
</UL>
See the <A HREF="http://en.wikipedia.org/wiki/Simplicial_complex">wikipedia
entry</A> for more about simplicial complexes.
## What's in this Package? ##
This \cgal package provides three main classes
for creating and manipulating triangulations.
The class `CGAL::Triangulation_data_structure<Dimensionality, TriangulationDSVertex, TriangulationDSFullCell>`
models an <I>abstract triangulation</I>: vertices in this
class are not embedded in Euclidean space but are only of combinatorial
nature. It deals with simplicial complexes
which are pure, connected and without boundaries nor singularities.
The class `CGAL::Triangulation<TriangulationTraits, TriangulationDataStructure>`
describes an embedded triangulation that has as vertices a given set of points.
Methods are provided for the insertion of points in the triangulation, the
traversal of various elements of the triangulation, as well as the localization of a
query point inside the triangulation.
The triangulation covers the convex hull of the set of points.
The class `CGAL::Delaunay_triangulation<DelaunayTriangulationTraits, TriangulationDataStructure>`
builds the Delaunay triangulation of a set of points.
In a Delaunay triangulation, each face has the so-called
<I>Delaunay</I> or <I>empty-ball</I> property: there exists a
circumscribing ball whose interior does not contain
any vertex of the triangulation.
## Further Definitions ##
An \f$ i\f$-face denotes an \f$ i\f$-dimensional simplex, or a simplex with \f$ i+1\f$
vertices. When these vertices are embedded in Euclidean space, they must be
affinely independent.
If the maximal dimension of a simplex in the triangulation is
\f$ d\f$, we use the following terminology:<UL>
<LI><I>face</I>: an \f$ i\f$-face for some \f$ i\in[0,d]\f$; <LI><I>face</I>: an \f$ i\f$-face for some \f$ i\in[0,d]\f$;
<LI><I>vertex</I>: a \f$ 0\f$-face; <LI><I>vertex</I>: a \f$ 0\f$-face;
<LI><I>edge</I>: a \f$ 1\f$-face; <LI><I>edge</I>: a \f$ 1\f$-face;
@ -96,32 +60,69 @@ If the maximal dimension of a simplex in the triangulation is
<LI><I>full cell</I>: a \f$ d\f$-face. <LI><I>full cell</I>: a \f$ d\f$-face.
</UL> </UL>
Two faces \f$ \sigma\f$ and \f$ \sigma'\f$ are <I>incident</I> if and only if If the vertices are embedded into Euclidean space \f$ \mathbb{R}^n\f$,
\f$ \sigma'\f$ is a proper sub-face of \f$ \sigma\f$ or <I>vice versa</I>. we deal with
<I>finite simplicial complexes</I>, which have slightly different simplices
and additional requirements:
<UL>
<LI>vertices correspond to points in space.
<LI>a simplex \f$ s\in S\f$ is the convex hull of its vertices.
<LI>the vertices of a simplex \f$ s\in S\f$ are affinely independent.
<LI>the intersection of any two simplices of \f$ S\f$ is a proper face of both
simplices (the empty set counts).
</UL>
# %Triangulation Data Structure # ## What is Provided in this Package? ##
This \cgal package provides four main classes
for creating and manipulating triangulations.
The class `CGAL::Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`
models an <I>abstract triangulation</I>: vertices in this
class are not embedded in Euclidean space but are only of combinatorial
nature.
The class `CGAL::Triangulation<TriangulationTraits_, TriangulationDataStructure_>`
describes an embedded triangulation that has as vertices a given set of points.
Methods are provided for the insertion of points in the triangulation, the
traversal of various elements of the triangulation, as well as the location of a
query point inside the triangulation.
The triangulation covers the convex hull of the set of points.
The class `CGAL::Delaunay_triangulation<DelaunayTriangulationTraits_, TriangulationDataStructure_>`
builds the Delaunay triangulation of a set of points.
In a Delaunay triangulation, each face has the so-called
<I>Delaunay</I> or <I>empty-ball</I> property: there exists a
circumscribing ball whose interior does not contain
any vertex of the triangulation.
The class `CGAL::Regular_triangulation<RegularTriangulationTraits_, TriangulationDataStructure_>`
builds the regular triangulation
-- also known as weighted Delaunay triangulation -- of a set of points.
A detailed definition of such a triangulation is available in section
\ref TriangulationSecRT.
\section TriangulationSecTDS Triangulation Data Structure
In this section, we describe the concept `TriangulationDataStructure` for In this section, we describe the concept `TriangulationDataStructure` for
which \cgal provides one model class: which \cgal provides one model class:
`CGAL::Triangulation_data_structure<Dimensionality, TriangulationDSVertex, TriangulationDSFullCell>`. `CGAL::Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`.
A `TriangulationDataStructure` can represent an abstract pure complex A triangulation data structure can represent an abstract triangulation.
such that any facet is incident to exactly two full cells.
A `TriangulationDataStructure` has a <!--- property called the ---> The <I>maximal dimension</I> of a triangulation data structure is a
<I>maximal dimension</I> which is a
positive integer equal to the maximum dimension a full cell can have. positive integer equal to the maximum dimension a full cell can have.
This maximal dimension can be chosen by the user at the creation of a This maximal dimension can be chosen by the user at the creation of the
`TriangulationDataStructure` and can then be queried using the method `tds.maximal_dimension()`. triangulation data structure and can then be obtained using the method `tds.maximal_dimension()`.
A `TriangulationDataStructure` also knows the <I>current dimension</I> of its full cells, A triangulation data structure also knows the <I>current dimension</I> of its full cells,
which can be queried with `tds.current_dimension()`. In the sequel, let which can be obtained using `tds.current_dimension()`. In the sequel, let
us denote the maximal dimension with \f$ D \f$ and the current dimension with \f$ d \f$. us denote the maximal dimension with \f$ D \f$ and the current dimension with \f$ d \f$.
The inequalities \f$ -2 \leq d \leq D\f$ and \f$ 0 \le D\f$ always hold. The inequalities \f$ -2 \leq d \leq D\f$ and \f$ 0 < D\f$ always hold.
The special meaning of negative values for \f$d\f$ is explained below. The special meaning of negative values for \f$d\f$ is explained below.
### The Set of Faces ### ## The Set of Faces ##
The set of faces of a `TriangulationDataStructure` with The set of faces of a triangulation data structure with
current dimension \f$ d \f$ forms a triangulation of the current dimension \f$ d \f$ forms a triangulation of the
topological sphere \f$ \mathbb{S}^d\f$. topological sphere \f$ \mathbb{S}^d\f$.
@ -132,7 +133,7 @@ Possible values of \f$d\f$ (the <I>current dimension</I> of the triangulation) i
<BLOCKQUOTE> <BLOCKQUOTE>
<DL> <DL>
<DT><B>\f$d=-2\f$</B><DD> This corresponds to an empty <DT><B>\f$d=-2\f$</B><DD> This corresponds to an empty
`TriangulationDataStructure`. triangulation data structure.
<DT><B>\f$d=-1\f$</B><DD> This corresponds to an abstract simplicial <DT><B>\f$d=-1\f$</B><DD> This corresponds to an abstract simplicial
complex reduced to a single vertex. complex reduced to a single vertex.
<!--- and a single full cell. In a geometric triangulation, this vertex corresponds to the vertex at infinity.---> <!--- and a single full cell. In a geometric triangulation, this vertex corresponds to the vertex at infinity.--->
@ -149,16 +150,16 @@ the sphere \f$ \mathbb{S}^d\f$.
## The `Triangulation_data_structure` Class ## ## The `Triangulation_data_structure` Class ##
We give here some details about the class We give here some details about the class
`Triangulation_data_structure<Dimensionality, TriangulationDSVertex, TriangulationDSFullCell>` `Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`
implementing the concept `TriangulationDataStructure`. implementing the concept `TriangulationDataStructure`.
### Storage ### ### Storage ###
A `TriangulationDataStructure` explicitly stores its vertices and full cells. A triangulation data structure explicitly stores its vertices and full cells.
Each vertex stores a reference to one of its incident full cells. Each vertex stores a reference to one of its incident full cells.
Each full cell stores references to its \f$ d+1\f$ vertices and Each full cell \f$ \sigma \f$ stores references to its \f$ d+1\f$ vertices and
neighbors. Its vertices and neighbors are indexed from \f$ 0\f$ to \f$ d \f$. The indices neighbors. Its vertices and neighbors are indexed from \f$ 0\f$ to \f$ d \f$. The indices
of its neighbors have the following meaning: the \f$ i\f$-th neighbor of \f$ \sigma\f$ of its neighbors have the following meaning: the \f$ i\f$-th neighbor of \f$ \sigma\f$
is the unique neighbor of \f$ \sigma\f$ that does not contain the \f$ i\f$-th vertex of is the unique neighbor of \f$ \sigma\f$ that does not contain the \f$ i\f$-th vertex of
@ -190,7 +191,7 @@ indices alongside the references to the vertices and neighbors in a
full cell. This improves speed a little, but requires more memory. full cell. This improves speed a little, but requires more memory.
\cgalAdvanced \cgal provides the class template \cgalAdvanced \cgal provides the class template
`Triangulation_ds_full_cell<TriangulationDataStructure, `Triangulation_ds_full_cell<TriangulationDataStructure_,
TriangulationDSFullCellStoragePolicy>` for representing full cells in a TriangulationDSFullCellStoragePolicy>` for representing full cells in a
triangulation. Its second template parameter is used to specify wether triangulation. Its second template parameter is used to specify wether
or not the mirror indices should be kept in memory or computed or not the mirror indices should be kept in memory or computed
@ -200,41 +201,41 @@ documentation of that class template for specific details.
###Template Parameters### ###Template Parameters###
The `Triangulation_data_structure<Dimensionality, TriangulationDSVertex, TriangulationDSFullCell>` The `Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`
class is designed in such a way that its user can choose class is designed in such a way that its user can choose
<UL> <UL>
<LI>the maximal dimension of the triangulation data structure by specifying the `Dimensionality` template parameter, <LI>the maximal dimension of the triangulation data structure by specifying the `Dimensionality` template parameter,
<LI>the type used to represent vertices by specifying the `TriangulationDSVertex` <LI>the type used to represent vertices by specifying the `TriangulationDSVertex_`
template parameter and template parameter and
<LI>the type used to represent full cells by specifying the <LI>the type used to represent full cells by specifying the
`TriangulationDSFullCell` template parameter. `TriangulationDSFullCell_` template parameter.
</UL> </UL>
The last two parameters have default values and are thus not necessary, unless The last two parameters have default values and are thus not necessary, unless
the user needs custom types (see the reference manual page for this class the user needs custom types (see `Triangulation_data_structure`).
template). The first template parameter, `Dimensionality`, must be The first template parameter, `Dimensionality`, must be one of the following:
one of the following:
<UL> <UL>
<LI>CGAL::`Dimension_tag<D>` for some integer \f$ D \f$. This <LI>`CGAL::Dimension_tag<D>` for some integer \f$ D \f$. This
indicates that the triangulation can store full cells of dimension at most indicates that the triangulation can store full cells of dimension at most
\f$ D \f$. The maximum dimension \f$ D \f$ is known by the compiler, which \f$ D \f$. The maximum dimension \f$ D \f$ is known by the compiler, which
triggers some optimizations. triggers some optimizations.
<LI>CGAL::`Dynamic_dimension_tag`. In this case, the maximum <LI>`CGAL::Dynamic_dimension_tag`. In this case, the maximum
dimension of the full cells must be passed as an integer argument to an instance dimension of the full cells must be passed as an integer argument to an instance
constructor (see `TriangulationDataStructure`). constructor (see `TriangulationDataStructure`).
</UL> </UL>
The `TriangulationDSVertex` and `TriangulationDSFullCell` parameters to the class template The `TriangulationDSVertex_` and `TriangulationDSFullCell_` parameters to the class template
must be models of the concepts `TriangulationDSVertex` and must be models of the concepts `TriangulationDSVertex` and
`TriangulationDSFullCell` respectively. \cgal provides models for these `TriangulationDSFullCell` respectively. \cgal provides models for these
concepts: `Triangulation_ds_vertex<TriangulationDataStructure>` and concepts: `Triangulation_ds_vertex<TriangulationDataStructure_>` and
`Triangulation_ds_full_cell<TriangulationDataStructure, TriangulationDSFullCellStoragePolicy>`, which, as one `Triangulation_ds_full_cell<TriangulationDataStructure_, TriangulationDSFullCellStoragePolicy>`, which, as one
can see, take the `TriangulationDataStructure` as a template parameter in order to get access to can see, take the triangulation data structure as a template parameter in order to get access to
some nested types in `TriangulationDataStructure`. some nested types in `TriangulationDataStructure_`.
The default values are `CGAL::Triangulation_ds_vertex<TDS>` The default values are `CGAL::Triangulation_ds_vertex<TDS>`
and `CGAL::Triangulation_ds_full_cell<TDS>` and `CGAL::Triangulation_ds_full_cell<TDS>`
where `TDS` is the current class `Triangulation_data_structure<Dimensionality, TriangulationDSVertex, TriangulationDSFullCell>` where `TDS` is the current class
`Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`.
<I>This creates a circular dependency</I>, which we resolve in the same way <I>This creates a circular dependency</I>, which we resolve in the same way
as in the \cgal `Triangulation_2` and `Triangulation_3` packages (see as in the \cgal `Triangulation_2` and `Triangulation_3` packages (see
Chapters \ref Chapter_2D_Triangulation_Data_Structure, \ref Chapter_2D_Triangulations, Chapters \ref Chapter_2D_Triangulation_Data_Structure, \ref Chapter_2D_Triangulations,
@ -276,8 +277,7 @@ full cells adjacent to `c` are automatically subdivided to match the
subdivision of the full cell `c`. The barycentric subdivision of `c` is subdivision of the full cell `c`. The barycentric subdivision of `c` is
obtained by enumerating all the faces of `c` in order of decreasing obtained by enumerating all the faces of `c` in order of decreasing
dimension, from the dimension of `c` to dimension 1, and inserting a new dimension, from the dimension of `c` to dimension 1, and inserting a new
vertex in each face. For the enumeration, we use a combination enumerator, vertex in each face.
which is not documented, but provided in \cgal.
\cgalFigureBegin{triangulationfigbarycentric,barycentric-subdivision.png} \cgalFigureBegin{triangulationfigbarycentric,barycentric-subdivision.png}
Barycentric subdivision in dimension \f$ d=2\f$. Barycentric subdivision in dimension \f$ d=2\f$.
@ -285,9 +285,9 @@ Barycentric subdivision in dimension \f$ d=2\f$.
\cgalExample{barycentric_subdivision.cpp} \cgalExample{barycentric_subdivision.cpp}
# Triangulations # \section TriangulationSecTriangulations Triangulations
The class `CGAL::Triangulation<TriangulationTraits, TriangulationDataStructure>` The class `CGAL::Triangulation<TriangulationTraits_, TriangulationDataStructure_>`
maintains a triangulation embedded in Euclidean space. The triangulation maintains a triangulation embedded in Euclidean space. The triangulation
covers the convex hull of the input points (the embedded vertices of the covers the convex hull of the input points (the embedded vertices of the
triangulation). triangulation).
@ -300,39 +300,39 @@ Each infinite \f$ i\f$-simplex is
incident to the infinite vertex and to an \f$ (i-1)\f$-simplex of the incident to the infinite vertex and to an \f$ (i-1)\f$-simplex of the
convex hull boundary. convex hull boundary.
See Chapters \ref Chapter_2D_Triangulations "2D Triangulations" and See Chapters \ref Chapter_2D_Triangulations "2D Triangulations" or
\ref Chapter_3D_Triangulations "3D Triangulations" for more details \ref Chapter_3D_Triangulations "3D Triangulations" for more details
about infinite vertices and cells. about infinite vertices and cells.
Methods are provided for the insertion of points in the triangulation, the Methods are provided for the insertion of points in the triangulation, the
contraction of faces, the traversal of various elements of the triangulation contraction of faces, the traversal of various elements of the triangulation
as well as the localization of a query point inside the triangulation. as well as the location of a query point inside the triangulation.
The ordering of the vertices of a full cell defines an orientation of The ordering of the vertices of a full cell defines an orientation of
that full cell. that full cell.
As long as no <I>advanced</I> class method is called, it is guaranteed As long as no <I>advanced</I> class method is called, it is guaranteed
that all finite full cells have positive orientation. The infinite full that all finite full cells have positive orientation. Each infinite full
cells are oriented as if the infinite vertex was on the other side cell is oriented as if its infinite vertex was on the side of
of the hyperplane supported by the convex hull facets that the other points. the hyperplane supported by its finite facet where there is no other point.
## Implementation ## ## Implementation ##
The class `CGAL::Triangulation<TriangulationTraits, TriangulationDataStructure>` The class `CGAL::Triangulation<TriangulationTraits_, TriangulationDataStructure_>`
stores a model of the concept `TriangulationDataStructure` which is stores a model of the concept `TriangulationDataStructure` that is
instantiated with a vertex type that stores a point. instantiated with a vertex type that stores a point.
The template parameter `TriangulationTraits` must be a model of the concept The template parameter `TriangulationTraits_` must be a model of the concept
`TriangulationTraits` which provides the `Point` type as well `TriangulationTraits`, which provides the point type as well
as various geometric predicates used by the `Triangulation` class. as various geometric predicates used by the `Triangulation` class.
The `TriangulationTraits` concept includes a nested type The `TriangulationTraits` concept includes a nested type
`TriangulationTraits::Dimension` which is the dimension of the predicates. `TriangulationTraits::Dimension`. This dimension governs the number of points
This dimension governs the number of points given as arguments to the given as arguments to the predicates. This type is either
predicates. This type is either `CGAL::Dimension_tag<D>` or `CGAL::Dimension_tag<D>` or `CGAL::Dynamic_dimension_tag`.
`CGAL::Dynamic_dimension_tag`. In any case, the dimension of the traits In any case, the dimension of the traits
must match the maximal dimension of the `TriangulationDataStructure`. must match the maximal dimension of the triangulation data structure.
The template parameter `TriangulationDataStructure` must be a model of the concept The template parameter `TriangulationDataStructure_` must be a model of the concept
`TriangulationDataStructure` which provides the triangulation data `TriangulationDataStructure` which provides the triangulation data
structure as described in the previous section. structure as described in the previous section.
@ -382,11 +382,11 @@ One important difference between the two examples above is that the first uses
visits <I>only</I> the infinite full cells but stores handles to them into the visits <I>only</I> the infinite full cells but stores handles to them into the
<I>potentially big</I> array <tt>infinite_full_cells</tt>. <I>potentially big</I> array <tt>infinite_full_cells</tt>.
# Delaunay Triangulations # \section TriangulationSecDT Delaunay Triangulations
The class `CGAL::Delaunay_triangulation<DelaunayTriangulationTraits, TriangulationDataStructure>` derives from The class `CGAL::Delaunay_triangulation<DelaunayTriangulationTraits_, TriangulationDataStructure_>` derives from
`CGAL::Triangulation<DelaunayTriangulationTraits, TriangulationDataStructure>` `CGAL::Triangulation<DelaunayTriangulationTraits_, TriangulationDataStructure_>`
and represent Delaunay triangulations. and represents Delaunay triangulations.
A <I>circumscribing ball</I> of a simplex is a ball A <I>circumscribing ball</I> of a simplex is a ball
having all vertices of the simplex on its boundary. having all vertices of the simplex on its boundary.
@ -396,8 +396,8 @@ circumscribing ball whose interior does not contain
any vertex of the triangulation. any vertex of the triangulation.
In case of degeneracies (co-spherical points) the triangulation is not In case of degeneracies (co-spherical points) the triangulation is not
uniquely defined. Note however that the \cgal implementation computes a unique uniquely defined. Note however that the CGAL implementation computes a
triangulation even in these cases. unique triangulation even in these cases.
When a new point `p` is inserted into a Delaunay triangulation, the When a new point `p` is inserted into a Delaunay triangulation, the
full cells whose circumscribing ball contains `p` are said to full cells whose circumscribing ball contains `p` are said to
@ -409,20 +409,23 @@ in the conflict zone are removed, leaving a hole that contains `p`. That
hole is ``star shaped'' around `p` and thus is re-triangulated using hole is ``star shaped'' around `p` and thus is re-triangulated using
`p` as a center vertex. `p` as a center vertex.
Delaunay triangulations also support vertex removal. Delaunay triangulations support insertion of points, removal of vertices,
and location of a query point inside the triangulation.
Note that inserting a large set of points at once is much faster
than inserting the same points one by one.
## Implementation ## ## Implementation ##
The class `CGAL::Delaunay_triangulation<DelaunayTriangulationTraits, TriangulationDataStructure>` derives from The class `CGAL::Delaunay_triangulation<DelaunayTriangulationTraits_, TriangulationDataStructure_>` derives from
`CGAL::Triangulation<DelaunayTriangulationTraits, TriangulationDataStructure>`. It thus stores a model of `CGAL::Triangulation<DelaunayTriangulationTraits_, TriangulationDataStructure_>`. It thus stores a model of
the concept `TriangulationDataStructure` which is instantiated with a vertex the concept `TriangulationDataStructure`, which is instantiated with a vertex
type that stores a geometric point and allows its retrieval. type that stores a geometric point and allows its retrieval.
The template parameter `DelaunayTriangulationTraits` must be a model of the concept The template parameter `DelaunayTriangulationTraits_` must be a model of the concept
`DelaunayTriangulationTraits` which provides the geometric `Point` type as `DelaunayTriangulationTraits` which provides the geometric `Point` type as
well as various geometric predicates used by the `Delaunay_triangulation` class. well as various geometric predicates used by the `Delaunay_triangulation` class.
The concept `DelaunayTriangulationTraits` refines the concept The concept `DelaunayTriangulationTraits` refines the concept
`TriangulationTraits` by requiring a few other geometric predicates, necessary `TriangulationTraits` by requiring a few additional geometric predicates, necessary
for the computation of Delaunay triangulations. for the computation of Delaunay triangulations.
## Examples ## ## Examples ##
@ -438,55 +441,150 @@ retaining an efficient update of the Delaunay triangulation.
\cgalExample{delaunay_triangulation.cpp} \cgalExample{delaunay_triangulation.cpp}
# Complexity and Performances # \section TriangulationSecRT Regular Triangulations
The current implementation locates points by walking in the The class `CGAL::Regular_triangulation<RegularTriangulationTraits_, TriangulationDataStructure_>` derives from
triangulation, and sorts the points with spatial sort to insert a `CGAL::Triangulation<RegularTriangulationTraits_, TriangulationDataStructure_>`
set of points. Thus the theoretical complexity are and represents regular triangulations.
\f$ O(n\log n)\f$ for inserting \f$ n\f$ random points and \f$ O(n^{\frac{1}{d}})\f$
for inserting one point in a triangulation of \f$ n\f$ random points.
In the worst case, the expected complexity is
\f$ O(n^{\lceil\frac{d}{2}\rceil}+n\log n)\f$.
We provide below (Figure \cgalFigureRef{Triangulationfigbenchmarks}) the Regular triangulations are also known as weighted Delaunay triangulations.
Let \f$ {S}^{(w)}\f$ be a set of weighted points in \f$ \mathbb{R}^D\f$. Let
\f$ {p}^{(w)}=(p,w_p), p\in\mathbb{R}^D, w_p\in\mathbb{R}\f$ and
\f$ {z}^{(w)}=(z,w_z), z\in\mathbb{R}^D, w_z\in\mathbb{R}\f$
be two weighted points.
A weighted point \f$ {p}^{(w)}=(p,w_p)\f$ can also be seen as a sphere of
center \f$ p\f$ and radius \f$ \sqrt{w_p}\f$.
The <I>power product</I> (or <I>power distance</I> )
between \f$ {p}^{(w)}\f$ and \f$ {z}^{(w)}\f$ is
defined as
\f[ \Pi({p}^{(w)},{z}^{(w)}) = {\|{p-z}\|^2-w_p-w_z} \f]
where \f$ \|{p-z}\|\f$ is the Euclidean distance between \f$ p\f$ and \f$ z\f$.
\f$ {p}^{(w)}\f$ and \f$ {z}^{(w)}\f$
are said to be <I>orthogonal</I> if \f$ \Pi({p}^{(w)},{z}^{(w)})
= 0\f$.
\f$D + 1\f$ weighted points have a unique common orthogonal weighted point
called the <I>power sphere</I>. A sphere \f$ {z}^{(w)}\f$ is said to be
<I>regular</I> if \f$ \forall {p}^{(w)}\in{S}^{(w)},
\Pi({p}^{(w)},{z}^{(w)})\geq 0\f$.
A triangulation of \f$ {S}^{(w)}\f$ is <I>regular</I> if the power spheres
of all simplices are regular.
Note that as a result, some points can be hidden and do not result in vertices
in the triangulation. Those points are discarded and cannot be retrieved.
A weighted point `p` is said to be in conflict
with a simplex `s` if it has a negative power distance to the power sphere of `s`.
Regular triangulations support insertion of weighted points,
and location of a query point inside the triangulation.
Note that inserting a large set of points at once is much faster
than inserting the same points one by one.
\warning The removal of vertices is not supported yet.
## Implementation ##
The class `CGAL::Regular_triangulation<RegularTriangulationTraits_, TriangulationDataStructure_>` derives from
`CGAL::Triangulation<RegularTriangulationTraits_, TriangulationDataStructure_>`. It thus stores a model of
the concept `TriangulationDataStructure_` which is instantiated with a vertex
type that stores a weighted point and allows its retrieval.
The template parameter `RegularTriangulationTraits_` must be a model of the concept
`RegularTriangulationTraits`. It must provide the `%Weighted_point_d`
type as well as various geometric predicates used by the
`Regular_triangulation` class.
The concept `RegularTriangulationTraits` refines the concept
`TriangulationTraits`.
## Example ##
This simple example shows how to create a regular triangulation.
\cgalExample{regular_triangulation.cpp}
\section TriangulationSecPerf Complexity and Performances
When inserting a batch of points into a Delaunay triangulation,
the current implementation starts by spatially sorting the points.
Then, for each point to insert, it locates it by walking in the triangulation,
using the previously inserted vertex as a "hint". Finally, the point is
inserted.
In the worst case scenario, without spatial sort, the expected complexity is
\f$ O(n^{\lceil\frac{d}{2}\rceil+1}) \f$.
When the algorithm is run on uniformly distributed points, the localization complexity is
\f$ O(n^{\frac{1}{d}}) \f$ and the size of the triangulation is \f$ O(n) \f$, which gives
a complexity of \f$ O(n^{1+\frac{1}{d}}) \f$ for the insertion.
With spatial sort and random points, one can expect a complexity of \f$ O(n\log n) \f$.
Please refer to \cgalCite{boissonnat2009Delaunay} for more details.
We provide below (\cgalFigureRef{Triangulationfigbenchmarks100},
\cgalFigureRef{Triangulationfigbenchmarks1000} and
\cgalFigureRef{triangulationfigbenchmarkchart}) the
performance of the Delaunay triangulation on randomly distributed points. performance of the Delaunay triangulation on randomly distributed points.
The machine used is a PC running The machine used is a PC running
Windows 7 64-bits with an Intel Xeon CPU clocked at 2.80 GHz with 32GB of RAM. Windows 7 64-bits with an Intel Xeon CPU clocked at 2.80 GHz with 32GB of RAM.
The program has been compiled with Microsoft Visual C++ 2012 in Release mode. The program has been compiled with Microsoft Visual C++ 2013 in Release mode.
\cgalFigureAnchor{Triangulationfigbenchmarks}
\cgalFigureAnchor{Triangulationfigbenchmarks100}
<CENTER> <CENTER>
<TABLE CELLSPACING=15> <TABLE CELLSPACING=15 align=center>
<tr><td ALIGN=LEFT NOWRAP COLSPAN=13><HR></td></tr>
<tr><th ALIGN=RIGHT NOWRAP>Dimension</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th><th>9</th><th>10</th><th>11</th><th>12</th></tr>
<tr><td ALIGN=LEFT NOWRAP COLSPAN=13><HR></td></tr>
<tr align=center><td align=right>Time (s)</td><td>0.003</td><td>0.007</td><td>0.03</td><td>0.14</td><td>0.56</td><td>2.7</td><td>11.3</td><td>45</td><td>185</td><td>686</td><td>2390</td></tr>
<tr align=center><td align=right>Memory (MB)</td><td>< 1</td><td>< 1</td><td>< 1</td><td>1</td><td>3</td><td>13</td><td>53</td><td>182</td><td>662</td><td>2187</td><td>7156</td></tr>
<tr align=center><td align=right>Number of maximal simplices</td><td>184</td><td>487</td><td>1,548</td><td>5,548</td><td>19,598</td><td>67,102</td><td>230,375</td><td>715,984</td><td>2,570,623</td><td>7,293,293</td><td>21,235,615</td></tr>
<tr align=center><td align=right>Number of convex hull facets</td><td>14</td><td>66</td><td>308</td><td>1,164</td><td>4,410</td><td>16,974</td><td>57,589</td><td>238,406</td><td>670,545</td><td>2,574,326</td><td>8,603,589</td></tr></td><td>
<tr><td ALIGN=LEFT NOWRAP COLSPAN=13><HR></td></tr>
</TABLE>
</CENTER>
\cgalFigureCaptionBegin{Triangulationfigbenchmarks100}
Performance of the insertion of 100 points in a Delaunay triangulation.
\cgalFigureCaptionEnd
\cgalFigureAnchor{Triangulationfigbenchmarks1000}
<CENTER>
<TABLE CELLSPACING=15 align=center>
<tr><td ALIGN=LEFT NOWRAP COLSPAN=9><HR></td></tr> <tr><td ALIGN=LEFT NOWRAP COLSPAN=9><HR></td></tr>
<tr><th ALIGN=RIGHT NOWRAP>Dimension</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th></tr> <tr><th ALIGN=RIGHT NOWRAP>Dimension</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th></tr>
<tr><td ALIGN=LEFT NOWRAP COLSPAN=9><HR></td></tr> <tr><td ALIGN=LEFT NOWRAP COLSPAN=9><HR></td></tr>
<tr><td>Inserting 100 points</td><td>0.003</td><td>0.007</td><td>0.03</td><td>0.14</td><td>0.56</td><td>2.7</td><td>11.3</td></tr> <tr align=center><td align=right>Time (s)</td><td>0.01</td><td>0.05</td><td>0.5</td><td>3.4</td><td>24</td><td>183</td><td>1365</td></tr>
<tr><td>Inserting 1000 points</td><td>0.015</td><td>0.056</td><td>0.52</td><td>3.5</td><td>26.2</td><td>185</td><td>1385</td></tr> <tr align=center><td align=right>Memory (MB)</td><td>< 1</td><td>< 1</td><td>2.7</td><td>14</td><td>81</td><td>483</td><td>2827</td></tr>
<tr align=center><td align=right>Number of maximal simplices</td><td>1,979</td><td>6,315</td><td>25,845</td><td>122,116</td><td>596,927</td><td>3,133,318</td><td>16,403,337</td></tr>
<tr align=center><td align=right>Number of convex hull facets</td><td>19</td><td>138</td><td>963</td><td>6,184</td><td>41,135</td><td>241,540</td><td>1,406,797</td></tr></td><td>
<tr><td ALIGN=LEFT NOWRAP COLSPAN=9><HR></td></tr> <tr><td ALIGN=LEFT NOWRAP COLSPAN=9><HR></td></tr>
</TABLE> </TABLE>
</CENTER> </CENTER>
\cgalFigureCaptionBegin{Triangulationfigbenchmarks} \cgalFigureCaptionBegin{Triangulationfigbenchmarks1000}
Running times in seconds for algorithms on Delaunay triangulations. Performance of the insertion of 1000 points in a Delaunay triangulation.
\cgalFigureCaptionEnd \cgalFigureCaptionEnd
# Design and Implementation History # \cgalFigureBegin{triangulationfigbenchmarkchart,benchmark_DTd.png}
Running time wrt. number of maximal simplices, for dimensions for 2 to 12.
\cgalFigureEnd
This package is heavily inspired by the works of \section TriangulationSecDesign Design and Implementation History
Monique Teillaud and Sylvain Pion (`Triangulation_3`)
and Mariette Yvinec (`Triangulation_2`).
The first version was written by Samuel Hornus. The final version is a joint
work by Samuel Hornus, Olivier Devillers and Clément Jamin.
Clément Jamin's work was supported by the
<a href="http://cordis.europa.eu/project/rcn/111529_en.html">Advanced Grant of the European Research Council GUDHI</a>
(Geometric Understanding in Higher Dimensions).
Starting with the version 2.3 of \cgal, a package written by Susan Hert and Michael Seel Starting with the version 2.3 of \cgal, a package written by Susan Hert and Michael Seel
was the first able to deal with triangulation and convex hulls in arbitrary was the first able to deal with triangulation and convex hulls in arbitrary
dimension. It is deprecated since the version 4.6 of \cgal and this package should be used dimension. It is deprecated since the version 4.6 of \cgal and this package should be used
instead. instead.
This package is heavily inspired by the works of
Monique Teillaud and Sylvain Pion (`Triangulation_3`)
and Mariette Yvinec (`Triangulation_2`).
The first version was written by Samuel Hornus. The final version is a joint
work by Samuel Hornus, Olivier Devillers and Clément Jamin. In 2017, Clément
Jamin added the regular triangulations.
Clément Jamin's work was supported by the
<a href="http://cordis.europa.eu/project/rcn/111529_en.html">Advanced Grant of the European Research Council GUDHI</a>
(Geometric Understanding in Higher Dimensions).
*/ */
} /* namespace CGAL */ } /* namespace CGAL */

View File

@ -1,6 +1,7 @@
/*! /*!
\example barycentric_subdivision.cpp \example barycentric_subdivision.cpp
\example delaunay_triangulation.cpp \example delaunay_triangulation.cpp
\example regular_triangulation.cpp
\example triangulation.cpp \example triangulation.cpp
\example triangulation1.cpp \example triangulation1.cpp
\example triangulation2.cpp \example triangulation2.cpp

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

View File

@ -22,6 +22,8 @@ if ( CGAL_FOUND )
create_single_source_cgal_program( "barycentric_subdivision.cpp" ) create_single_source_cgal_program( "barycentric_subdivision.cpp" )
create_single_source_cgal_program( "delaunay_triangulation.cpp" ) create_single_source_cgal_program( "delaunay_triangulation.cpp" )
create_single_source_cgal_program( "convex_hull.cpp" )
create_single_source_cgal_program( "regular_triangulation.cpp" )
create_single_source_cgal_program( "triangulation.cpp" ) create_single_source_cgal_program( "triangulation.cpp" )
create_single_source_cgal_program( "triangulation_data_structure_dynamic.cpp" ) create_single_source_cgal_program( "triangulation_data_structure_dynamic.cpp" )
create_single_source_cgal_program( "triangulation_data_structure_static.cpp" ) create_single_source_cgal_program( "triangulation_data_structure_static.cpp" )

View File

@ -1,5 +1,5 @@
#include <CGAL/Triangulation_data_structure.h> #include <CGAL/Triangulation_data_structure.h>
#include <CGAL/internal/Combination_enumerator.h> #include <CGAL/Combination_enumerator.h>
#include <CGAL/assertions.h> #include <CGAL/assertions.h>
#include <iostream> #include <iostream>
@ -34,8 +34,8 @@ void barycentric_subdivide(TDS & tds, typename TDS::Full_cell_handle fc)
face_vertices.resize(d+1); face_vertices.resize(d+1);
// The following class // The following class
// enumerates all (d+1)-tuple of the set {0, 1, ..., dim} // enumerates all (d+1)-tuple of the set {0, 1, ..., dim}
CGAL::internal::Combination_enumerator combi(d+1, 0, dim); CGAL::Combination_enumerator<unsigned int> combi(d+1, 0, dim);
while( ! combi.end() ) while ( !combi.finished() )
{ {
for( int i = 0; i <= d; ++i ) for( int i = 0; i <= d; ++i )
face_vertices[i] = vertices[combi[i]]; face_vertices[i] = vertices[combi[i]];

View File

@ -0,0 +1,70 @@
#include <CGAL/Epick_d.h>
#include <CGAL/point_generators_d.h>
#include <CGAL/Delaunay_triangulation.h>
#include <CGAL/algorithm.h>
#include <CGAL/Timer.h>
#include <CGAL/assertions.h>
#include <iostream>
#include <iterator>
#include <vector>
const int D = 10;
typedef CGAL::Epick_d< CGAL::Dimension_tag<D> > K;
typedef CGAL::Delaunay_triangulation<K> T;
// The triangulation uses the default instanciation of the
// TriangulationDataStructure template parameter
int main(int argc, char **argv)
{
int N = 100; // number of points
if (argc > 1)
N = atoi(argv[1]);
CGAL::Timer cost; // timer
// Generate N random points
typedef CGAL::Random_points_in_cube_d<T::Point> Random_points_iterator;
Random_points_iterator rand_it(D, 1.0, CGAL::get_default_random());
std::vector<T::Point> points;
CGAL::cpp11::copy_n(rand_it, N, std::back_inserter(points));
T t(D);
CGAL_assertion(t.empty());
// insert the points in the triangulation, only if they are outside the
// convex hull
std::cout << " Convex hull of "<<N<<" points in dim " << D << std::flush;
cost.reset();
cost.start();
// Spatial sort points to speed-up localization
CGAL::spatial_sort(points.begin(), points.end(), t.geom_traits());
int c = 0;
T::Full_cell_handle hint;
for (std::vector<T::Point>::iterator it_p = points.begin() ;
it_p != points.end() ; ++it_p)
{
T::Locate_type lt;
T::Face f(t.maximal_dimension());
T::Facet ft;
T::Full_cell_handle fch = t.locate(*it_p, lt, f, ft, hint);
if (lt == T::OUTSIDE_CONVEX_HULL || lt == T::OUTSIDE_AFFINE_HULL)
{
hint = t.insert(*it_p, lt, f, ft, fch)->full_cell();
++c;
}
else
{
hint = fch;
}
}
std::cout << " done in " << cost.time() << " seconds.\n";
std::cout << c << " points where actually inserted.\n";
CGAL_assertion( t.is_valid() );
return 0;
}

View File

@ -9,69 +9,42 @@ int main()
#else #else
#include <CGAL/Epick_d.h> #include <CGAL/Epick_d.h>
#include <CGAL/point_generators_d.h>
#include <CGAL/Delaunay_triangulation.h> #include <CGAL/Delaunay_triangulation.h>
#include <CGAL/algorithm.h>
#include <CGAL/Timer.h>
#include <CGAL/assertions.h>
#include <iostream> int main()
#include <iterator>
#include <vector>
const int D=5;
typedef CGAL::Epick_d< CGAL::Dimension_tag<D> > K;
typedef CGAL::Delaunay_triangulation<K> T;
// The triangulation uses the default instanciation of the
// TriangulationDataStructure template parameter
int main(int argc, char **argv)
{ {
int N = 100; if( argc > 2 )N = atoi(argv[1]); // number of points double pointsIn[][7] = {
CGAL::Timer cost; // timer { 42.89, 0, 60.55, 30.72, 0, 0, 0 },
{ 45.65, 50.83, 50.37, 16.13, 0, 0, 0 },
{ 79.06, 57.84, 61.59, 2.52, 0, 0, 0 },
{ 44.47, 39.46, 39.53, 28.72, 0, 0, 0 },
{ 0, 100, 0, 0, 100, 0, 53.47 },
{ 66.95, 100, 33.6, 0, 0, 0, 0 },
{ 42.89, 0, 0, 30.72, 100, 0, 53.47 },
{ 100, 100, 100, 100, 100, 100, 100 }
};
typedef CGAL::Triangulation<CGAL::Epick_d< CGAL::Dimension_tag<7> > > T;
T dt(7);
// Instanciate a random point generator
CGAL::Random rng(0);
typedef CGAL::Random_points_in_cube_d<T::Point> Random_points_iterator;
Random_points_iterator rand_it(D, 1.0, rng);
// Generate N random points
std::vector<T::Point> points; std::vector<T::Point> points;
CGAL::cpp11::copy_n(rand_it, N, std::back_inserter(points)); points.reserve(8);
for (int j = 0; j < 8; ++j) {
T t(D); T::Point p(&pointsIn[j][0], &pointsIn[j][7]);
CGAL_assertion(t.empty()); points.push_back(p);
// insert the points in the triangulation
cost.reset();cost.start();
std::cout << " Delaunay triangulation of "<<N<<" points in dim "<<D<< std::flush;
t.insert(points.begin(), points.end());
std::cout << " done in "<<cost.time()<<" seconds." << std::endl;
CGAL_assertion( t.is_valid() );
// insert with special operations in conflict zone and new created cells
cost.reset();
std::cout << " adding "<<N<<" other points "<< std::endl;
for(int i=0; i<N; ++i)
{
T::Vertex_handle v;
T::Face f(t.current_dimension());
T::Facet ft;
T::Full_cell_handle c;
T::Locate_type lt;
typedef std::vector<T::Full_cell_handle> Full_cells;
Full_cells zone, new_full_cells;
std::back_insert_iterator<Full_cells> out(zone);
c = t.locate(*++rand_it, lt, f, ft, v);
// previously inserted vertex v is used as hint for point location (if defined)
T::Facet ftc = t.compute_conflict_zone(*rand_it, c, out);
std::cout<<i<<" conflict zone of size "<<zone.size()<<" -> "<<std::flush;
out = std::back_inserter(new_full_cells);
CGAL_assertion( t.is_valid() );
v = t.insert_in_hole(*rand_it, zone.begin(), zone.end(), ftc, out);
std::cout<<new_full_cells.size()<<" new cells"<<std::endl;
} }
std::cout << " done in "<<cost.time()<<" seconds." << std::endl; T::Vertex_handle hint;
int i = 0;
for (std::vector<T::Point>::iterator it = points.begin(); it != points.end(); ++it) {
if (T::Vertex_handle() != hint) {
hint = dt.insert(*it, hint);
}
else {
hint = dt.insert(*it);
}
printf("Processing: %d/%d\n", ++i, (int)points.size());
}
return 0; return 0;
} }

View File

@ -0,0 +1,41 @@
#include <CGAL/Epick_d.h>
#include <CGAL/point_generators_d.h>
#include <CGAL/Regular_triangulation.h>
#include <CGAL/assertions.h>
#include <iostream>
#include <iterator>
#include <vector>
const int D = 5; // Dimension
const int N = 100; // Number of points
typedef CGAL::Epick_d< CGAL::Dimension_tag<D> > K;
typedef CGAL::Regular_triangulation<K> T;
typedef T::Bare_point Bare_point;
typedef T::Weighted_point Weighted_point;
int main()
{
// Instantiate a random point generator
CGAL::Random rng(0);
typedef CGAL::Random_points_in_cube_d<Bare_point> Random_points_iterator;
Random_points_iterator rand_it(D, 1.0, rng);
// Generate N random points
std::vector<Weighted_point> points;
for (int i = 0; i < N; ++i)
points.push_back(Weighted_point(*rand_it++, rng.get_double(0., 10.)));
T t(D);
CGAL_assertion(t.empty());
// Insert the points in the triangulation
t.insert(points.begin(), points.end());
CGAL_assertion( t.is_valid() );
std::cout << "Regular triangulation successfully computed: "
<< t.number_of_vertices() << " vertices, "
<< t.number_of_finite_full_cells() << " finite cells."
<< std::endl;
return 0;
}

View File

@ -59,7 +59,7 @@ class Delaunay_triangulation
public: // PUBLIC NESTED TYPES public: // PUBLIC NESTED TYPES
typedef DCTraits Geom_traits; typedef DCTraits Geom_traits;
typedef typename Base::Triangulation_ds Triangulation_ds; typedef typename Base::Triangulation_ds Triangulation_ds;
typedef typename Base::Vertex Vertex; typedef typename Base::Vertex Vertex;
typedef typename Base::Full_cell Full_cell; typedef typename Base::Full_cell Full_cell;
@ -75,21 +75,27 @@ public: // PUBLIC NESTED TYPES
typedef typename Base::Vertex_const_handle Vertex_const_handle; typedef typename Base::Vertex_const_handle Vertex_const_handle;
typedef typename Base::Vertex_const_iterator Vertex_const_iterator; typedef typename Base::Vertex_const_iterator Vertex_const_iterator;
typedef typename Base::Full_cell_handle Full_cell_handle; typedef typename Base::Full_cell_handle Full_cell_handle;
typedef typename Base::Full_cell_iterator Full_cell_iterator; typedef typename Base::Full_cell_iterator Full_cell_iterator;
typedef typename Base::Full_cell_const_handle Full_cell_const_handle; typedef typename Base::Full_cell_const_handle Full_cell_const_handle;
typedef typename Base::Full_cell_const_iterator Full_cell_const_iterator; typedef typename Base::Full_cell_const_iterator Full_cell_const_iterator;
typedef typename Base::Finite_full_cell_const_iterator
Finite_full_cell_const_iterator;
typedef typename Base::size_type size_type; typedef typename Base::size_type size_type;
typedef typename Base::difference_type difference_type; typedef typename Base::difference_type difference_type;
typedef typename Base::Locate_type Locate_type; typedef typename Base::Locate_type Locate_type;
//Tag to distinguish triangulations with weighted_points
typedef Tag_false Weighted_tag;
protected: // DATA MEMBERS protected: // DATA MEMBERS
public: public:
using typename Base::Rotor;
using Base::maximal_dimension; using Base::maximal_dimension;
using Base::are_incident_full_cells_valid; using Base::are_incident_full_cells_valid;
using Base::coaffine_orientation_predicate; using Base::coaffine_orientation_predicate;
@ -99,11 +105,12 @@ public:
//using Base::incident_full_cells; //using Base::incident_full_cells;
using Base::geom_traits; using Base::geom_traits;
using Base::index_of_covertex; using Base::index_of_covertex;
//using Base::index_of_second_covertex;
using Base::infinite_vertex; using Base::infinite_vertex;
using Base::rotate_rotor;
using Base::insert_in_hole; using Base::insert_in_hole;
using Base::insert_outside_convex_hull_1; using Base::insert_outside_convex_hull_1;
using Base::is_infinite; using Base::is_infinite;
using Base::is_valid;
using Base::locate; using Base::locate;
using Base::points_begin; using Base::points_begin;
using Base::set_neighbors; using Base::set_neighbors;
@ -115,6 +122,8 @@ public:
using Base::full_cell; using Base::full_cell;
using Base::full_cells_begin; using Base::full_cells_begin;
using Base::full_cells_end; using Base::full_cells_end;
using Base::finite_full_cells_begin;
using Base::finite_full_cells_end;
using Base::vertices_begin; using Base::vertices_begin;
using Base::vertices_end; using Base::vertices_end;
// using Base:: // using Base::
@ -147,36 +156,9 @@ private:
}; };
public: public:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - UTILITIES
// A co-dimension 2 sub-simplex. called a Rotor because we can rotate
// the two "covertices" around the sub-simplex. Useful for traversing the
// boundary of a hole. NOT DOCUMENTED
typedef cpp11::tuple<Full_cell_handle, int, int> Rotor;
/*Full_cell_handle full_cell(const Rotor & r) const // NOT DOCUMENTED
{
return cpp11::get<0>(r);
}
int index_of_covertex(const Rotor & r) const // NOT DOCUMENTED
{
return cpp11::get<1>(r);
}
int index_of_second_covertex(const Rotor & r) const // NOT DOCUMENTED
{
return cpp11::get<2>(r);
}*/
Rotor rotate_rotor(Rotor & r) // NOT DOCUMENTED...
{
int opposite = cpp11::get<0>(r)->mirror_index(cpp11::get<1>(r));
Full_cell_handle s = cpp11::get<0>(r)->neighbor(cpp11::get<1>(r));
int new_second = s->index(cpp11::get<0>(r)->vertex(cpp11::get<2>(r)));
return Rotor(s, new_second, opposite);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - CREATION / CONSTRUCTORS // - - - - - - - - - - - - - - - - - - - - - - - - - - CREATION / CONSTRUCTORS
Delaunay_triangulation(int dim, const Geom_traits k = Geom_traits()) Delaunay_triangulation(int dim, const Geom_traits &k = Geom_traits())
: Base(dim, k) : Base(dim, k)
{ {
} }
@ -189,7 +171,7 @@ public:
Delaunay_triangulation( Delaunay_triangulation(
int dim, int dim,
const std::pair<int, const Flat_orientation_d *> &preset_flat_orientation, const std::pair<int, const Flat_orientation_d *> &preset_flat_orientation,
const Geom_traits k = Geom_traits()) const Geom_traits &k = Geom_traits())
: Base(dim, preset_flat_orientation, k) : Base(dim, preset_flat_orientation, k)
{ {
} }
@ -250,8 +232,8 @@ public:
} }
return number_of_vertices() - n; return number_of_vertices() - n;
} }
Vertex_handle insert(const Point &, const Locate_type, const Face &, const Facet &, const Full_cell_handle); Vertex_handle insert(const Point &, Locate_type, const Face &, const Facet &, Full_cell_handle);
Vertex_handle insert(const Point & p, const Full_cell_handle start = Full_cell_handle()) Vertex_handle insert(const Point & p, Full_cell_handle start = Full_cell_handle())
{ {
Locate_type lt; Locate_type lt;
Face f(maximal_dimension()); Face f(maximal_dimension());
@ -259,13 +241,13 @@ public:
Full_cell_handle s = locate(p, lt, f, ft, start); Full_cell_handle s = locate(p, lt, f, ft, start);
return insert(p, lt, f, ft, s); return insert(p, lt, f, ft, s);
} }
Vertex_handle insert(const Point & p, const Vertex_handle hint) Vertex_handle insert(const Point & p, Vertex_handle hint)
{ {
CGAL_assertion( Vertex_handle() != hint ); CGAL_assertion( Vertex_handle() != hint );
return insert(p, hint->full_cell()); return insert(p, hint->full_cell());
} }
Vertex_handle insert_outside_affine_hull(const Point &); Vertex_handle insert_outside_affine_hull(const Point &);
Vertex_handle insert_in_conflicting_cell(const Point &, const Full_cell_handle); Vertex_handle insert_in_conflicting_cell(const Point &, Full_cell_handle);
// - - - - - - - - - - - - - - - - - - - - - - - - - GATHERING CONFLICTING SIMPLICES // - - - - - - - - - - - - - - - - - - - - - - - - - GATHERING CONFLICTING SIMPLICES
@ -275,7 +257,7 @@ public:
Full_cell_const_handle, const OrientationPredicate &) const; Full_cell_const_handle, const OrientationPredicate &) const;
template< typename OutputIterator > template< typename OutputIterator >
Facet compute_conflict_zone(const Point &, const Full_cell_handle, OutputIterator) const; Facet compute_conflict_zone(const Point &, Full_cell_handle, OutputIterator) const;
template < typename OrientationPredicate, typename SideOfOrientedSpherePredicate > template < typename OrientationPredicate, typename SideOfOrientedSpherePredicate >
class Conflict_predicate class Conflict_predicate
@ -345,6 +327,10 @@ public:
} }
}; };
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VALIDITY
bool is_valid(bool verbose = false, int level = 0) const;
private: private:
// Some internal types to shorten notation // Some internal types to shorten notation
typedef typename Base::Coaffine_orientation_d Coaffine_orientation_d; typedef typename Base::Coaffine_orientation_d Coaffine_orientation_d;
@ -357,27 +343,6 @@ private:
Conflict_traversal_pred_in_subspace; Conflict_traversal_pred_in_subspace;
typedef Conflict_traversal_predicate<Conflict_pred_in_fullspace> typedef Conflict_traversal_predicate<Conflict_pred_in_fullspace>
Conflict_traversal_pred_in_fullspace; Conflict_traversal_pred_in_fullspace;
// This is used in the |remove(v)| member function to manage sets of Full_cell_handles
template< typename FCH >
struct Full_cell_set : public std::vector<FCH>
{
typedef std::vector<FCH> Base_set;
using Base_set::begin;
using Base_set::end;
void make_searchable()
{ // sort the full cell handles
std::sort(begin(), end());
}
bool contains(const FCH & fch) const
{
return std::binary_search(begin(), end(), fch);
}
bool contains_1st_and_not_2nd(const FCH & fst, const FCH & snd) const
{
return ( ! contains(snd) ) && ( contains(fst) );
}
};
}; };
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
@ -407,24 +372,14 @@ Delaunay_triangulation<DCTraits, TDS>
return Full_cell_handle(); return Full_cell_handle();
} }
Full_cell_handle left = v->full_cell(); Full_cell_handle left = v->full_cell();
if( is_infinite(left) && left->neighbor(0)->index(left) == 0 ) // we are on the infinite right.
left = left->neighbor(0);
if( 0 == left->index(v) ) if( 0 == left->index(v) )
left = left->neighbor(1); left = left->neighbor(1);
CGAL_assertion( 1 == left->index(v) ); CGAL_assertion( 1 == left->index(v) );
Full_cell_handle right = left->neighbor(0); Full_cell_handle right = left->neighbor(0);
if( ! is_infinite(right) )
{
tds().associate_vertex_with_full_cell(left, 1, right->vertex(1)); tds().associate_vertex_with_full_cell(left, 1, right->vertex(1));
set_neighbors(left, 0, right->neighbor(0), right->mirror_index(0)); set_neighbors(left, 0, right->neighbor(0), right->mirror_index(0));
}
else
{
tds().associate_vertex_with_full_cell(left, 1, left->vertex(0));
tds().associate_vertex_with_full_cell(left, 0, infinite_vertex());
set_neighbors(left, 0, left->neighbor(1), left->mirror_index(1));
set_neighbors(left, 1, right->neighbor(1), right->mirror_index(1));
}
tds().delete_vertex(v); tds().delete_vertex(v);
tds().delete_full_cell(right); tds().delete_full_cell(right);
return left; return left;
@ -432,7 +387,7 @@ Delaunay_triangulation<DCTraits, TDS>
// THE CASE cur_dim >= 2 // THE CASE cur_dim >= 2
// Gather the finite vertices sharing an edge with |v| // Gather the finite vertices sharing an edge with |v|
typedef Full_cell_set<Full_cell_handle> Simplices; typedef typename Base::template Full_cell_set<Full_cell_handle> Simplices;
Simplices simps; Simplices simps;
std::back_insert_iterator<Simplices> out(simps); std::back_insert_iterator<Simplices> out(simps);
tds().incident_full_cells(v, out); tds().incident_full_cells(v, out);
@ -513,24 +468,16 @@ Delaunay_triangulation<DCTraits, TDS>
{ {
int v_idx = (*it)->index(v); int v_idx = (*it)->index(v);
tds().associate_vertex_with_full_cell(*it, v_idx, infinite_vertex()); tds().associate_vertex_with_full_cell(*it, v_idx, infinite_vertex());
if( v_idx != 0 )
{
// we must put the infinite vertex at index 0.
// OK, now with the new convention that the infinite vertex
// does not have to be at index 0, this is not necessary,
// but still, I prefer to keep this piece of code here. [-- Samuel Hornus]
(*it)->swap_vertices(0, v_idx);
// Now, we preserve the positive orientation of the full_cell
(*it)->swap_vertices(current_dimension() - 1, current_dimension());
} }
}
// Make the handles to infinite full cells searchable // Make the handles to infinite full cells searchable
infinite_simps.make_searchable(); infinite_simps.make_searchable();
// Then, modify the neighboring relation // Then, modify the neighboring relation
for( typename Simplices::iterator it = simps.begin(); it != simps.end(); ++it ) for( typename Simplices::iterator it = simps.begin(); it != simps.end(); ++it )
{ {
for( int i = 1; i <= current_dimension(); ++i ) for( int i = 0; i <= current_dimension(); ++i )
{ {
if (is_infinite((*it)->vertex(i)))
continue;
(*it)->vertex(i)->set_full_cell(*it); (*it)->vertex(i)->set_full_cell(*it);
Full_cell_handle n = (*it)->neighbor(i); Full_cell_handle n = (*it)->neighbor(i);
// Was |n| a finite full cell prior to removing |v| ? // Was |n| a finite full cell prior to removing |v| ?
@ -568,7 +515,7 @@ Delaunay_triangulation<DCTraits, TDS>
Dark_s_handle dark_ret_s = dark_s; Dark_s_handle dark_ret_s = dark_s;
Full_cell_handle ret_s; Full_cell_handle ret_s;
typedef Full_cell_set<Dark_s_handle> Dark_full_cells; typedef typename Base::template Full_cell_set<Dark_s_handle> Dark_full_cells;
Dark_full_cells conflict_zone; Dark_full_cells conflict_zone;
std::back_insert_iterator<Dark_full_cells> dark_out(conflict_zone); std::back_insert_iterator<Dark_full_cells> dark_out(conflict_zone);
@ -722,7 +669,7 @@ Delaunay_triangulation<DCTraits, TDS>
template< typename DCTraits, typename TDS > template< typename DCTraits, typename TDS >
typename Delaunay_triangulation<DCTraits, TDS>::Vertex_handle typename Delaunay_triangulation<DCTraits, TDS>::Vertex_handle
Delaunay_triangulation<DCTraits, TDS> Delaunay_triangulation<DCTraits, TDS>
::insert(const Point & p, const Locate_type lt, const Face & f, const Facet &, const Full_cell_handle s) ::insert(const Point & p, Locate_type lt, const Face & f, const Facet &, Full_cell_handle s)
{ {
switch( lt ) switch( lt )
{ {
@ -753,6 +700,15 @@ Delaunay_triangulation<DCTraits, TDS>
} }
} }
/*
[Undocumented function]
Inserts the point `p` in the Delaunay triangulation. Returns a handle to the
(possibly newly created) vertex at that position.
\pre The point `p`
must lie outside the affine hull of the Delaunay triangulation. This implies that
`dt`.`current_dimension()` must be less than `dt`.`maximal_dimension()`.
*/
template< typename DCTraits, typename TDS > template< typename DCTraits, typename TDS >
typename Delaunay_triangulation<DCTraits, TDS>::Vertex_handle typename Delaunay_triangulation<DCTraits, TDS>::Vertex_handle
Delaunay_triangulation<DCTraits, TDS> Delaunay_triangulation<DCTraits, TDS>
@ -774,15 +730,53 @@ Delaunay_triangulation<DCTraits, TDS>
CGAL_assertion( ZERO != o ); CGAL_assertion( ZERO != o );
if( NEGATIVE == o ) if( NEGATIVE == o )
reorient_full_cells(); reorient_full_cells();
// We just inserted the second finite point and the right infinite
// cell is like : (inf_v, v), but we want it to be (v, inf_v) to be
// consistent with the rest of the cells
if (current_dimension() == 1)
{
// Is "inf_v_cell" the right infinite cell?
// Then inf_v_index should be 1
if (inf_v_cell->neighbor(inf_v_index)->index(inf_v_cell) == 0
&& inf_v_index == 0)
{
inf_v_cell->swap_vertices(
current_dimension() - 1, current_dimension());
}
// Otherwise, let's find the right infinite cell
else
{
inf_v_cell = inf_v_cell->neighbor((inf_v_index + 1) % 2);
inf_v_index = inf_v_cell->index(infinite_vertex());
// Is "inf_v_cell" the right infinite cell?
// Then inf_v_index should be 1
if (inf_v_cell->neighbor(inf_v_index)->index(inf_v_cell) == 0
&& inf_v_index == 0)
{
inf_v_cell->swap_vertices(
current_dimension() - 1, current_dimension());
}
}
}
} }
return v; return v;
} }
/*!
[Undocumented function]
Inserts the point `p` in the Delaunay triangulation. Returns a handle to the
(possibly newly created) vertex at that position.
\pre The point `p` must be in conflict with the full cell `c`.
*/
template< typename DCTraits, typename TDS > template< typename DCTraits, typename TDS >
typename Delaunay_triangulation<DCTraits, TDS>::Vertex_handle typename Delaunay_triangulation<DCTraits, TDS>::Vertex_handle
Delaunay_triangulation<DCTraits, TDS> Delaunay_triangulation<DCTraits, TDS>
::insert_in_conflicting_cell(const Point & p, const Full_cell_handle s) ::insert_in_conflicting_cell(const Point & p, Full_cell_handle s)
{ {
CGAL_precondition(is_in_conflict(p, s));
// for storing conflicting full_cells. // for storing conflicting full_cells.
typedef std::vector<Full_cell_handle> Full_cell_h_vector; typedef std::vector<Full_cell_handle> Full_cell_h_vector;
CGAL_STATIC_THREAD_LOCAL_VARIABLE(Full_cell_h_vector,cs,0); CGAL_STATIC_THREAD_LOCAL_VARIABLE(Full_cell_h_vector,cs,0);
@ -876,7 +870,7 @@ template< typename DCTraits, typename TDS >
template< typename OutputIterator > template< typename OutputIterator >
typename Delaunay_triangulation<DCTraits, TDS>::Facet typename Delaunay_triangulation<DCTraits, TDS>::Facet
Delaunay_triangulation<DCTraits, TDS> Delaunay_triangulation<DCTraits, TDS>
::compute_conflict_zone(const Point & p, const Full_cell_handle s, OutputIterator out) const ::compute_conflict_zone(const Point & p, Full_cell_handle s, OutputIterator out) const
{ {
CGAL_precondition( 2 <= current_dimension() ); CGAL_precondition( 2 <= current_dimension() );
if( current_dimension() < maximal_dimension() ) if( current_dimension() < maximal_dimension() )
@ -895,6 +889,48 @@ Delaunay_triangulation<DCTraits, TDS>
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VALIDITY
template< typename DCTraits, typename TDS >
bool
Delaunay_triangulation<DCTraits, TDS>
::is_valid(bool verbose, int level) const
{
if (!Base::is_valid(verbose, level))
return false;
int dim = current_dimension();
if (dim == maximal_dimension())
{
for (Finite_full_cell_const_iterator cit = this->finite_full_cells_begin() ;
cit != this->finite_full_cells_end() ; ++cit )
{
Full_cell_const_handle ch = cit.base();
for(int i = 0; i < dim+1 ; ++i )
{
// If the i-th neighbor is not an infinite cell
Vertex_handle opposite_vh =
ch->neighbor(i)->vertex(ch->neighbor(i)->index(ch));
if (!is_infinite(opposite_vh))
{
Side_of_oriented_sphere_d side =
geom_traits().side_of_oriented_sphere_d_object();
if (side(Point_const_iterator(ch->vertices_begin()),
Point_const_iterator(ch->vertices_end()),
opposite_vh->point()) == ON_BOUNDED_SIDE)
{
if (verbose)
CGAL_warning_msg(false, "Non-empty sphere");
return false;
}
}
}
}
}
return true;
}
} //namespace CGAL } //namespace CGAL
#endif // CGAL_DELAUNAY_COMPLEX_H #endif // CGAL_DELAUNAY_COMPLEX_H

View File

@ -0,0 +1,320 @@
// Copyright (c) 2014 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL: $
// $Id: $
//
// Author(s) : Clement Jamin
#ifndef CGAL_TRIANGULATION_IO_H
#define CGAL_TRIANGULATION_IO_H
#include <CGAL/Epick_d.h>
#include <CGAL/Triangulation.h>
#include <sstream>
#include <iostream>
namespace CGAL {
namespace Triangulation_IO
{
// TODO: test if the stream is binary or text?
template<typename Traits, typename P>
int
output_point(std::ostream & os, const Traits &traits, const P & p)
{
typedef typename Traits::Compute_coordinate_d Ccd;
const Ccd ccd = traits.compute_coordinate_d_object();
const int dim = traits.point_dimension_d_object()(p);
if (dim > 0)
{
os << ccd(p, 0);
for (int i = 1 ; i < dim ; ++i)
os << " " << CGAL::to_double(ccd(p, i));
}
return dim;
}
// TODO: test if the stream is binary or text?
template<typename Traits, typename P>
int
output_weighted_point(std::ostream & os, const Traits &traits, const P & p,
bool output_weight = true)
{
typedef typename Traits::Compute_coordinate_d Ccd;
typename Traits::Construct_point_d cp =
traits.construct_point_d_object();
typename Traits::Compute_weight_d pt_weight = traits.compute_weight_d_object();
const Ccd ccd = traits.compute_coordinate_d_object();
const int dim = traits.point_dimension_d_object()(p);
if (dim > 0)
{
output_point(os, traits, p);
if (output_weight)
os << " " << pt_weight(p);
}
return dim;
}
// TODO: test if the stream is binary or text?
template<typename Traits, typename FCH>
void
output_full_cell(std::ostream & os, const Traits &traits, const FCH & fch,
bool output_weights = false)
{
typename FCH::value_type::Vertex_handle_iterator vit = fch->vertices_begin();
for( ; vit != fch->vertices_end(); ++vit )
{
int dim;
if (output_weights)
dim = output_weighted_point(os, traits, (*vit)->point());
else
dim = output_point(os, traits, (*vit)->point());
if (dim > 0)
os << std::endl;
}
}
// TODO: test if the stream is binary or text?
/*template<typename Traits, typename P>
void
input_point(std::istream & is, const Traits &traits, P & p)
{
typedef typename Traits::FT FT;
std::vector<FT> coords;
std::string line;
for(;;)
{
if (!std::getline(is, line))
return is;
if (line != "")
break;
}
std::stringstream line_sstr(line);
FT temp;
while (line_sstr >> temp)
coords.push_back(temp);
p = traits.construct_point_d_object()(coords.begin(), coords.end());
}*/
} // namespace Triangulation_IO
///////////////////////////////////////////////////////////////
// TODO: replace these operator>> by an "input_point" function
///////////////////////////////////////////////////////////////
// TODO: test if the stream is binary or text?
template<typename K>
std::istream &
operator>>(std::istream &is, typename Wrap::Point_d<K> & p)
{
typedef typename Wrap::Point_d<K> P;
typedef typename K::FT FT;
std::vector<FT> coords;
std::string line;
for(;;)
{
if (!std::getline(is, line))
return is;
if (line != "")
break;
}
std::stringstream line_sstr(line);
FT temp;
while (line_sstr >> temp)
coords.push_back(temp);
p = P(coords.begin(), coords.end());
return is;
}
// TODO: test if the stream is binary or text?
template<typename K>
std::istream &
operator>>(std::istream &is, typename Wrap::Weighted_point_d<K> & wp)
{
typedef typename Wrap::Point_d<K> P;
typedef typename Wrap::Weighted_point_d<K> WP;
typedef typename K::FT FT;
std::string line;
for(;;)
{
if (!std::getline(is, line))
return is;
if (line != "")
break;
}
std::stringstream line_sstr(line);
FT temp;
std::vector<FT> coords;
while (line_sstr >> temp)
coords.push_back(temp);
typename std::vector<FT>::iterator last = coords.end() - 1;
P p = P(coords.begin(), last);
wp = WP(p, *last);
return is;
}
// TODO: test if the stream is binary or text?
template<typename K>
std::istream &
operator>>(std::istream &is, typename Wrap::Vector_d<K> & v)
{
typedef typename Wrap::Vector_d<K> V;
typedef typename K::FT FT;
std::vector<FT> coords;
std::string line;
for (;;)
{
if (!std::getline(is, line))
return is;
if (line != "")
break;
}
std::stringstream line_sstr(line);
FT temp;
while (line_sstr >> temp)
coords.push_back(temp);
v = V(coords.begin(), coords.end());
return is;
}
template < class GT, class TDS >
std::ostream &
export_triangulation_to_off(std::ostream & os,
const Triangulation<GT,TDS> & tr,
bool in_3D_export_surface_only = false)
{
typedef Triangulation<GT,TDS> Tr;
typedef typename Tr::Vertex_const_handle Vertex_handle;
typedef typename Tr::Finite_vertex_const_iterator Finite_vertex_iterator;
typedef typename Tr::Finite_full_cell_const_iterator Finite_full_cell_iterator;
typedef typename Tr::Full_cell_const_iterator Full_cell_iterator;
typedef typename Tr::Full_cell Full_cell;
typedef typename Full_cell::Vertex_handle_const_iterator Full_cell_vertex_iterator;
if (tr.maximal_dimension() < 2 || tr.maximal_dimension() > 3)
{
std::cerr << "Warning: export_tds_to_off => dimension should be 2 or 3.";
os << "Warning: export_tds_to_off => dimension should be 2 or 3.";
return os;
}
size_t n = tr.number_of_vertices();
std::stringstream output;
// write the vertices
std::map<Vertex_handle, int> index_of_vertex;
int i = 0;
for(Finite_vertex_iterator it = tr.finite_vertices_begin();
it != tr.finite_vertices_end(); ++it, ++i)
{
Triangulation_IO::output_point(output, tr.geom_traits(), it->point());
if (tr.maximal_dimension() == 2)
output << " 0";
output << std::endl;
index_of_vertex[it.base()] = i;
}
CGAL_assertion( i == n );
size_t number_of_triangles = 0;
if (tr.maximal_dimension() == 2)
{
for (Finite_full_cell_iterator fch = tr.finite_full_cells_begin() ;
fch != tr.finite_full_cells_end() ; ++fch)
{
output << "3 ";
for (Full_cell_vertex_iterator vit = fch->vertices_begin() ;
vit != fch->vertices_end() ; ++vit)
{
output << index_of_vertex[*vit] << " ";
}
output << std::endl;
++number_of_triangles;
}
}
else if (tr.maximal_dimension() == 3)
{
if (in_3D_export_surface_only)
{
// Parse boundary facets
for (Full_cell_iterator fch = tr.full_cells_begin() ;
fch != tr.full_cells_end() ; ++fch)
{
if (tr.is_infinite(fch))
{
output << "3 ";
for (Full_cell_vertex_iterator vit = fch->vertices_begin() ;
vit != fch->vertices_end() ; ++vit)
{
if (!tr.is_infinite(*vit))
output << index_of_vertex[*vit] << " ";
}
output << std::endl;
++number_of_triangles;
}
}
}
else
{
// Parse finite cells
for (Finite_full_cell_iterator fch = tr.finite_full_cells_begin() ;
fch != tr.finite_full_cells_end() ; ++fch)
{
output << "3 "
<< index_of_vertex[fch->vertex(0)] << " "
<< index_of_vertex[fch->vertex(1)] << " "
<< index_of_vertex[fch->vertex(2)]
<< std::endl;
output << "3 "
<< index_of_vertex[fch->vertex(0)] << " "
<< index_of_vertex[fch->vertex(2)] << " "
<< index_of_vertex[fch->vertex(3)]
<< std::endl;
output << "3 "
<< index_of_vertex[fch->vertex(1)] << " "
<< index_of_vertex[fch->vertex(2)] << " "
<< index_of_vertex[fch->vertex(3)]
<< std::endl;
output << "3 "
<< index_of_vertex[fch->vertex(0)] << " "
<< index_of_vertex[fch->vertex(1)] << " "
<< index_of_vertex[fch->vertex(3)]
<< std::endl;
number_of_triangles += 4;
}
}
}
os << "OFF \n"
<< n << " "
<< number_of_triangles << " 0\n"
<< output.str();
return os;
}
} //namespace CGAL
#endif // CGAL_TRIANGULATION_IO_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,288 @@
// Copyright (c) 2014 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
// Author(s) : Clement Jamin
#ifndef CGAL_REGULAR_TRIANGULATION_TRAITS_ADAPTER_H
#define CGAL_REGULAR_TRIANGULATION_TRAITS_ADAPTER_H
#include <CGAL/basic.h>
#include <boost/iterator/transform_iterator.hpp>
namespace CGAL {
// Wrapper class to make a model of `RegularTriangulationTraits` easily usable
// by the `Regular_triangulation` class. By using this class:
// - Point_d (used by `Triangulation` and the TDS) becomes a weighted point
// - Predicates and functors such as Less_coordinate_d or Orientation_d
// can be called using weighted points instead of bare points (this is
// needed because `Weighted_point_d` is not convertible to `Point_d`)
// This way, `Triangulation` works perfectly well with weighted points.
template <class K>
class Regular_triangulation_traits_adapter
: public K
{
public:
typedef K Base;
// Required by TriangulationTraits
typedef typename K::Dimension Dimension;
typedef typename K::FT FT;
typedef typename K::Flat_orientation_d Flat_orientation_d;
typedef typename K::Weighted_point_d Point_d;
// Required by RegularTriangulationTraits
typedef typename K::Point_d Bare_point_d;
typedef typename K::Weighted_point_d Weighted_point_d;
typedef typename K::Construct_point_d Construct_point_d;
typedef typename K::Compute_weight_d Compute_weight_d;
typedef typename K::Power_side_of_power_sphere_d Power_side_of_power_sphere_d;
typedef typename K::In_flat_power_side_of_power_sphere_d
In_flat_power_side_of_power_sphere_d;
//===========================================================================
// Custom types
//===========================================================================
// Required by SpatialSortingTraits_d
class Less_coordinate_d
{
const K &m_kernel;
public:
typedef bool result_type;
Less_coordinate_d(const K &kernel)
: m_kernel(kernel) {}
result_type operator()(
Weighted_point_d const& p, Weighted_point_d const& q, int i) const
{
Construct_point_d cp = m_kernel.construct_point_d_object();
return m_kernel.less_coordinate_d_object() (cp(p), cp(q), i);
}
};
//===========================================================================
// Required by TriangulationTraits
class Orientation_d
{
const K &m_kernel;
public:
typedef Orientation result_type;
Orientation_d(const K &kernel)
: m_kernel(kernel) {}
template <typename ForwardIterator>
result_type operator()(ForwardIterator start, ForwardIterator end) const
{
Construct_point_d cp = m_kernel.construct_point_d_object();
return m_kernel.orientation_d_object() (
boost::make_transform_iterator(start, cp),
boost::make_transform_iterator(end, cp)
);
}
};
//===========================================================================
// Required by TriangulationTraits
class Construct_flat_orientation_d
{
const K &m_kernel;
public:
typedef Flat_orientation_d result_type;
Construct_flat_orientation_d(const K &kernel)
: m_kernel(kernel) {}
template <typename ForwardIterator>
result_type operator()(ForwardIterator start, ForwardIterator end) const
{
Construct_point_d cp = m_kernel.construct_point_d_object();
return m_kernel.construct_flat_orientation_d_object() (
boost::make_transform_iterator(start, cp),
boost::make_transform_iterator(end, cp)
);
}
};
//===========================================================================
// Required by TriangulationTraits
class In_flat_orientation_d
{
const K &m_kernel;
public:
typedef Orientation result_type;
In_flat_orientation_d(const K &kernel)
: m_kernel(kernel) {}
template <typename ForwardIterator>
result_type operator()(Flat_orientation_d orient,
ForwardIterator start, ForwardIterator end) const
{
Construct_point_d cp = m_kernel.construct_point_d_object();
return m_kernel.in_flat_orientation_d_object() (
orient,
boost::make_transform_iterator(start, cp),
boost::make_transform_iterator(end, cp)
);
}
};
//===========================================================================
// Required by TriangulationTraits
class Contained_in_affine_hull_d
{
const K &m_kernel;
public:
typedef bool result_type;
Contained_in_affine_hull_d(const K &kernel)
: m_kernel(kernel) {}
template <typename ForwardIterator>
result_type operator()(ForwardIterator start, ForwardIterator end,
const Weighted_point_d & p) const
{
Construct_point_d cp = m_kernel.construct_point_d_object();
return m_kernel.contained_in_affine_hull_d_object() (
boost::make_transform_iterator(start, cp),
boost::make_transform_iterator(end, cp),
cp(p)
);
}
};
//===========================================================================
// Required by TriangulationTraits
class Compare_lexicographically_d
{
const K &m_kernel;
public:
typedef Comparison_result result_type;
Compare_lexicographically_d(const K &kernel)
: m_kernel(kernel) {}
result_type operator()(
const Weighted_point_d & p, const Weighted_point_d & q) const
{
Construct_point_d cp = m_kernel.construct_point_d_object();
return m_kernel.compare_lexicographically_d_object()(cp(p), cp(q));
}
};
//===========================================================================
// Only for Triangulation_off_ostream.h (undocumented)
class Compute_coordinate_d
{
const K &m_kernel;
public:
typedef FT result_type;
Compute_coordinate_d(const K &kernel)
: m_kernel(kernel) {}
result_type operator()(
const Weighted_point_d & p, const int i) const
{
Construct_point_d cp = m_kernel.construct_point_d_object();
return m_kernel.compute_coordinate_d_object()(cp(p), i);
}
};
//===========================================================================
// To satisfy SpatialSortingTraits_d
// and also for Triangulation_off_ostream.h (undocumented)
class Point_dimension_d
{
const K &m_kernel;
public:
typedef int result_type;
Point_dimension_d(const K &kernel)
: m_kernel(kernel) {}
result_type operator()(
const Weighted_point_d & p) const
{
Construct_point_d cp = m_kernel.construct_point_d_object();
return m_kernel.point_dimension_d_object()(cp(p));
}
};
//===========================================================================
// Object creation
//===========================================================================
Less_coordinate_d less_coordinate_d_object() const
{
return Less_coordinate_d(*this);
}
Contained_in_affine_hull_d contained_in_affine_hull_d_object() const
{
return Contained_in_affine_hull_d(*this);
}
Orientation_d orientation_d_object() const
{
return Orientation_d(*this);
}
Construct_flat_orientation_d construct_flat_orientation_d_object() const
{
return Construct_flat_orientation_d(*this);
}
In_flat_orientation_d in_flat_orientation_d_object() const
{
return In_flat_orientation_d(*this);
}
Compare_lexicographically_d compare_lexicographically_d_object() const
{
return Compare_lexicographically_d(*this);
}
Compute_coordinate_d compute_coordinate_d_object() const
{
return Compute_coordinate_d(*this);
}
Point_dimension_d point_dimension_d_object() const
{
return Point_dimension_d(*this);
}
};
} //namespace CGAL
#endif // CGAL_REGULAR_TRIANGULATION_TRAITS_ADAPTER_H

View File

@ -32,6 +32,7 @@
#include <CGAL/Dimension.h> #include <CGAL/Dimension.h>
#include <CGAL/iterator.h> #include <CGAL/iterator.h>
#include <CGAL/Default.h> #include <CGAL/Default.h>
#include <CGAL/Random.h>
#include <boost/iterator/filter_iterator.hpp> #include <boost/iterator/filter_iterator.hpp>
#include <boost/iterator/transform_iterator.hpp> #include <boost/iterator/transform_iterator.hpp>
@ -141,20 +142,20 @@ public:
typedef Maximal_dimension_ Maximal_dimension; typedef Maximal_dimension_ Maximal_dimension;
typedef typename Geom_traits::Point_d Point; typedef typename Geom_traits::Point_d Point;
typedef typename TDS::Vertex_handle Vertex_handle; typedef typename TDS::Vertex_handle Vertex_handle;
typedef typename TDS::Vertex_iterator Vertex_iterator; typedef typename TDS::Vertex_iterator Vertex_iterator;
typedef typename TDS::Vertex_const_handle Vertex_const_handle; typedef typename TDS::Vertex_const_handle Vertex_const_handle;
typedef typename TDS::Vertex_const_iterator Vertex_const_iterator; typedef typename TDS::Vertex_const_iterator Vertex_const_iterator;
typedef typename TDS::Full_cell_handle Full_cell_handle; typedef typename TDS::Full_cell_handle Full_cell_handle;
typedef typename TDS::Full_cell_iterator Full_cell_iterator; typedef typename TDS::Full_cell_iterator Full_cell_iterator;
typedef typename TDS::Full_cell_const_handle Full_cell_const_handle; typedef typename TDS::Full_cell_const_handle Full_cell_const_handle;
typedef typename TDS::Full_cell_const_iterator Full_cell_const_iterator; typedef typename TDS::Full_cell_const_iterator Full_cell_const_iterator;
typedef typename TDS::Facet_iterator Facet_iterator; typedef typename TDS::Facet_iterator Facet_iterator;
typedef typename TDS::size_type size_type; typedef typename TDS::size_type size_type;
typedef typename TDS::difference_type difference_type; typedef typename TDS::difference_type difference_type;
/// The type of location a new point is found lying on /// The type of location a new point is found lying on
enum Locate_type enum Locate_type
@ -184,18 +185,18 @@ public:
protected: // DATA MEMBERS protected: // DATA MEMBERS
Triangulation_ds tds_; Triangulation_ds tds_;
const Geom_traits kernel_; const Geom_traits kernel_;
Vertex_handle infinity_; Vertex_handle infinity_;
mutable std::vector<Oriented_side> orientations_; mutable std::vector<Oriented_side> orientations_;
mutable boost::optional<Flat_orientation_d> flat_orientation_; mutable boost::optional<Flat_orientation_d> flat_orientation_;
// The user can specify a Flat_orientation_d object to be used for // The user can specify a Flat_orientation_d object to be used for
// orienting simplices of a specific dimension // orienting simplices of a specific dimension
// (= preset_flat_orientation_.first) // (= preset_flat_orientation_.first)
// preset_flat_orientation_.first = numeric_limits<int>::max() otherwise) // preset_flat_orientation_.first = numeric_limits<int>::max() otherwise)
std::pair<int, const Flat_orientation_d *> preset_flat_orientation_; std::pair<int, const Flat_orientation_d *> preset_flat_orientation_;
// for stochastic walk in the locate() function: // for stochastic walk in the locate() function:
mutable Random rng_; mutable Random rng_;
#ifdef CGAL_TRIANGULATION_STATISTICS #ifdef CGAL_TRIANGULATION_STATISTICS
mutable unsigned long walk_size_; mutable unsigned long walk_size_;
#endif #endif
@ -230,9 +231,37 @@ public:
return tds().index_of_covertex(f); return tds().index_of_covertex(f);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - UTILITIES
// A co-dimension 2 sub-simplex. called a Rotor because we can rotate
// the two "covertices" around the sub-simplex. Useful for traversing the
// boundary of a hole. NOT DOCUMENTED
typedef cpp11::tuple<Full_cell_handle, int, int> Rotor;
// Commented out because it was causing "internal compiler error" in MSVC
/*Full_cell_handle full_cell(const Rotor & r) const // NOT DOCUMENTED
{
return cpp11::get<0>(r);
}
int index_of_covertex(const Rotor & r) const // NOT DOCUMENTED
{
return cpp11::get<1>(r);
}
int index_of_second_covertex(const Rotor & r) const // NOT DOCUMENTED
{
return cpp11::get<2>(r);
}*/
Rotor rotate_rotor(Rotor & r) // NOT DOCUMENTED...
{
int opposite = cpp11::get<0>(r)->mirror_index(cpp11::get<1>(r));
Full_cell_handle s = cpp11::get<0>(r)->neighbor(cpp11::get<1>(r));
int new_second = s->index(cpp11::get<0>(r)->vertex(cpp11::get<2>(r)));
return Rotor(s, new_second, opposite);
}
// - - - - - - - - - - - - - - - - - - - - - - - - CREATION / CONSTRUCTORS // - - - - - - - - - - - - - - - - - - - - - - - - CREATION / CONSTRUCTORS
Triangulation(int dim, const Geom_traits k = Geom_traits()) Triangulation(int dim, const Geom_traits &k = Geom_traits())
: tds_(dim) : tds_(dim)
, kernel_(k) , kernel_(k)
, infinity_() , infinity_()
@ -503,7 +532,7 @@ public:
bool is_infinite(const Facet & ft) const bool is_infinite(const Facet & ft) const
{ {
Full_cell_const_handle s = full_cell(ft); Full_cell_const_handle s = full_cell(ft);
CGAL_precondition(s != Full_cell_handle()); CGAL_precondition(s != Full_cell_const_handle());
if( is_infinite(s) ) if( is_infinite(s) )
return (s->vertex(index_of_covertex(ft)) != infinite_vertex()); return (s->vertex(index_of_covertex(ft)) != infinite_vertex());
return false; return false;
@ -512,7 +541,7 @@ public:
bool is_infinite(const Face & f) const bool is_infinite(const Face & f) const
{ {
Full_cell_const_handle s = f.full_cell(); Full_cell_const_handle s = f.full_cell();
CGAL_precondition(s != Full_cell_handle()); CGAL_precondition(s != Full_cell_const_handle());
if( is_infinite(s) ) if( is_infinite(s) )
{ {
Vertex_handle v; Vertex_handle v;
@ -542,7 +571,7 @@ public:
} }
template< typename OutputIterator > template< typename OutputIterator >
OutputIterator incident_faces(Vertex_const_handle v, int d, OutputIterator out) OutputIterator incident_faces(Vertex_const_handle v, int d, OutputIterator out) const
{ {
return tds().incident_faces(v, d, out); return tds().incident_faces(v, d, out);
} }
@ -604,7 +633,12 @@ public:
return tds().new_full_cell(); return tds().new_full_cell();
} }
Vertex_handle new_vertex(const Point & p) Vertex_handle new_vertex()
{
return tds().new_vertex();
}
Vertex_handle new_vertex(const Point & p)
{ {
return tds().new_vertex(p); return tds().new_vertex(p);
} }
@ -623,13 +657,13 @@ public:
protected: protected:
template< typename OrientationPredicate > template< typename OrientationPredicate >
Full_cell_handle do_locate( const Point &, Locate_type &, Face &, Facet &, Full_cell_handle do_locate(const Point &, Locate_type &, Face &, Facet &,
Full_cell_handle start, Full_cell_handle start,
const OrientationPredicate & o) const; const OrientationPredicate & o) const;
public: public:
Full_cell_handle locate( const Point &, Locate_type &, Face &, Facet &, Full_cell_handle locate(const Point &, Locate_type &, Face &, Facet &,
Full_cell_handle start = Full_cell_handle()) const; Full_cell_handle start = Full_cell_handle()) const;
Full_cell_handle locate( const Point &, Locate_type &, Face &, Facet &, Full_cell_handle locate(const Point &, Locate_type &, Face &, Facet &,
Vertex_handle) const; Vertex_handle) const;
Full_cell_handle locate(const Point & p, Full_cell_handle s = Full_cell_handle()) const; Full_cell_handle locate(const Point & p, Full_cell_handle s = Full_cell_handle()) const;
Full_cell_handle locate(const Point & p, Vertex_handle v) const; Full_cell_handle locate(const Point & p, Vertex_handle v) const;
@ -654,7 +688,7 @@ public:
} }
return number_of_vertices() - n; return number_of_vertices() - n;
} }
Vertex_handle insert(const Point &, const Locate_type, const Face &, const Facet &, const Full_cell_handle); Vertex_handle insert(const Point &, Locate_type, const Face &, const Facet &, Full_cell_handle);
Vertex_handle insert(const Point &, Full_cell_handle start = Full_cell_handle()); Vertex_handle insert(const Point &, Full_cell_handle start = Full_cell_handle());
Vertex_handle insert(const Point &, Vertex_handle); Vertex_handle insert(const Point &, Vertex_handle);
template< typename ForwardIterator > template< typename ForwardIterator >
@ -709,6 +743,43 @@ public:
// make sure all full_cells have positive orientation // make sure all full_cells have positive orientation
void reorient_full_cells(); void reorient_full_cells();
protected:
// This is used in the |remove(v)| member function to manage sets of Full_cell_handles
template< typename FCH >
struct Full_cell_set : public std::vector<FCH>
{
typedef std::vector<FCH> Base_set;
using Base_set::begin;
using Base_set::end;
void make_searchable()
{ // sort the full cell handles
std::sort(begin(), end());
}
bool contains(const FCH & fch) const
{
return std::binary_search(begin(), end(), fch);
}
bool contains_1st_and_not_2nd(const FCH & fst, const FCH & snd) const
{
return ( ! contains(snd) ) && ( contains(fst) );
}
};
void display_all_full_cells__debugging() const
{
std::cerr << "ALL FULL CELLS:" << std::endl;
for (Full_cell_const_iterator cit = full_cells_begin() ;
cit != full_cells_end() ; ++cit )
{
std::cerr << std::hex << &*cit << ": ";
for (int jj = 0 ; jj <= current_dimension() ; ++jj)
std::cerr << (is_infinite(cit->vertex(jj)) ? 0xFFFFFFFF : (unsigned int)&*cit->vertex(jj)) << " - ";
std::cerr << std::dec << std::endl;
}
std::cerr << std::endl;
}
}; // Triangulation<...> }; // Triangulation<...>
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
@ -722,17 +793,15 @@ Triangulation<TT, TDS>
{ {
if( current_dimension() < 1 ) if( current_dimension() < 1 )
return; return;
Full_cell_iterator sit = full_cells_begin(); Full_cell_iterator sit = full_cells_begin();
Full_cell_iterator send = full_cells_end(); Full_cell_iterator send = full_cells_end();
while( sit != send ) for ( ; sit != send ; ++sit)
{ {
if( is_infinite(sit) && (1 == current_dimension()) ) if( ! (is_infinite(sit) && (1 == current_dimension())) )
{ {
++sit; sit->swap_vertices(current_dimension() - 1, current_dimension());
continue;
} }
sit->swap_vertices(current_dimension() - 1, current_dimension());
++sit;
} }
} }
@ -757,7 +826,7 @@ Triangulation<TT, TDS>
template < class TT, class TDS > template < class TT, class TDS >
typename Triangulation<TT, TDS>::Vertex_handle typename Triangulation<TT, TDS>::Vertex_handle
Triangulation<TT, TDS> Triangulation<TT, TDS>
::insert(const Point & p, const Locate_type lt, const Face & f, const Facet & ft, const Full_cell_handle s) ::insert(const Point & p, Locate_type lt, const Face & f, const Facet & ft, Full_cell_handle s)
{ {
switch( lt ) switch( lt )
{ {
@ -853,14 +922,8 @@ Triangulation<TT, TDS>
// infinite one... // infinite one...
CGAL_precondition( is_infinite(s) ); CGAL_precondition( is_infinite(s) );
CGAL_precondition( 1 == current_dimension() ); CGAL_precondition( 1 == current_dimension() );
int inf_v_index = s->index(infinite_vertex());
bool swap = (0 == s->neighbor(inf_v_index)->index(s));
Vertex_handle v = tds().insert_in_full_cell(s); Vertex_handle v = tds().insert_in_full_cell(s);
v->set_point(p); v->set_point(p);
if( swap )
{
s->swap_vertices(0, 1);
}
return v; return v;
} }
@ -917,6 +980,36 @@ Triangulation<TT, TDS>
CGAL_assertion( COPLANAR != o ); CGAL_assertion( COPLANAR != o );
if( NEGATIVE == o ) if( NEGATIVE == o )
reorient_full_cells(); reorient_full_cells();
// We just inserted the second finite point and the right infinite
// cell is like : (inf_v, v), but we want it to be (v, inf_v) to be
// consistent with the rest of the cells
if (current_dimension() == 1)
{
// Is "inf_v_cell" the right infinite cell?
// Then inf_v_index should be 1
if (inf_v_cell->neighbor(inf_v_index)->index(inf_v_cell) == 0
&& inf_v_index == 0)
{
inf_v_cell->swap_vertices(
current_dimension() - 1, current_dimension());
}
// Otherwise, let's find the right infinite cell
else
{
inf_v_cell = inf_v_cell->neighbor((inf_v_index + 1) % 2);
inf_v_index = inf_v_cell->index(infinite_vertex());
// Is "inf_v_cell" the right infinite cell?
// Then inf_v_index should be 1
if (inf_v_cell->neighbor(inf_v_index)->index(inf_v_cell) == 0
&& inf_v_index == 0)
{
inf_v_cell->swap_vertices(
current_dimension() - 1, current_dimension());
}
}
}
} }
return v; return v;
} }
@ -928,12 +1021,12 @@ template < class TT, class TDS >
template< typename OrientationPredicate > template< typename OrientationPredicate >
typename Triangulation<TT, TDS>::Full_cell_handle typename Triangulation<TT, TDS>::Full_cell_handle
Triangulation<TT, TDS> Triangulation<TT, TDS>
::do_locate( const Point & p, // query point ::do_locate(const Point & p, // query point
Locate_type & loc_type,// type of result (full_cell, face, vertex) Locate_type & loc_type,// type of result (full_cell, face, vertex)
Face & face,// the face containing the query in its interior (when appropriate) Face & face,// the face containing the query in its interior (when appropriate)
Facet & facet,// the facet containing the query in its interior (when appropriate) Facet & facet,// the facet containing the query in its interior (when appropriate)
const Full_cell_handle start// starting full_cell for the walk Full_cell_handle start, // starting full_cell for the walk
, OrientationPredicate const& orientation_pred OrientationPredicate const& orientation_pred
) const ) const
{ {
const int cur_dim = current_dimension(); const int cur_dim = current_dimension();

View File

@ -157,13 +157,13 @@ private:
template < class Dim_tag > template < class Dim_tag >
struct get_maximal_dimension struct get_maximal_dimension
{ {
static int value(const int D) { return D; } static int value(int D) { return D; }
}; };
// specialization // specialization
template < int D > template < int D >
struct get_maximal_dimension<Dimension_tag<D> > struct get_maximal_dimension<Dimension_tag<D> >
{ {
static int value(const int) { return D; } static int value(int) { return D; }
}; };
public: public:
@ -211,7 +211,7 @@ public:
protected: protected:
bool check_range(const int i) const bool check_range(int i) const
{ {
if( current_dimension() < 0 ) if( current_dimension() < 0 )
{ {
@ -245,19 +245,19 @@ public:
Full_cell_container & full_cells() { return full_cells_; } Full_cell_container & full_cells() { return full_cells_; }
const Full_cell_container & full_cells() const { return full_cells_; } const Full_cell_container & full_cells() const { return full_cells_; }
Vertex_handle vertex(const Full_cell_handle s, const int i) const /* Concept */ Vertex_handle vertex(Full_cell_handle s, int i) const /* Concept */
{ {
CGAL_precondition(s != Full_cell_handle() && check_range(i)); CGAL_precondition(s != Full_cell_handle() && check_range(i));
return s->vertex(i); return s->vertex(i);
} }
Vertex_const_handle vertex(const Full_cell_const_handle s, const int i) const /* Concept */ Vertex_const_handle vertex(Full_cell_const_handle s, int i) const /* Concept */
{ {
CGAL_precondition(s != Full_cell_handle() && check_range(i)); CGAL_precondition(s != Full_cell_handle() && check_range(i));
return s->vertex(i); return s->vertex(i);
} }
bool is_vertex(const Vertex_const_handle & v) const /* Concept */ bool is_vertex(Vertex_const_handle v) const /* Concept */
{ {
if( Vertex_const_handle() == v ) if( Vertex_const_handle() == v )
return false; return false;
@ -267,7 +267,7 @@ public:
return v == vit; return v == vit;
} }
bool is_full_cell(const Full_cell_const_handle & s) const /* Concept */ bool is_full_cell(Full_cell_const_handle s) const /* Concept */
{ {
if( Full_cell_const_handle() == s ) if( Full_cell_const_handle() == s )
return false; return false;
@ -277,43 +277,43 @@ public:
return s == sit; return s == sit;
} }
Full_cell_handle full_cell(const Vertex_handle v) const /* Concept */ Full_cell_handle full_cell(Vertex_handle v) const /* Concept */
{ {
CGAL_precondition(v != Vertex_handle()); CGAL_precondition(v != Vertex_handle());
return v->full_cell(); return v->full_cell();
} }
Full_cell_const_handle full_cell(const Vertex_const_handle v) const /* Concept */ Full_cell_const_handle full_cell(Vertex_const_handle v) const /* Concept */
{ {
CGAL_precondition(Vertex_const_handle() != v); CGAL_precondition(Vertex_const_handle() != v);
return v->full_cell(); return v->full_cell();
} }
Full_cell_handle neighbor(const Full_cell_handle s, const int i) const /* Concept */ Full_cell_handle neighbor(Full_cell_handle s, int i) const /* Concept */
{ {
CGAL_precondition(Full_cell_handle() != s && check_range(i)); CGAL_precondition(Full_cell_handle() != s && check_range(i));
return s->neighbor(i); return s->neighbor(i);
} }
Full_cell_const_handle neighbor(const Full_cell_const_handle s, const int i) const/* Concept */ Full_cell_const_handle neighbor(Full_cell_const_handle s, int i) const/* Concept */
{ {
CGAL_precondition(Full_cell_const_handle() != s && check_range(i)); CGAL_precondition(Full_cell_const_handle() != s && check_range(i));
return s->neighbor(i); return s->neighbor(i);
} }
int mirror_index(const Full_cell_handle s, const int i) const /* Concept */ int mirror_index(Full_cell_handle s, int i) const /* Concept */
{ {
CGAL_precondition(Full_cell_handle() != s && check_range(i)); CGAL_precondition(Full_cell_handle() != s && check_range(i));
return s->mirror_index(i); return s->mirror_index(i);
} }
int mirror_index(const Full_cell_const_handle s, const int i) const int mirror_index(Full_cell_const_handle s, int i) const
{ {
CGAL_precondition(Full_cell_const_handle() != s && check_range(i)); /* Concept */ CGAL_precondition(Full_cell_const_handle() != s && check_range(i)); /* Concept */
return s->mirror_index(i); return s->mirror_index(i);
} }
int mirror_vertex(const Full_cell_handle s, const int i) const /* Concept */ int mirror_vertex(Full_cell_handle s, int i) const /* Concept */
{ {
CGAL_precondition(Full_cell_handle() != s && check_range(i)); CGAL_precondition(Full_cell_handle() != s && check_range(i));
return s->mirror_vertex(i); return s->mirror_vertex(i);
@ -368,7 +368,7 @@ public:
// NICE UPDATE OPERATIONS // NICE UPDATE OPERATIONS
protected: protected:
void do_insert_increase_dimension(const Vertex_handle, const Vertex_handle); void do_insert_increase_dimension(Vertex_handle, Vertex_handle);
public: public:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - REMOVALS // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - REMOVALS
@ -381,9 +381,9 @@ public:
Vertex_handle insert_in_face(const Face &); /* Concept */ Vertex_handle insert_in_face(const Face &); /* Concept */
Vertex_handle insert_in_facet(const Facet &); /* Concept */ Vertex_handle insert_in_facet(const Facet &); /* Concept */
template< typename Forward_iterator > template< typename Forward_iterator >
Vertex_handle insert_in_hole(Forward_iterator, const Forward_iterator, Facet); /* Concept */ Vertex_handle insert_in_hole(Forward_iterator, Forward_iterator, Facet); /* Concept */
template< typename Forward_iterator, typename OutputIterator > template< typename Forward_iterator, typename OutputIterator >
Vertex_handle insert_in_hole(Forward_iterator, const Forward_iterator, Facet, OutputIterator); /* Concept */ Vertex_handle insert_in_hole(Forward_iterator, Forward_iterator, Facet, OutputIterator); /* Concept */
template< typename OutputIterator > template< typename OutputIterator >
Full_cell_handle insert_in_tagged_hole(Vertex_handle, Facet, OutputIterator); Full_cell_handle insert_in_tagged_hole(Vertex_handle, Facet, OutputIterator);
@ -420,7 +420,6 @@ private:
void clear_visited_marks(Full_cell_handle) const; void clear_visited_marks(Full_cell_handle) const;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DANGEROUS UPDATE OPERATIONS // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DANGEROUS UPDATE OPERATIONS
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DANGEROUS UPDATE OPERATIONS
private: private:
@ -449,13 +448,13 @@ public:
dcur_ = -2; dcur_ = -2;
} }
void set_current_dimension(const int d) /* Concept */ void set_current_dimension(int d) /* Concept */
{ {
CGAL_precondition(-2<=d && d<=maximal_dimension()); CGAL_precondition(-2<=d && d<=maximal_dimension());
dcur_ = d; dcur_ = d;
} }
Full_cell_handle new_full_cell(const Full_cell_handle s) Full_cell_handle new_full_cell(Full_cell_handle s)
{ {
return full_cells_.emplace(*s); return full_cells_.emplace(*s);
} }
@ -497,7 +496,7 @@ public:
vertices_.erase(v); vertices_.erase(v);
} }
void associate_vertex_with_full_cell(Full_cell_handle s, const int i, Vertex_handle v) /* Concept */ void associate_vertex_with_full_cell(Full_cell_handle s, int i, Vertex_handle v) /* Concept */
{ {
CGAL_precondition(check_range(i)); CGAL_precondition(check_range(i));
CGAL_precondition(s != Full_cell_handle()); CGAL_precondition(s != Full_cell_handle());
@ -557,7 +556,7 @@ public:
const Triangulation_data_structure & tds_; const Triangulation_data_structure & tds_;
public: public:
Incident_full_cell_traversal_predicate(const Triangulation_data_structure & tds, Incident_full_cell_traversal_predicate(const Triangulation_data_structure & tds,
const Face & f) const Face & f)
: f_(f), tds_(tds) : f_(f), tds_(tds)
{ {
dim_ = f.face_dimension(); dim_ = f.face_dimension();
@ -582,7 +581,7 @@ public:
const Triangulation_data_structure & tds_; const Triangulation_data_structure & tds_;
public: public:
Star_traversal_predicate(const Triangulation_data_structure & tds, Star_traversal_predicate(const Triangulation_data_structure & tds,
const Face & f) const Face & f)
: f_(f), tds_(tds) : f_(f), tds_(tds)
{ {
dim_ = f.face_dimension(); dim_ = f.face_dimension();
@ -610,28 +609,28 @@ public:
OutputIterator star(const Face &, OutputIterator) const; /* Concept */ OutputIterator star(const Face &, OutputIterator) const; /* Concept */
#ifndef CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES #ifndef CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES
template< typename OutputIterator, typename Comparator = std::less<Vertex_const_handle> > template< typename OutputIterator, typename Comparator = std::less<Vertex_const_handle> >
OutputIterator incident_upper_faces(Vertex_const_handle v, const int dim, OutputIterator out, Comparator cmp = Comparator()) OutputIterator incident_upper_faces(Vertex_const_handle v, int dim, OutputIterator out, Comparator cmp = Comparator())
{ {
return incident_faces(v, dim, out, cmp, true); return incident_faces(v, dim, out, cmp, true);
} }
template< typename OutputIterator, typename Comparator = std::less<Vertex_const_handle> > template< typename OutputIterator, typename Comparator = std::less<Vertex_const_handle> >
OutputIterator incident_faces(Vertex_const_handle, const int, OutputIterator, Comparator = Comparator(), bool = false); OutputIterator incident_faces(Vertex_const_handle, int, OutputIterator, Comparator = Comparator(), bool = false) const;
#else #else
template< typename OutputIterator, typename Comparator > template< typename OutputIterator, typename Comparator >
OutputIterator incident_upper_faces(Vertex_const_handle v, const int dim, OutputIterator out, Comparator cmp = Comparator()) OutputIterator incident_upper_faces(Vertex_const_handle v, int dim, OutputIterator out, Comparator cmp = Comparator())
{ {
return incident_faces(v, dim, out, cmp, true); return incident_faces(v, dim, out, cmp, true);
} }
template< typename OutputIterator > template< typename OutputIterator >
OutputIterator incident_upper_faces(Vertex_const_handle v, const int dim, OutputIterator out) OutputIterator incident_upper_faces(Vertex_const_handle v, int dim, OutputIterator out)
{ {
return incident_faces(v, dim, out, std::less<Vertex_const_handle>(), true); return incident_faces(v, dim, out, std::less<Vertex_const_handle>(), true);
} }
template< typename OutputIterator, typename Comparator > template< typename OutputIterator, typename Comparator >
OutputIterator incident_faces(Vertex_const_handle, const int, OutputIterator, Comparator = Comparator(), bool = false); OutputIterator incident_faces(Vertex_const_handle, int, OutputIterator, Comparator = Comparator(), bool = false) const;
template< typename OutputIterator > template< typename OutputIterator >
OutputIterator incident_faces(Vertex_const_handle, const int, OutputIterator, OutputIterator incident_faces(Vertex_const_handle, int, OutputIterator,
std::less<Vertex_const_handle> = std::less<Vertex_const_handle>(), bool = false); std::less<Vertex_const_handle> = std::less<Vertex_const_handle>(), bool = false) const;
#endif #endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INPUT / OUTPUT // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INPUT / OUTPUT
@ -726,8 +725,8 @@ template< class Dim, class Vb, class Fcb >
template< typename OutputIterator > template< typename OutputIterator >
OutputIterator OutputIterator
Triangulation_data_structure<Dim, Vb, Fcb> Triangulation_data_structure<Dim, Vb, Fcb>
::incident_faces(Vertex_const_handle v, const int dim, OutputIterator out, ::incident_faces(Vertex_const_handle v, int dim, OutputIterator out,
std::less<Vertex_const_handle> cmp, bool upper_faces) std::less<Vertex_const_handle> cmp, bool upper_faces) const
{ {
return incident_faces<OutputIterator, std::less<Vertex_const_handle> >(v, dim, out, cmp, upper_faces); return incident_faces<OutputIterator, std::less<Vertex_const_handle> >(v, dim, out, cmp, upper_faces);
} }
@ -737,7 +736,7 @@ template< class Dim, class Vb, class Fcb >
template< typename OutputIterator, typename Comparator > template< typename OutputIterator, typename Comparator >
OutputIterator OutputIterator
Triangulation_data_structure<Dim, Vb, Fcb> Triangulation_data_structure<Dim, Vb, Fcb>
::incident_faces(Vertex_const_handle v, const int dim, OutputIterator out, Comparator cmp, bool upper_faces) ::incident_faces(Vertex_const_handle v, int dim, OutputIterator out, Comparator cmp, bool upper_faces) const
{ {
CGAL_precondition( 0 < dim ); CGAL_precondition( 0 < dim );
if( dim >= current_dimension() ) if( dim >= current_dimension() )
@ -791,13 +790,13 @@ Triangulation_data_structure<Dim, Vb, Fcb>
// init state for enumerating all candidate faces: // init state for enumerating all candidate faces:
internal::Combination_enumerator f_idx(dim, v_idx + 1, current_dimension()); internal::Combination_enumerator f_idx(dim, v_idx + 1, current_dimension());
Face f(*s); Face f(*s);
f.set_index(0, v_idx); f.set_index(0, sorted_idx[v_idx]);
while( ! f_idx.end() ) while( ! f_idx.end() )
{ {
// check if face has already been found
for( int i = 0; i < dim; ++i ) for( int i = 0; i < dim; ++i )
f.set_index(1 + i, sorted_idx[f_idx[i]]); f.set_index(1 + i, sorted_idx[f_idx[i]]);
face_set.insert(f); face_set.insert(f); // checks if face has already been found
// compute next sorted face (lexicographic enumeration) // compute next sorted face (lexicographic enumeration)
++f_idx; ++f_idx;
} }
@ -892,8 +891,7 @@ Triangulation_data_structure<Dim, Vb, Fcb>
if( v_idx != current_dimension() ) if( v_idx != current_dimension() )
{ {
(*it)->swap_vertices(v_idx, current_dimension()); (*it)->swap_vertices(v_idx, current_dimension());
if( ( ! (*it)->has_vertex(star) ) || (current_dimension() > 2) ) (*it)->swap_vertices(current_dimension() - 2, current_dimension() - 1);
(*it)->swap_vertices(current_dimension() - 2, current_dimension() - 1);
} }
(*it)->set_vertex(current_dimension(), Vertex_handle()); (*it)->set_vertex(current_dimension(), Vertex_handle());
(*it)->set_neighbor(current_dimension(), Full_cell_handle()); (*it)->set_neighbor(current_dimension(), Full_cell_handle());
@ -971,10 +969,10 @@ Triangulation_data_structure<Dim, Vb, Fcb>
CGAL_assertion_msg(is_boundary_facet(f), "starting facet should be on the hole boundary"); CGAL_assertion_msg(is_boundary_facet(f), "starting facet should be on the hole boundary");
const int cur_dim = current_dimension(); const int cur_dim = current_dimension();
Full_cell_handle new_s; Full_cell_handle new_s;
std::queue<IITH_task> task_queue; std::queue<IITH_task> task_queue;
task_queue.push( task_queue.push(
IITH_task(f, mirror_index(full_cell(f), index_of_covertex(f))) ); IITH_task(f, mirror_index(full_cell(f), index_of_covertex(f))) );
while (!task_queue.empty()) while (!task_queue.empty())
@ -1003,7 +1001,7 @@ Triangulation_data_structure<Dim, Vb, Fcb>
associate_vertex_with_full_cell(new_s, facet_index, v); associate_vertex_with_full_cell(new_s, facet_index, v);
set_neighbors(new_s, set_neighbors(new_s,
facet_index, facet_index,
neighbor(old_s, facet_index), outside_neighbor,
mirror_index(old_s, facet_index)); mirror_index(old_s, facet_index));
// add the new full_cell to the list of new full_cells // add the new full_cell to the list of new full_cells
@ -1120,7 +1118,7 @@ Triangulation_data_structure<Dim, Vb, Fcb>
template <class Dim, class Vb, class Fcb> template <class Dim, class Vb, class Fcb>
void Triangulation_data_structure<Dim, Vb, Fcb> void Triangulation_data_structure<Dim, Vb, Fcb>
::do_insert_increase_dimension(const Vertex_handle x, const Vertex_handle star) ::do_insert_increase_dimension(Vertex_handle x, Vertex_handle star)
{ {
Full_cell_handle start = full_cells_begin(); Full_cell_handle start = full_cells_begin();
Full_cell_handle swap_me; Full_cell_handle swap_me;
@ -1142,11 +1140,6 @@ void Triangulation_data_structure<Dim, Vb, Fcb>
for( int k = 1; k <= cur_dim; ++k ) for( int k = 1; k <= cur_dim; ++k )
associate_vertex_with_full_cell(S_new, k, vertex(S, k - 1)); associate_vertex_with_full_cell(S_new, k, vertex(S, k - 1));
} }
else if( cur_dim == 2 )
{ // if cur. dim. is 2, we must take care of the 'rightmost' infinite vertex.
if( S->mirror_index(S->index(star)) == 0 )
swap_me = S;
}
} }
// now we setup the neighbors // now we setup the neighbors
set_visited(start, false); set_visited(start, false);
@ -1526,7 +1519,7 @@ operator>>(std::istream & is, Triangulation_data_structure<Dimen, Vb, Fcb> & tr)
// - the neighbors of each full_cell by their index in the preceding list // - the neighbors of each full_cell by their index in the preceding list
{ {
typedef Triangulation_data_structure<Dimen, Vb, Fcb> TDS; typedef Triangulation_data_structure<Dimen, Vb, Fcb> TDS;
typedef typename TDS::Vertex_handle Vertex_handle; typedef typename TDS::Vertex_handle Vertex_handle;
// read current dimension and number of vertices // read current dimension and number of vertices
std::size_t n; std::size_t n;
@ -1576,8 +1569,8 @@ operator<<(std::ostream & os, const Triangulation_data_structure<Dimen, Vb, Fcb>
// - the neighbors of each full_cell by their index in the preceding list // - the neighbors of each full_cell by their index in the preceding list
{ {
typedef Triangulation_data_structure<Dimen, Vb, Fcb> TDS; typedef Triangulation_data_structure<Dimen, Vb, Fcb> TDS;
typedef typename TDS::Vertex_const_handle Vertex_handle; typedef typename TDS::Vertex_const_handle Vertex_handle;
typedef typename TDS::Vertex_const_iterator Vertex_iterator; typedef typename TDS::Vertex_const_iterator Vertex_iterator;
// outputs dimension and number of vertices // outputs dimension and number of vertices
std::size_t n = tr.number_of_vertices(); std::size_t n = tr.number_of_vertices();
@ -1598,6 +1591,8 @@ operator<<(std::ostream & os, const Triangulation_data_structure<Dimen, Vb, Fcb>
for( Vertex_iterator it = tr.vertices_begin(); it != tr.vertices_end(); ++it, ++i ) for( Vertex_iterator it = tr.vertices_begin(); it != tr.vertices_end(); ++it, ++i )
{ {
os << *it; // write the vertex os << *it; // write the vertex
if (is_ascii(os))
os << std::endl;
index_of_vertex[it] = i; index_of_vertex[it] = i;
} }
CGAL_assertion( (std::size_t) i == n ); CGAL_assertion( (std::size_t) i == n );

View File

@ -64,7 +64,6 @@ public:
/// Set 's' as an incident full_cell /// Set 's' as an incident full_cell
void set_full_cell(Full_cell_handle s) /* Concept */ void set_full_cell(Full_cell_handle s) /* Concept */
{ {
CGAL_precondition( Full_cell_handle() != s );
full_cell_ = s; full_cell_ = s;
} }

View File

@ -69,22 +69,6 @@ public:
Triangulation_full_cell(const Self & s) Triangulation_full_cell(const Self & s)
: Base(s), data_(s.data_) {} : Base(s), data_(s.data_) {}
Point circumcenter() const
{
TriangulationTraits pct;
Vertex_handle_const_iterator vhit = vertices_begin();
while( vhit != vertices_end() )
{
if( *vhit == Vertex_const_handle() )
{
CGAL_warning_msg(false, "too few points; can not compute circumcenter.");
return Point();
}
++vhit;
}
return pct.center_of_sphere_d_object()(points_begin(), points_end());
}
const Data & data() const const Data & data() const
{ {
return data_; return data_;

View File

@ -25,7 +25,6 @@
#include <CGAL/Triangulation_ds_vertex.h> #include <CGAL/Triangulation_ds_vertex.h>
#include <CGAL/Default.h> #include <CGAL/Default.h>
#include <CGAL/Random.h>
namespace CGAL { namespace CGAL {

View File

@ -101,7 +101,7 @@ public:
template< class T > template< class T >
struct Compare_points_for_perturbation struct Compare_points_for_perturbation
{ {
typedef typename T::Point_d Point; typedef typename T::Geom_traits::Point_d Point;
const T & t_; const T & t_;
@ -122,8 +122,8 @@ public:
template< class T > template< class T >
struct Point_from_pointer struct Point_from_pointer
{ {
typedef const typename T::Point_d * argument_type; typedef const typename T::Geom_traits::Point_d * argument_type;
typedef const typename T::Point_d result_type; typedef const typename T::Geom_traits::Point_d result_type;
result_type & operator()(argument_type & x) const result_type & operator()(argument_type & x) const
{ {
return (*x); return (*x);

View File

@ -1,7 +1,6 @@
# Created by the script cgal_create_cmake_script # Created by the script cgal_create_cmake_script
# This is the CMake script for compiling a CGAL application. # This is the CMake script for compiling a CGAL application.
project( Triangulation_Tests ) project( Triangulation_Tests )
cmake_minimum_required(VERSION 2.8.11) cmake_minimum_required(VERSION 2.8.11)
@ -21,18 +20,18 @@ if ( CGAL_FOUND )
include_directories (BEFORE "../../include") include_directories (BEFORE "../../include")
include_directories (BEFORE "include") include_directories (BEFORE "include")
create_single_source_cgal_program( "test_triangulation.cpp" )
create_single_source_cgal_program( "test_delaunay.cpp" ) create_single_source_cgal_program( "test_delaunay.cpp" )
create_single_source_cgal_program( "test_regular.cpp" )
create_single_source_cgal_program( "test_tds.cpp" ) create_single_source_cgal_program( "test_tds.cpp" )
create_single_source_cgal_program( "test_torture.cpp" ) create_single_source_cgal_program( "test_torture.cpp" )
create_single_source_cgal_program( "test_triangulation.cpp" ) create_single_source_cgal_program( "test_insert_if_in_star.cpp" )
else() else()
message(STATUS "NOTICE: Some of the executables in this directory need Eigen 3.1 (or greater) and will not be compiled.") message(STATUS "NOTICE: Some of the executables in this directory need Eigen 3.1 (or greater) and will not be compiled.")
endif() endif()
else() else()
message(STATUS "This program requires the CGAL library, and will not be compiled.") message(STATUS "This program requires the CGAL library, and will not be compiled.")
endif() endif()

View File

@ -34,102 +34,105 @@ void test(const int d, const string & type, const int N)
typedef CGAL::Random_points_in_cube_d<Point> Random_points_iterator; typedef CGAL::Random_points_in_cube_d<Point> Random_points_iterator;
DC pc(d); DC dt(d);
cerr << "\nBuilding Delaunay triangulation of (" << type << d << ") dimension with " << N << " points"; cerr << "\nBuilding Delaunay triangulation of (" << type << d << ") dimension with " << N << " points";
assert(pc.empty()); assert(dt.empty());
vector<Point> points; vector<Point> points;
CGAL::Random rng; //CGAL::Random rng;
Random_points_iterator rand_it(d, 2.0, rng); //Random_points_iterator rand_it(d, 2.0, rng);
//CGAL::cpp11::copy_n(rand_it, N, back_inserter(points)); //CGAL::cpp11::copy_n(rand_it, N, back_inserter(points));
vector<int> coords(d); srand(10);
for( int i = 0; i < N; ++i ) for( int i = 0; i < N; ++i )
{ {
vector<double> coords(d);
for( int j = 0; j < d; ++j ) for( int j = 0; j < d; ++j )
coords[j] = rand() % 100000; coords[j] = static_cast<double>(rand() % 100000)/10000;
points.push_back(Point(d, coords.begin(), coords.end())); points.push_back(Point(d, coords.begin(), coords.end()));
} }
pc.insert(points.begin(), points.end()); dt.insert(points.begin(), points.end());
cerr << "\nChecking topology and geometry..."; cerr << "\nChecking topology and geometry...";
assert( pc.is_valid() ); assert( dt.is_valid() );
cerr << "\nTraversing finite full_cells... "; cerr << "\nTraversing finite full_cells... ";
size_t nbfs(0), nbis(0); size_t nbfs(0), nbis(0);
Finite_full_cell_const_iterator fsit = pc.finite_full_cells_begin(); Finite_full_cell_const_iterator fsit = dt.finite_full_cells_begin();
while( fsit != pc.finite_full_cells_end() ) while( fsit != dt.finite_full_cells_end() )
++fsit, ++nbfs; ++fsit, ++nbfs;
cerr << nbfs << " + "; cerr << nbfs << " + ";
vector<Full_cell_handle> infinite_full_cells; vector<Full_cell_handle> infinite_full_cells;
pc.tds().incident_full_cells(pc.infinite_vertex(), back_inserter(infinite_full_cells)); dt.tds().incident_full_cells(dt.infinite_vertex(), back_inserter(infinite_full_cells));
nbis = infinite_full_cells.size(); nbis = infinite_full_cells.size();
cerr << nbis << " = " << (nbis+nbfs) cerr << nbis << " = " << (nbis+nbfs)
<< " = " << pc.number_of_full_cells(); << " = " << dt.number_of_full_cells();
cerr << "\nThe triangulation has current dimension " << pc.current_dimension(); cerr << "\nThe triangulation has current dimension " << dt.current_dimension();
CGAL_assertion( pc.number_of_full_cells() == nbis+nbfs); CGAL_assertion( dt.number_of_full_cells() == nbis+nbfs);
cerr << "\nTraversing finite vertices... "; cerr << "\nTraversing finite vertices... ";
size_t nbfv(0); size_t nbfv(0);
Finite_vertex_iterator fvit = pc.finite_vertices_begin(); Finite_vertex_iterator fvit = dt.finite_vertices_begin();
while( fvit != pc.finite_vertices_end() ) while( fvit != dt.finite_vertices_end() )
++fvit, ++nbfv; ++fvit, ++nbfv;
cerr << nbfv <<endl; cerr << nbfv <<endl;
// Count convex hull vertices: // Count convex hull vertices:
if( pc.maximal_dimension() > 1 ) if( dt.maximal_dimension() > 1 )
{ {
typedef vector<Face> Faces; typedef vector<Face> Faces;
Faces edges; Faces edges;
back_insert_iterator<Faces> out(edges); back_insert_iterator<Faces> out(edges);
pc.tds().incident_faces(pc.infinite_vertex(), 1, out); dt.tds().incident_faces(dt.infinite_vertex(), 1, out);
cout << "\nThere are " << edges.size() << " vertices on the convex hull."; cout << "\nThere are " << edges.size() << " vertices on the convex hull.";
edges.clear(); edges.clear();
} }
else // pc.maximal_dimension() == 1 else // dt.maximal_dimension() == 1
{ {
typedef vector<Full_cell_handle> Cells; typedef vector<Full_cell_handle> Cells;
Cells cells; Cells cells;
back_insert_iterator<Cells> out(cells); back_insert_iterator<Cells> out(cells);
pc.tds().incident_full_cells(pc.infinite_vertex(), out); dt.tds().incident_full_cells(dt.infinite_vertex(), out);
cout << "\nThere are " << cells.size() << " vertices on the convex hull."; cout << "\nThere are " << cells.size() << " vertices on the convex hull.";
cells.clear(); cells.clear();
} }
// Remove all ! // Remove all !
cerr << "\nBefore removal: " << pc.number_of_vertices() << " vertices. After: "; cerr << "\nBefore removal: " << dt.number_of_vertices() << " vertices. After: ";
random_shuffle(points.begin(), points.end()); random_shuffle(points.begin(), points.end());
pc.remove(points.begin(), points.end()); dt.remove(points.begin(), points.end());
assert( pc.is_valid() ); assert( dt.is_valid() );
cerr << pc.number_of_vertices() << " vertices."; cerr << dt.number_of_vertices() << " vertices.";
// assert( pc.empty() ); NOT YET ! // assert( dt.empty() ); NOT YET !
// CLEAR // CLEAR
pc.clear(); dt.clear();
assert( -1 == pc.current_dimension() ); assert( -1 == dt.current_dimension() );
assert( pc.empty() ); assert( dt.empty() );
assert( pc.is_valid() ); assert( dt.is_valid() );
} }
template< int D > template< int D >
void go(const int N) void go(const int N)
{ {
//typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> FK;
typedef CGAL::Epick_d<CGAL::Dimension_tag<D> > FK; typedef CGAL::Epick_d<CGAL::Dimension_tag<D> > FK;
typedef CGAL::Delaunay_triangulation<FK> Triangulation; typedef CGAL::Delaunay_triangulation<FK> Triangulation;
//test<Triangulation>(D, "dynamic", N);
test<Triangulation>(D, "static", N); test<Triangulation>(D, "static", N);
typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> FK_dyn;
typedef CGAL::Delaunay_triangulation<FK> Triangulation_dyn;
test<Triangulation_dyn>(D, "dynamic", N);
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
srand(static_cast<unsigned int>(time(NULL))); srand(static_cast<unsigned int>(time(NULL)));
int N = 100; int N = 10;
if( argc > 1 ) if( argc > 1 )
N = atoi(argv[1]); N = atoi(argv[1]);
go<5>(N); //go<5>(N);
go<4>(N); go<4>(N);
go<3>(N); go<3>(N);
go<2>(N); go<2>(N);
go<1>(N); go<1>(N);
cerr << endl; cerr << endl;
return 0; return 0;

View File

@ -0,0 +1,92 @@
#include <CGAL/Epick_d.h>
#include <CGAL/point_generators_d.h>
#include <CGAL/Regular_triangulation.h>
#include <CGAL/IO/Triangulation_off_ostream.h>
#include <CGAL/algorithm.h>
#include <vector>
#include <string>
#include <fstream>
#include <cstdlib>
#include <algorithm>
using namespace std;
template<typename RTri>
void test(const int d, const string & type, const int N)
{
typedef typename RTri::Vertex_handle Vertex_handle;
typedef typename RTri::Point Point;
typedef typename RTri::Bare_point Bare_point;
typedef CGAL::Random_points_in_cube_d<Bare_point> Random_points_iterator;
RTri rt(d);
RTri rt_star_only(d);
cerr << "\nBuilding Regular triangulation of (" << type << d
<< ") dimension with " << N << " points\n";
assert(rt.empty());
assert(rt_star_only.empty());
srand(static_cast<unsigned int>(time(NULL)));
// Insert first point (0, 0...)
vector<double> coords(d);
for( int j = 0; j < d; ++j )
coords[j] = 0;
Point p = Point(
Bare_point(d, coords.begin(), coords.end()),
static_cast<double>(rand() % 10000)/100000);
rt.insert(p);
Vertex_handle first_vertex = rt_star_only.insert(p);
// Insert the other points
for( int i = 1 ; i < N ; ++i )
{
for( int j = 0; j < d; ++j )
coords[j] = 10.*(rand() % RAND_MAX)/RAND_MAX - 5.;
p = Point(
Bare_point(d, coords.begin(), coords.end()),
static_cast<double>(rand() % 10000)/1000000);
rt.insert(p);
rt_star_only.insert_if_in_star(p, first_vertex);
}
cerr << "\nChecking topology and geometry..."
<< (rt.is_valid(true) ? "OK.\n" : "Error.\n");
cerr << "\nThe triangulation using 'insert' has current dimension " << rt.current_dimension()
<< " and " << rt.number_of_full_cells() << " full cells\n";
cerr << "\nThe triangulation using 'insert_if_in_star' has current dimension " << rt.current_dimension()
<< " and " << rt_star_only.number_of_full_cells() << " full cells\n";
// Export
if (d <= 3)
{
std::ofstream off_stream_all("data/test_insert_all.off");
CGAL::export_triangulation_to_off(off_stream_all, rt);
std::ofstream off_stream_star_only("data/test_insert_if_in_star.off");
CGAL::export_triangulation_to_off(off_stream_star_only, rt_star_only);
}
}
template< int D >
void go(const int N)
{
//typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> FK;
typedef CGAL::Epick_d<CGAL::Dimension_tag<D> > FK;
typedef CGAL::Regular_triangulation<FK> Triangulation;
//test<Triangulation>(D, "dynamic", N);
test<Triangulation>(D, "static", N);
}
int main(int argc, char **argv)
{
go<2>(100);
return 0;
}

View File

@ -0,0 +1,289 @@
#include <CGAL/Epick_d.h>
#include <CGAL/point_generators_d.h>
#include <CGAL/Regular_triangulation.h>
#include <CGAL/algorithm.h>
#include <tilted_grid.h>
#include <vector>
#include <string>
#include <fstream>
#include <cstdlib>
#include <algorithm>
using namespace std;
template<typename RTri>
void test(const int d, const string & type, const int N)
{
typedef typename RTri::Full_cell_handle Full_cell_handle;
typedef typename RTri::Face Face;
typedef typename RTri::Point Point;
typedef typename RTri::Bare_point Bare_point;
typedef typename RTri::Finite_full_cell_const_iterator Finite_full_cell_const_iterator;
typedef typename RTri::Finite_vertex_iterator Finite_vertex_iterator;
typedef CGAL::Random_points_in_cube_d<Bare_point> Random_points_iterator;
RTri rt(d);
cerr << "\nBuilding Regular triangulation of (" << type << d << ") dimension with " << N << " points";
assert(rt.empty());
vector<Point> points;
srand(10);
for( int i = 0; i < N; ++i )
{
vector<double> coords(d);
for( int j = 0; j < d; ++j )
coords[j] = static_cast<double>(rand() % 100000)/10000;
points.push_back(Point(
Bare_point(d, coords.begin(), coords.end()),
static_cast<double>(rand() % 100000)/100000
));
}
rt.insert(points.begin(), points.end());
cerr << "\nChecking topology and geometry...";
assert( rt.is_valid(true) );
cerr << "\nTraversing finite full_cells... ";
size_t nbfs(0), nbis(0);
Finite_full_cell_const_iterator fsit = rt.finite_full_cells_begin();
while( fsit != rt.finite_full_cells_end() )
++fsit, ++nbfs;
cerr << nbfs << " + ";
vector<Full_cell_handle> infinite_full_cells;
rt.tds().incident_full_cells(rt.infinite_vertex(), back_inserter(infinite_full_cells));
nbis = infinite_full_cells.size();
cerr << nbis << " = " << (nbis+nbfs)
<< " = " << rt.number_of_full_cells();
cerr << "\nThe triangulation has current dimension " << rt.current_dimension();
CGAL_assertion( rt.number_of_full_cells() == nbis+nbfs);
cerr << "\nTraversing finite vertices... ";
size_t nbfv(0);
Finite_vertex_iterator fvit = rt.finite_vertices_begin();
while( fvit != rt.finite_vertices_end() )
++fvit, ++nbfv;
cerr << nbfv <<endl;
// Count convex hull vertices:
if( rt.maximal_dimension() > 1 )
{
typedef vector<Face> Faces;
Faces edges;
back_insert_iterator<Faces> out(edges);
rt.tds().incident_faces(rt.infinite_vertex(), 1, out);
cout << "\nThere are " << edges.size() << " vertices on the convex hull.";
edges.clear();
}
else // rt.maximal_dimension() == 1
{
typedef vector<Full_cell_handle> Cells;
Cells cells;
back_insert_iterator<Cells> out(cells);
rt.tds().incident_full_cells(rt.infinite_vertex(), out);
cout << "\nThere are " << cells.size() << " vertices on the convex hull.";
cells.clear();
}
// Remove all !
cerr << "\nBefore removal: " << rt.number_of_vertices() << " vertices. After: ";
random_shuffle(points.begin(), points.end());
rt.remove(points.begin(), points.end());
assert( rt.is_valid() );
//std::cerr << ((rt.is_valid(true)) ? "VALID!" : "NOT VALID :(") << std::endl;
cerr << rt.number_of_vertices() << " vertices.";
// assert( rt.empty() ); NOT YET !
// CLEAR
rt.clear();
assert( -1 == rt.current_dimension() );
assert( rt.empty() );
assert( rt.is_valid() );
//std::cerr << ((rt.is_valid(true)) ? "VALID!" : "NOT VALID :(") << std::endl;
}
template< int D >
void go(const int N)
{
typedef CGAL::Epick_d<CGAL::Dimension_tag<D> > FK;
typedef CGAL::Regular_triangulation<FK> Triangulation;
test<Triangulation>(D, "static", N);
typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> FK_dyn;
typedef CGAL::Regular_triangulation<FK_dyn> Triangulation_dyn;
test<Triangulation_dyn>(D, "dynamic", N);
}
void test_inserting_points_at_the_same_position()
{
const int DIM = 5;
typedef CGAL::Epick_d<CGAL::Dimension_tag<DIM> > FK;
typedef CGAL::Regular_triangulation<FK> RTri;
typedef RTri::Vertex_handle Vertex_handle;
typedef RTri::Full_cell_handle Full_cell_handle;
typedef RTri::Face Face;
typedef RTri::Point Point;
typedef RTri::Bare_point Bare_point;
typedef RTri::Finite_full_cell_const_iterator Finite_full_cell_const_iterator;
typedef RTri::Finite_vertex_iterator Finite_vertex_iterator;
RTri rt(DIM);
cerr << "\nTesting insertion of points at the same position";
assert(rt.empty());
std::vector<double> pt;
pt.push_back(1.2);
pt.push_back(20.3);
pt.push_back(10.);
pt.push_back(8.);
pt.push_back(7.1);
//=======================
// First point
Vertex_handle vh = rt.insert(Point(Bare_point(pt.begin(), pt.end()), 0.));
assert(rt.number_of_vertices() == 1);
assert(rt.number_of_hidden_vertices() == 0);
assert(vh != Vertex_handle());
// Same point
Vertex_handle vh2 = rt.insert(Point(Bare_point(pt.begin(), pt.end()), 0.));
assert(rt.number_of_vertices() == 1);
assert(rt.number_of_hidden_vertices() == 0);
assert(vh == vh2);
// Same position, bigger weight
vh = rt.insert(Point(Bare_point(pt.begin(), pt.end()), 1.3));
assert(rt.number_of_vertices() == 1);
assert(rt.number_of_hidden_vertices() == 1);
assert(vh != Vertex_handle());
// Same point
vh2 = rt.insert(Point(Bare_point(pt.begin(), pt.end()), 1.3));
assert(rt.number_of_vertices() == 1);
assert(rt.number_of_hidden_vertices() == 1);
assert(vh == vh2);
// Same position, lower weight
vh = rt.insert(Point(Bare_point(pt.begin(), pt.end()), 1.1));
assert(rt.number_of_vertices() == 1);
assert(rt.number_of_hidden_vertices() == 2);
assert(vh == Vertex_handle());
//=======================
// New position
pt[3] = 0.78;
vh = rt.insert(Point(Bare_point(pt.begin(), pt.end()), 0.));
assert(rt.number_of_vertices() == 2);
assert(rt.number_of_hidden_vertices() == 2);
assert(vh != Vertex_handle());
// Same point
vh2 = rt.insert(Point(Bare_point(pt.begin(), pt.end()), 0.));
assert(rt.number_of_vertices() == 2);
assert(rt.number_of_hidden_vertices() == 2);
assert(vh == vh2);
// Same position, bigger weight
vh = rt.insert(Point(Bare_point(pt.begin(), pt.end()), 1.3));
assert(rt.number_of_vertices() == 2);
assert(rt.number_of_hidden_vertices() == 3);
assert(vh != Vertex_handle());
// Same point
vh2 = rt.insert(Point(Bare_point(pt.begin(), pt.end()), 1.3));
assert(rt.number_of_vertices() == 2);
assert(rt.number_of_hidden_vertices() == 3);
assert(vh == vh2);
// Same position, lower weight
vh = rt.insert(Point(Bare_point(pt.begin(), pt.end()), 1.1));
assert(rt.number_of_vertices() == 2);
assert(rt.number_of_hidden_vertices() == 4);
assert(vh == Vertex_handle());
//=======================
// New position
pt[4] = 1.78;
vh = rt.insert(Point(Bare_point(pt.begin(), pt.end()), 0.2));
assert(rt.number_of_vertices() == 3);
assert(rt.number_of_hidden_vertices() == 4);
assert(vh != Vertex_handle());
//=======================
// New position
pt[1] = 1.78;
vh = rt.insert(Point(Bare_point(pt.begin(), pt.end()), 0.8));
assert(rt.number_of_vertices() == 4);
assert(rt.number_of_hidden_vertices() == 4);
assert(vh != Vertex_handle());
//=======================
// New position
pt[2] = 1.78;
vh = rt.insert(Point(Bare_point(pt.begin(), pt.end()), 0.25));
assert(rt.number_of_vertices() == 5);
assert(rt.number_of_hidden_vertices() == 4);
assert(vh != Vertex_handle());
//=======================
// New position
pt[0] = 12.13;
vh = rt.insert(Point(Bare_point(pt.begin(), pt.end()), 1.25));
assert(rt.number_of_vertices() == 6);
assert(rt.number_of_hidden_vertices() == 4);
assert(vh != Vertex_handle());
// Same position, bigger weight
vh = rt.insert(Point(Bare_point(pt.begin(), pt.end()), 1.3));
assert(rt.number_of_vertices() == 6);
assert(rt.number_of_hidden_vertices() == 5);
assert(vh != Vertex_handle());
//=======================
// New position
pt[0] = 9.13;
vh = rt.insert(Point(Bare_point(pt.begin(), pt.end()), 1.25));
assert(rt.number_of_vertices() == 7);
assert(rt.number_of_hidden_vertices() == 5);
assert(vh != Vertex_handle());
//=======================
cerr << "\nChecking topology and geometry...";
assert(rt.is_valid(true));
rt.clear();
assert(-1 == rt.current_dimension());
assert(rt.empty());
assert(rt.is_valid());
//std::cerr << ((rt.is_valid(true)) ? "VALID!" : "NOT VALID :(") << std::endl;
}
int main(int argc, char **argv)
{
srand(static_cast<unsigned int>(time(NULL)));
int N = 10;
if( argc > 1 )
N = atoi(argv[1]);
test_inserting_points_at_the_same_position();
//go<5>(N);
go<4>(N);
go<3>(N);
go<2>(N);
go<1>(N);
cerr << endl;
return 0;
}

View File

@ -82,11 +82,7 @@ void test(const int D, const int d, const int N, bool no_transform)
for( int j = 0; j < d; ++j ) for( int j = 0; j < d; ++j )
coords[i] = coords[i] + (*pit)[j] * aff[j][i]; coords[i] = coords[i] + (*pit)[j] * aff[j][i];
} }
#ifdef USE_NEW_KERNEL points.push_back(Point(D, coords.begin(), coords.end()));
points.push_back(Point(coords)); // this is for New_kernel_d
#else
points.push_back(Point(D, coords.begin(), coords.end())); // this is for Old_kernel_d
#endif
} }
assert( dc.is_valid() ); assert( dc.is_valid() );
cout << " Inserting " << points.size() << " points."; cout << " Inserting " << points.size() << " points.";

View File

@ -53,7 +53,6 @@ void test(const int d, const string & type, int N)
Finite_full_cell_const_iterator fsit = tri.finite_full_cells_begin(); Finite_full_cell_const_iterator fsit = tri.finite_full_cells_begin();
while( fsit != tri.finite_full_cells_end() ) while( fsit != tri.finite_full_cells_end() )
{ {
fsit->circumcenter();
++fsit, ++nbfs; ++fsit, ++nbfs;
} }
cerr << nbfs << " + "; cerr << nbfs << " + ";
@ -124,10 +123,11 @@ int main(int argc, char **argv)
int N = 1000; int N = 1000;
if( argc > 1 ) if( argc > 1 )
N = atoi(argv[1]); N = atoi(argv[1]);
go<5>(N); //go<5>(N);
go<3>(N); go<4>(N);
go<2>(N); go<3>(N);
go<1>(N); go<2>(N);
go<1>(N);
cerr << std::endl; cerr << std::endl;
return 0; return 0;

View File

@ -0,0 +1,19 @@
0 0 6.28953
-2.85086 -0.471442 6.12896
1.90972 0.101219 0.988689
0.637771 2.59367 5.80372
2.22209 0.903198 2.19478
-0.487202 -2.71506 4.90996
1.1193 -1.91787 2.99626
1.54714 0.109831 0
0.44556 -2.73047 4.48142
0.427936 1.28495 6.23624
-2.67212 0.766674 5.29623
1.5763 -1.59828 2.58905
-0.476603 2.2546 6.04797
1.57172 -0.514711 6.11405
1.84528 2.10139 5.53936
-2.99827 -0.101677 5.92246
-0.482122 -2.39584 4.44264
-2.25558 -1.492 6.23448
0.128475 -1.75125 3.18916

View File

@ -0,0 +1,28 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Regular_triangulation_euclidean_traits_2.h>
#include <CGAL/Regular_triangulation_filtered_traits_2.h>
#include <CGAL/Regular_triangulation_2.h>
#include <CGAL/IO/Triangulation_off_ostream_2.h>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Regular_triangulation_filtered_traits_2<K> Traits;
typedef CGAL::Regular_triangulation_2<Traits> Regular_triangulation;
int main()
{
std::ifstream in("data/points.cin");
Regular_triangulation::Weighted_point wp;
std::vector<Regular_triangulation::Weighted_point> wpoints;
while(in >> wp)
wpoints.push_back(wp);
Regular_triangulation rt(wpoints.begin(), wpoints.end());
CGAL_assertion(rt.is_valid(true));
std::ofstream off_stream("data/rt2.off");
CGAL::export_triangulation_2_to_off(off_stream, rt);
return 0;
}

View File

@ -0,0 +1,79 @@
// Copyright (c) 2014 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL: $
// $Id: $
//
// Author(s) : Clement Jamin
#ifndef CGAL_TRIANGULATION_OFF_OSTREAM_2_H
#define CGAL_TRIANGULATION_OFF_OSTREAM_2_H
#include <CGAL/Triangulation_2.h>
#include <sstream>
#include <iostream>
namespace CGAL {
template < class GT, class TDS >
std::ostream &
export_triangulation_2_to_off(std::ostream & os,
const Triangulation_2<GT,TDS> & tr)
{
typedef Triangulation_2<GT,TDS> Tr;
typedef typename Tr::Vertex_handle Vertex_handle;
typedef typename Tr::Vertex_iterator Vertex_iterator;
typedef typename Tr::Finite_vertices_iterator Finite_vertex_iterator;
typedef typename Tr::Finite_faces_iterator Finite_faces_iterator;
size_t n = tr.number_of_vertices();
std::stringstream output;
// write the vertices
std::map<Vertex_handle, int> index_of_vertex;
int i = 0;
for(Finite_vertex_iterator it = tr.finite_vertices_begin();
it != tr.finite_vertices_end(); ++it, ++i)
{
output << it->point().x() << " " << it->point().y() << " 0" << std::endl;
index_of_vertex[it.base()] = i;
}
CGAL_assertion( i == n );
size_t number_of_triangles = 0;
for (Finite_faces_iterator fit = tr.finite_faces_begin() ;
fit != tr.finite_faces_end() ; ++fit)
{
output << "3 "
<< index_of_vertex[fit->vertex(0)] << " "
<< index_of_vertex[fit->vertex(1)] << " "
<< index_of_vertex[fit->vertex(2)]
<< std::endl;
++number_of_triangles;
}
os << "OFF \n"
<< n << " "
<< number_of_triangles << " 0\n"
<< output.str();
return os;
}
} //namespace CGAL
#endif // CGAL_TRIANGULATION_OFF_OSTREAM_2_H

View File

@ -0,0 +1,10 @@
0.0071 1.6899 2.521 0
0.3272 1.3694 3.15 0.05
1.3697 1.8296 2.654 0.1
-10.6722 0.3012 0.1548 1000.15
1.1726 0.1899 0.3658 0.2
0.4374 20.8541 1.45894 2000.25
2.5923 0.1904 0.6971 0.3
10.3083 2.5462 1.3658 1000.35
1.4981 1.3929 2.949 0.4
2.1304 2.055 0.6597455 1.45

View File

@ -0,0 +1,10 @@
0.0071 1.6899 2.521 0
0.3272 1.3694 3.15 0
1.3697 1.8296 2.654 0
-10.6722 0.3012 0.1548 0
1.1726 0.1899 0.3658 0
0.4374 20.8541 1.45894 0
2.5923 0.1904 0.6971 0
10.3083 2.5462 1.3658 0
1.4981 1.3929 2.949 0
2.1304 2.055 0.6597455 0

View File

@ -0,0 +1,10 @@
0.0071 1.6899 2.521 0
0.3272 1.3694 3.15 0
1.3697 1.8296 2.654 0
-10.6722 0.3012 0.1548 0
1.1726 0.1899 0.3658 0
0.4374 20.8541 1.45894 0
2.5923 0.1904 0.6971 0
10.3083 2.5462 1.3658 0
1.4981 1.3929 2.949 0
2.1304 2.055 0.6597455 0

View File

@ -0,0 +1,26 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Regular_triangulation_3.h>
#include <CGAL/Regular_triangulation_euclidean_traits_3.h>
#include <CGAL/IO/Triangulation_off_ostream_3.h>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Regular_triangulation_euclidean_traits_3<K> Traits;
typedef CGAL::Regular_triangulation_3<Traits> Regular_triangulation;
int main()
{
std::ifstream in("data/points.cin");
Regular_triangulation::Weighted_point wp;
std::vector<Regular_triangulation::Weighted_point> wpoints;
while(in >> wp)
wpoints.push_back(wp);
Regular_triangulation rt(wpoints.begin(), wpoints.end());
std::ofstream off_stream("data/rt3.off");
CGAL::export_triangulation_3_to_off(off_stream, rt);
return 0;
}

View File

@ -303,9 +303,6 @@ void benchmark_remove()
Time_accumulator tt(time); Time_accumulator tt(time);
tr.remove(&vhs[0], &vhs[NUM_VERTICES_TO_REMOVE - 1]); tr.remove(&vhs[0], &vhs[NUM_VERTICES_TO_REMOVE - 1]);
++iterations; ++iterations;
//std::cout<<"\b\b\b\b\b\b"<<i<<std::flush;
//tr.is_valid();
}
} while (time < BENCH_MIN_TIME); } while (time < BENCH_MIN_TIME);
cout << NUM_VERTICES_TO_REMOVE << "\t" cout << NUM_VERTICES_TO_REMOVE << "\t"

View File

@ -0,0 +1,119 @@
// Copyright (c) 2014 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL: $
// $Id: $
//
// Author(s) : Clement Jamin
#ifndef CGAL_TRIANGULATION_OFF_OSTREAM_3_H
#define CGAL_TRIANGULATION_OFF_OSTREAM_3_H
#include <CGAL/Triangulation_3.h>
#include <sstream>
#include <iostream>
namespace CGAL {
template < class GT, class TDS >
std::ostream &
export_triangulation_3_to_off(std::ostream & os,
const Triangulation_3<GT,TDS> & tr,
bool export_surface_only = false)
{
typedef Triangulation_3<GT,TDS> Tr;
typedef typename Tr::Vertex_handle Vertex_handle;
typedef typename Tr::Vertex_iterator Vertex_iterator;
typedef typename Tr::Finite_vertices_iterator Finite_vertex_iterator;
typedef typename Tr::All_cells_iterator Cells_iterator;
typedef typename Tr::Finite_cells_iterator Finite_cells_iterator;
size_t n = tr.number_of_vertices();
std::stringstream output;
// write the vertices
std::map<Vertex_handle, int> index_of_vertex;
int i = 0;
for(Finite_vertex_iterator it = tr.finite_vertices_begin();
it != tr.finite_vertices_end(); ++it, ++i)
{
output << it->point().x() << " "
<< it->point().y() << " "
<< it->point().z() << std::endl;
index_of_vertex[it.base()] = i;
}
CGAL_assertion( i == n );
size_t number_of_triangles = 0;
if (export_surface_only)
{
for (Cells_iterator cit = tr.cells_begin() ;
cit != tr.cells_end() ; ++cit)
{
if (tr.is_infinite(cit))
{
output << "3 ";
for (int i = 0 ; i < 4 ; ++i)
{
if (!tr.is_infinite(cit->vertex(i)))
output << index_of_vertex[cit->vertex(i)] << " ";
}
output << std::endl;
++number_of_triangles;
}
}
}
else
{
for (Finite_cells_iterator cit = tr.finite_cells_begin() ;
cit != tr.finite_cells_end() ; ++cit)
{
output << "3 "
<< index_of_vertex[cit->vertex(0)] << " "
<< index_of_vertex[cit->vertex(1)] << " "
<< index_of_vertex[cit->vertex(2)]
<< std::endl;
output << "3 "
<< index_of_vertex[cit->vertex(0)] << " "
<< index_of_vertex[cit->vertex(2)] << " "
<< index_of_vertex[cit->vertex(3)]
<< std::endl;
output << "3 "
<< index_of_vertex[cit->vertex(1)] << " "
<< index_of_vertex[cit->vertex(2)] << " "
<< index_of_vertex[cit->vertex(3)]
<< std::endl;
output << "3 "
<< index_of_vertex[cit->vertex(0)] << " "
<< index_of_vertex[cit->vertex(1)] << " "
<< index_of_vertex[cit->vertex(3)]
<< std::endl;
number_of_triangles += 4;
}
}
os << "OFF \n"
<< n << " "
<< number_of_triangles << " 0\n"
<< output.str();
return os;
}
} //namespace CGAL
#endif // CGAL_TRIANGULATION_OFF_OSTREAM_3_H