Partition_2: Make it work for a traits with state

This commit is contained in:
Andreas Fabri 2019-04-09 10:54:03 +02:00
parent 4ebeaf017d
commit ca161c5639
20 changed files with 145 additions and 86 deletions

View File

@ -134,9 +134,9 @@ A valid partition is one in
which the polygons are nonoverlapping and the union of the polygons is the
same as the original polygon and each polygon is \f$ y\f$-monotone
\pre P
\pre
The function returns `true` iff the partition is valid and otherwise
returns false.
returns ` false`.

View File

@ -45,12 +45,14 @@ int main()
Point_generator(100));
*/
make_polygon(polygon);
Traits traits;
CGAL::approx_convex_partition_2(polygon.vertices_begin(),
polygon.vertices_end(),
std::back_inserter(partition_polys));
std::back_inserter(partition_polys), traits);
assert(CGAL::convex_partition_is_valid_2(polygon.vertices_begin(),
polygon.vertices_end(),
partition_polys.begin(),
partition_polys.end()));
partition_polys.end(),
traits));
return 0;
}

View File

@ -44,7 +44,7 @@ int main()
Polygon_2 polygon;
Polygon_list partition_polys;
Traits partition_traits;
Validity_traits validity_traits;
Validity_traits validity_traits(partition_traits);
/*
CGAL::random_polygon_2(50, std::back_inserter(polygon),

View File

@ -55,10 +55,11 @@ int main( )
assert(CGAL::is_y_monotone_2((*poly_it).vertices_begin(),
(*poly_it).vertices_end()));
}
assert(CGAL::partition_is_valid_2(polygon.vertices_begin(),
polygon.vertices_end(),
partition_polys.begin(),
partition_polys.end()));
return 0;
}

View File

@ -45,12 +45,12 @@ class Indirect_edge_compare
typedef typename Traits::Line_2 Line_2;
typedef typename Traits::Point_2 Point_2;
Indirect_edge_compare() :
_compare_y_2(Traits().compare_y_2_object()),
_compare_x_2(Traits().compare_x_2_object()),
_construct_line_2(Traits().construct_line_2_object()),
_compare_x_at_y_2(Traits().compare_x_at_y_2_object()),
_is_horizontal_2(Traits().is_horizontal_2_object())
Indirect_edge_compare(const Traits& traits) :
_compare_y_2(traits.compare_y_2_object()),
_compare_x_2(traits.compare_x_2_object()),
_construct_line_2(traits.construct_line_2_object()),
_compare_x_at_y_2(traits.compare_x_at_y_2_object()),
_is_horizontal_2(traits.is_horizontal_2_object())
{ }
// determines if the edge (edge_vtx_1, edge_vtx_1++) has a larger

View File

@ -33,7 +33,7 @@ class Indirect_less_xy_2
public:
typedef typename Traits::Less_xy_2 Less_xy_2;
Indirect_less_xy_2() : _less_xy_2(Traits().less_xy_2_object())
Indirect_less_xy_2(const Traits& traits) : _less_xy_2(traits.less_xy_2_object())
{ }
template <class Iterator>

View File

@ -62,10 +62,6 @@ public:
friend bool operator != ( Vertex_info const& a, Vertex_info const& b ) { return !(a==b); }
friend bool operator < ( Vertex_info const& a, Vertex_info const& b )
{
return Traits().less_xy_2_object()(*a.vertex_it(), *b.vertex_it());
}
private:
@ -73,6 +69,24 @@ private:
Polygon_2 const* m_poly_ptr ;
} ;
template<class Traits_>
class Vertex_info_less
{
public:
Vertex_info_less(const Traits_ traits)
: traits(traits)
{}
bool operator()(Vertex_info<Traits_> const& a, Vertex_info<Traits_> const& b ) const
{
return traits.less_xy_2_object()(*a.vertex_it(), *b.vertex_it());
}
private:
Traits_ traits;
};
template <class Traits_>
class Edge_info
{
@ -117,9 +131,9 @@ public:
typedef typename Traits::Less_xy_2 Less_xy_2;
typedef typename Traits::Point_2 Point_2;
CW_indirect_edge_info_compare (Vertex_const_iterator v_info) : vertex_it(v_info),
left_turn(Traits().left_turn_2_object()),
less_xy(Traits().less_xy_2_object())
CW_indirect_edge_info_compare (Vertex_const_iterator v_info, const Traits& traits) : vertex_it(v_info),
left_turn(traits.left_turn_2_object()),
less_xy(traits.less_xy_2_object())
{}
bool operator()(Edge_info e1, Edge_info e2)
@ -185,6 +199,12 @@ public:
Edge_info const& back() const { return m_list.back() ; }
Edge_info & back() { return m_list.back() ; }
Edge_list(const Traits& traits)
: traits(traits)
{}
template<class Compare> void sort ( Compare c ) { m_list.sort(c); }
void insert_next(Vertex_info endpoint_ref, int num)
@ -242,7 +262,7 @@ public:
// polygon.
if (m_list.size() > 2)
{
m_list.sort(CW_indirect_edge_info_compare<Traits>(vertex_it));
m_list.sort(CW_indirect_edge_info_compare<Traits>(vertex_it,traits));
}
#ifdef CGAL_PARTITION_CHECK_DEBUG
@ -301,7 +321,7 @@ public:
}
private :
Traits traits;
List m_list ;
};
@ -335,7 +355,8 @@ public:
typedef Partition_vertex_map<Traits> Self;
typedef std::map<Vertex_info, Edge_list> Map ;
typedef Vertex_info_less<Traits> Less;
typedef std::map<Vertex_info, Edge_list,Less> Map ;
typedef typename Map::const_iterator Self_const_iterator;
typedef typename Map::iterator Self_iterator;
@ -348,7 +369,8 @@ public:
Partition_vertex_map() {}
template <class InputIterator>
Partition_vertex_map(InputIterator first_poly, InputIterator last_poly)
Partition_vertex_map(InputIterator first_poly, InputIterator last_poly, const Traits& traits)
: m_map(traits), traits(traits)
{ _build(first_poly, last_poly); }
Self_const_iterator begin() const { return m_map.begin() ; }
@ -419,7 +441,7 @@ public:
if ((*m_it).second.size() > 2)
{
(*m_it).second.sort(
CW_indirect_edge_info_compare<Traits>((*m_it).first.vertex_it()));
CW_indirect_edge_info_compare<Traits>((*m_it).first.vertex_it(),traits));
}
// find the previous vertex in this vertex's list
@ -474,7 +496,7 @@ private :
vtx_begin = (*poly_first).vertices_begin();
vtx_end = (*poly_first).vertices_end();
begin_v_loc_pair = m_map.insert(P_Vertex( Vertex_info(vtx_begin,poly_ptr), Edge_list()));
begin_v_loc_pair = m_map.insert(P_Vertex( Vertex_info(vtx_begin,poly_ptr), Edge_list(traits)));
prev_v_loc_pair = begin_v_loc_pair;
v_it = vtx_begin;
@ -482,7 +504,7 @@ private :
for (v_it++; v_it != vtx_end; v_it++)
{
v_loc_pair = m_map.insert(P_Vertex( Vertex_info(v_it,poly_ptr), Edge_list()));
v_loc_pair = m_map.insert(P_Vertex( Vertex_info(v_it,poly_ptr), Edge_list(traits)));
insert_next_edge(prev_v_loc_pair.first, v_loc_pair.first, poly_num);
@ -509,7 +531,7 @@ private :
}
private :
Traits traits;
Map m_map ;
};

View File

@ -43,8 +43,9 @@ public:
Indirect_CW_diag_compare(){}
Indirect_CW_diag_compare(Point_2 vertex, Iterator prev_ref,
Iterator next_ref) :
_orientation(Traits().orientation_2_object()),
Iterator next_ref,
const Traits& traits) :
_orientation(traits.orientation_2_object()),
_vertex(vertex),
_prev_v_ref(prev_ref)
{
@ -114,12 +115,13 @@ public:
typedef typename Diagonal_list::iterator Diagonal_iterator;
Partitioned_polygon_2() : _left_turn(Traits().left_turn_2_object())
{ }
Partitioned_polygon_2(const Traits& traits)
: _left_turn(traits.left_turn_2_object()), traits(traits)
{}
template <class InputIterator>
Partitioned_polygon_2(InputIterator first, InputIterator beyond) :
_left_turn(Traits().left_turn_2_object())
Partitioned_polygon_2(InputIterator first, InputIterator beyond, const Traits& traits) :
_left_turn(traits.left_turn_2_object()), traits(traits)
{
for (; first != beyond; first++) {
this->push_back(Vertex(*first));
@ -180,7 +182,7 @@ public:
{
next = c;
next++;
(*c).sort_diagonals(prev, next);
(*c).sort_diagonals(prev, next, traits);
#ifdef CGAL_PARTITIONED_POLY_DEBUG
(*c).print_diagonals();
#endif
@ -287,7 +289,8 @@ private:
cuts_reflex_angle(diag_ref2, diag_ref1));
}
Left_turn_2 _left_turn;
Left_turn_2 _left_turn;
Traits traits;
};
template <class Traits_>
@ -369,9 +372,9 @@ class Partition_vertex : public Traits_::Point_2
// sort the diagonals ccw around the point they have in common
// and remove any duplicate diagonals
void sort_diagonals(const Circulator& prev, const Circulator& next)
void sort_diagonals(const Circulator& prev, const Circulator& next, const Traits& traits)
{
diag_endpoint_refs.sort(Indirect_CW_diag_compare<Circulator,Traits>(*this, prev, next));
diag_endpoint_refs.sort(Indirect_CW_diag_compare<Circulator,Traits>(*this, prev, next, traits));
diag_endpoint_refs.unique();
current_diag = diag_endpoint_refs.begin();

View File

@ -42,7 +42,7 @@ class Point_pair_less_xy_2
typedef typename Traits::Less_xy_2 Less_xy_2;
public:
Point_pair_less_xy_2() : _less_xy_2(Traits().less_xy_2_object())
Point_pair_less_xy_2(const Traits& traits) : _less_xy_2(traits.less_xy_2_object())
{ }

View File

@ -72,12 +72,12 @@ public:
// constructor
template<class ForwardIterator>
Rotation_tree_2(ForwardIterator first, ForwardIterator beyond)
Rotation_tree_2(ForwardIterator first, ForwardIterator beyond, const Traits& traits)
{
for (ForwardIterator it = first; it != beyond; it++)
push_back(*it);
Greater greater (Traits().less_xy_2_object());
Greater greater (traits.less_xy_2_object());
std::sort(this->begin(), this->end(), greater);
std::unique(this->begin(), this->end());

View File

@ -50,11 +50,11 @@ class Segment_less_yx_2
typedef Turn_reverser<Point_2, Left_turn_2> Right_turn_2;
public:
Segment_less_yx_2() :
_less_xy_2(Traits().less_xy_2_object()),
_compare_x_2(Traits().compare_x_2_object()),
_compare_y_2(Traits().compare_y_2_object()),
_left_turn_2(Traits().left_turn_2_object()),
Segment_less_yx_2(const Traits& traits) :
_less_xy_2(traits.less_xy_2_object()),
_compare_x_2(traits.compare_x_2_object()),
_compare_y_2(traits.compare_y_2_object()),
_left_turn_2(traits.left_turn_2_object()),
_right_turn_2(Right_turn_2(_left_turn_2))
{ }

View File

@ -133,30 +133,31 @@ public:
// first and beyond should be iterators over vertices of a polygon
//
template <class ForwardIterator>
Vertex_visibility_graph_2(ForwardIterator first, ForwardIterator beyond):
left_turn_2(Traits().left_turn_2_object()),
orientation_2(Traits().orientation_2_object()),
collinear_ordered_2(Traits().collinear_are_ordered_along_line_2_object()),
Vertex_visibility_graph_2(ForwardIterator first, ForwardIterator beyond, const Traits& traits):
left_turn_2(traits.left_turn_2_object()),
orientation_2(traits.orientation_2_object()),
collinear_ordered_2(traits.collinear_are_ordered_along_line_2_object()),
are_strictly_ordered_along_line_2(
Traits().are_strictly_ordered_along_line_2_object()),
less_xy_2(Traits().less_xy_2_object()),
construct_segment_2(Traits().construct_segment_2_object()),
construct_ray_2(Traits().construct_ray_2_object()),
intersect_2(Traits().intersect_2_object()),
assign_2(Traits().assign_2_object())
traits.are_strictly_ordered_along_line_2_object()),
less_xy_2(traits.less_xy_2_object()),
construct_segment_2(traits.construct_segment_2_object()),
construct_ray_2(traits.construct_ray_2_object()),
intersect_2(traits.intersect_2_object()),
assign_2(traits.assign_2_object()),
edges(Point_pair_compare(traits))
{
build(first, beyond);
build(first, beyond, traits);
}
// Pre: ccw order of points; no repeated points
template <class ForwardIterator>
void build(ForwardIterator first, ForwardIterator beyond)
void build(ForwardIterator first, ForwardIterator beyond, const Traits& traits)
{
Polygon polygon(first,beyond);
Tree tree(polygon.begin(), polygon.end());
Tree tree(polygon.begin(), polygon.end(),traits);
Vertex_map vertex_map;
initialize_vertex_map(polygon, vertex_map);
initialize_vertex_map(polygon, vertex_map,traits);
// NOTE: use the std::list as the basis here because otherwise the basis
// is a deque, which is buggy under MSVC++
@ -353,7 +354,8 @@ private:
// immediately below it. For vertical edges, the segment below is not the
// one that begins at the other endpoint of the edge.
void initialize_vertex_map(const Polygon& polygon,
Vertex_map& vertex_map);
Vertex_map& vertex_map,
const Traits& traits);
// determines if one makes a left turn going from p to q to q's parent.
// if q's parent is p_infinity, then a left turn is made when p's x value

View File

@ -56,8 +56,9 @@ Vertex_visibility_graph_2<Traits>::is_valid(ForwardIterator first,
// one that begins at the other endpoint of the edge.
template <class Traits>
void
Vertex_visibility_graph_2<Traits>::initialize_vertex_map(
const Polygon& polygon, Vertex_map& vertex_map)
Vertex_visibility_graph_2<Traits>::initialize_vertex_map(const Polygon& polygon,
Vertex_map& vertex_map,
const Traits& traits)
{
typedef typename Vertex_map::value_type Map_pair;
@ -67,12 +68,12 @@ Vertex_visibility_graph_2<Traits>::initialize_vertex_map(
// Sort the event list (iterators to points) from left to right
// (using less_xy)
iterator_list.sort(Indirect_less_xy_2<Traits>());
iterator_list.sort(Indirect_less_xy_2<Traits>(traits));
// Create an ordered list of edge endpoints (iterators), initially empty
typedef std::set< Point_pair, Segment_less_yx_2 > Ordered_edge_set;
typedef typename Ordered_edge_set::iterator Ordered_edge_set_iterator;
Ordered_edge_set ordered_edges;
Segment_less_yx_2 less_xy(traits);
Ordered_edge_set ordered_edges(less_xy);
Ordered_edge_set_iterator edge_it;
Vertex_map_iterator vm_it;
Vertex_map_iterator vis_it;

View File

@ -145,7 +145,7 @@ OutputIterator partition_approx_convex_2(InputIterator first,
typedef typename Constrained_tri_2::Vertex_handle Vertex_handle;
typedef typename Gt::Segment_2 Segment_2;
P_Polygon_2 polygon(first, beyond);
P_Polygon_2 polygon(first, beyond,traits);
CGAL_partition_precondition(
orientation_2(polygon.begin(), polygon.end(), traits) == COUNTERCLOCKWISE);

View File

@ -457,7 +457,7 @@ void partition_opt_cvx_preprocessing(Polygon& polygon,
typedef typename Traits::Point_2 Point_2;
typedef std::pair<Point_2, Point_2> Point_pair;
Vis_graph graph(polygon.begin(), polygon.end());
Vis_graph graph(polygon.begin(), polygon.end(), traits);
size_type prev_i, i, next_i, next_next_i;
size_type prev_j, j, next_j;
@ -528,7 +528,7 @@ OutputIterator partition_optimal_convex_2(InputIterator first,
Tee_for_output_iterator<OutputIterator, Polygon_2> res(result);
#endif // no postconditions
P_Polygon_2 polygon(first, beyond);
P_Polygon_2 polygon(first, beyond,traits);
CGAL_partition_precondition(
orientation_2(polygon.begin(), polygon.end(), traits) == COUNTERCLOCKWISE);

View File

@ -436,7 +436,7 @@ OutputIterator partition_y_monotone_2(InputIterator first,
Tee_for_output_iterator<OutputIterator, Polygon_2> res(result);
#endif // no postcondition
P_Polygon_2 polygon(first, beyond);
P_Polygon_2 polygon(first, beyond, traits);
CGAL_partition_precondition(
orientation_2(polygon.begin(), polygon.end(), traits) == COUNTERCLOCKWISE);
@ -457,9 +457,10 @@ OutputIterator partition_y_monotone_2(InputIterator first,
std::cout << std::endl;
#endif
typedef std::map<Circulator, Circulator,
Indirect_edge_compare<Circulator, Traits> > Tree;
Tree tree;
typedef Indirect_edge_compare<Circulator, Traits> Cmp;
typedef std::map<Circulator, Circulator, Cmp> Tree;
Cmp cmp(traits);
Tree tree(cmp);
typename std::vector<Circulator>::iterator it = circulators.begin();
for (; it != circulators.end(); it++) {

View File

@ -38,7 +38,11 @@ public:
typedef typename Traits::Orientation_2 Orientation_2;
typedef PolygonIsValid Is_valid;
Partition_is_valid_traits_2(const Traits& traits)
: Traits(traits)
{}
Is_valid
is_valid_object(const Traits& traits) const
{ return Is_valid(traits); }

View File

@ -38,6 +38,7 @@ class Partition_traits_2 : public Partition_traits_2_base<Kernel_>
private:
typedef Kernel_ Kernel;
typedef Partition_traits_2<Kernel_> Self;
public:
typedef typename Kernel::Point_2 Point_2;
typedef ::std::list<Point_2> Container;

View File

@ -132,6 +132,8 @@ polygons_are_equal(Circulator1 orig_first, Circulator2 new_first)
}
namespace internal {
template<class InputIterator, class ForwardIterator, class Traits>
bool
partition_is_valid_2 (InputIterator point_first, InputIterator point_last,
@ -157,7 +159,7 @@ partition_is_valid_2 (InputIterator point_first, InputIterator point_last,
CGAL_partition_precondition(orientation_2(orig_poly.begin(),orig_poly.end(),
traits) == COUNTERCLOCKWISE);
P_Vertex_map output_vertex_set(poly_first, poly_last);
P_Vertex_map output_vertex_set(poly_first, poly_last, traits);
if (output_vertex_set.polygons_overlap()) return false;
@ -206,7 +208,8 @@ partition_is_valid_2 (InputIterator point_first, InputIterator point_last,
return polygons_w_steiner_are_equal(orig_poly_circ, union_poly_circ,
traits);
}
} // namespace internal
template<class InputIterator, class FowardIterator>
bool
partition_is_valid_2 (InputIterator point_first, InputIterator point_last,
@ -223,6 +226,25 @@ partition_is_valid_2 (InputIterator point_first, InputIterator point_last,
poly_first, poly_last, validity_traits);
}
template<class InputIterator, class FowardIterator, class Traits>
bool
partition_is_valid_2 (InputIterator point_first, InputIterator point_last,
FowardIterator poly_first, FowardIterator poly_last,
const Traits& traits)
{
typedef typename std::iterator_traits<InputIterator>::value_type Point_2;
typedef typename Kernel_traits<Point_2>::Kernel K;
typedef Partition_traits_2<K> Traits;
typedef Is_vacuously_valid<Traits> Is_valid;
Partition_is_valid_traits_2<Traits, Is_valid> validity_traits(traits);
return internal::partition_is_valid_2(point_first, point_last,
poly_first, poly_last, validity_traits);
}
template<class InputIterator, class ForwardIterator, class Traits>
bool
@ -230,13 +252,13 @@ convex_partition_is_valid_2(InputIterator point_first,
InputIterator point_last,
ForwardIterator poly_first,
ForwardIterator poly_last,
const Traits& )
const Traits& traits)
{
typedef typename Traits::Is_convex_2 Is_convex_2;
Partition_is_valid_traits_2<Traits, Is_convex_2> validity_traits;
Partition_is_valid_traits_2<Traits, Is_convex_2> validity_traits(traits);
return partition_is_valid_2(point_first, point_last, poly_first, poly_last,
validity_traits);
return internal::partition_is_valid_2(point_first, point_last, poly_first, poly_last,
validity_traits);
}
template<class InputIterator, class ForwardIterator>
@ -260,14 +282,14 @@ y_monotone_partition_is_valid_2(InputIterator point_first,
InputIterator point_last,
ForwardIterator poly_first,
ForwardIterator poly_last,
const Traits& )
const Traits& traits)
{
typedef typename Traits::Is_y_monotone_2 Is_y_monotone_2;
Partition_is_valid_traits_2<Traits, Is_y_monotone_2> validity_traits;
Partition_is_valid_traits_2<Traits, Is_y_monotone_2> validity_traits(traits);
return partition_is_valid_2(point_first, point_last, poly_first, poly_last,
validity_traits);
return internal::partition_is_valid_2(point_first, point_last, poly_first, poly_last,
validity_traits);
}
template<class InputIterator, class ForwardIterator>

View File

@ -25,7 +25,7 @@ public:
/*!
*/
boost::property_traits<PointPropertyMap>::key_type Point_2;
typdef boost::property_traits<PointPropertyMap>::key_type Point_2;
/// @}