mirror of https://github.com/CGAL/cgal
Improved the divide-and-conquer algorithm for aggregated operations,
so that we use merge sort instead of O(n log(n)) sort. (with Baruch)
This commit is contained in:
parent
c5492b6644
commit
403cf9d75c
|
|
@ -12,7 +12,7 @@
|
|||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// $Id$ $Date$
|
||||
//
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
#define GSP_AGG_OP_H
|
||||
|
||||
#include <CGAL/Boolean_set_operations_2/Gps_agg_meta_traits.h>
|
||||
#include <CGAL/Sweep_line_2.h>
|
||||
#include <CGAL/Boolean_set_operations_2/Gps_agg_op_sweep.h>
|
||||
#include <CGAL/Sweep_line_2/Arr_construction_curve.h>
|
||||
#include <CGAL/Sweep_line_2/Arr_construction_event.h>
|
||||
|
||||
|
|
@ -52,20 +52,28 @@ class Gps_agg_op
|
|||
Ccb_halfedge_const_circulator;
|
||||
typedef typename Arrangement_2::Ccb_halfedge_circulator
|
||||
Ccb_halfedge_circulator;
|
||||
|
||||
typedef std::pair<Arrangement_2 *,
|
||||
std::vector<Vertex_handle> *> Arr_entry;
|
||||
|
||||
typedef Arr_construction_curve<Meta_traits> Subcurve;
|
||||
typedef Arr_construction_event<Meta_traits,
|
||||
Subcurve,
|
||||
Halfedge_handle> Event;
|
||||
Halfedge_handle> Base_event;
|
||||
|
||||
typedef Indexed_event<Base_event> Event;
|
||||
|
||||
typedef Gps_agg_op_visitor<Meta_traits,
|
||||
Arrangement_2,
|
||||
Event,
|
||||
Subcurve> Visitor;
|
||||
|
||||
typedef Sweep_line_2<Meta_traits,
|
||||
typedef Gps_agg_op_sweep_line_2<Arrangement_2,
|
||||
Meta_traits,
|
||||
Visitor,
|
||||
Subcurve,
|
||||
Event> Sweep_line_2;
|
||||
|
||||
typedef Unique_hash_map<Halfedge_handle,
|
||||
unsigned int> Edges_hash;
|
||||
|
||||
|
|
@ -85,19 +93,18 @@ protected:
|
|||
public:
|
||||
|
||||
/*! Constructor. */
|
||||
Gps_agg_op (Arrangement_2& arr, Traits_2& tr) :
|
||||
Gps_agg_op (Arrangement_2& arr, std::vector<Vertex_handle>& vert_vec,
|
||||
Traits_2& tr) :
|
||||
m_arr (&arr),
|
||||
m_traits(new Meta_traits(tr)),
|
||||
m_visitor (&arr, &m_edges_hash),
|
||||
m_visitor (&arr, &m_edges_hash, &vert_vec),
|
||||
m_sweep_line (m_traits, &m_visitor)
|
||||
{}
|
||||
|
||||
|
||||
|
||||
void sweep_arrangements(unsigned int lower,
|
||||
unsigned int upper,
|
||||
unsigned int jump,
|
||||
std::vector<Arrangement_2*>& arr_vec)
|
||||
std::vector<Arr_entry>& arr_vec)
|
||||
{
|
||||
std::list<Meta_X_monotone_curve_2> curves_list;
|
||||
|
||||
|
|
@ -107,9 +114,11 @@ public:
|
|||
unsigned int n_inf_pgn = 0; // number of infinte polygons (arrangement
|
||||
// with a contained unbounded face
|
||||
unsigned int n_pgn = 0; // number of polygons (arrangements)
|
||||
for(unsigned int i=lower; i<=upper; i+=jump, ++n_pgn)
|
||||
unsigned int i;
|
||||
|
||||
for (i = lower; i <= upper; i += jump, ++n_pgn)
|
||||
{
|
||||
Arrangement_2* arr = arr_vec[i];
|
||||
Arrangement_2* arr = (arr_vec[i]).first;
|
||||
if (arr->unbounded_face()->contained())
|
||||
++n_inf_pgn;
|
||||
|
||||
|
|
@ -129,7 +138,10 @@ public:
|
|||
curves_list.push_back(Meta_X_monotone_curve_2(he->curve(), cv_data));
|
||||
}
|
||||
}
|
||||
m_sweep_line.sweep(curves_list.begin(), curves_list.end());
|
||||
|
||||
m_sweep_line.sweep (curves_list.begin(), curves_list.end(),
|
||||
lower, upper, jump,
|
||||
arr_vec);
|
||||
|
||||
m_faces_hash[m_arr->unbounded_face()] = n_inf_pgn;
|
||||
Bfs_visitor visitor(&m_edges_hash, &m_faces_hash, n_pgn);
|
||||
|
|
@ -139,48 +151,6 @@ public:
|
|||
visitor.after_scan(*m_arr);
|
||||
}
|
||||
|
||||
//Arrangement_2* create_clean_arr()
|
||||
//{
|
||||
// typedef Gps_insertion_meta_traits<Arrangement_2> Insert_meta_traits;
|
||||
// typedef typename Insert_meta_traits::Curve_data Curve_data;
|
||||
// typedef Arr_construction_curve<Insert_meta_traits> Subcurve;
|
||||
// typedef Arr_construction_event<Insert_meta_traits,
|
||||
// Subcurve,
|
||||
// Halfedge_handle> Event;
|
||||
// typedef typename Insert_meta_traits::X_monotone_curve_2 Ex_X_monotone_curve_2;
|
||||
// typedef Arr_construction_visitor<Insert_meta_traits,
|
||||
// Arrangement_2,
|
||||
// Event,
|
||||
// Subcurve> Insertion_visitor;
|
||||
// typedef Basic_sweep_line_2<Insert_meta_traits,
|
||||
// Insertion_visitor,
|
||||
// Subcurve,
|
||||
// Event> Basic_sweep_line_2;
|
||||
|
||||
//
|
||||
//
|
||||
// Arrangement_2* new_arr = new Arrangement_2();
|
||||
// std::vector<Ex_X_monotone_curve_2> xcurves_vec;
|
||||
// for(Edge_iterator itr = m_arr->edges_begin();
|
||||
// itr != m_arr->edges_end();
|
||||
// ++itr)
|
||||
// {
|
||||
// Halfedge_handle he = itr;
|
||||
// if(he->face()->contained() == he->twin()->face()->contained())
|
||||
// continue; //redundent edge, continue.
|
||||
|
||||
// if(he->direction() == LARGER)
|
||||
// he = he->twin();
|
||||
|
||||
// xcurves_vec.push_back(Ex_X_monotone_curve_2(he->curve(), Curve_data(he)));
|
||||
// }
|
||||
|
||||
// std::cout<<"number of edges in clear arr: " << xcurves_vec.size()<<"\n";
|
||||
// Insertion_visitor visitor(new_arr);
|
||||
// Basic_sweep_line_2 sl (&visitor);
|
||||
// sl.sweep(xcurves_vec.begin(), xcurves_vec.end());
|
||||
//}
|
||||
|
||||
~Gps_agg_op()
|
||||
{
|
||||
delete m_traits;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,275 @@
|
|||
// Copyright (c) 2005 Tel-Aviv University (Israel).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
||||
// the terms of the Q Public License version 1.0.
|
||||
// See the file LICENSE.QPL distributed with CGAL.
|
||||
//
|
||||
// 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$ $Date$
|
||||
//
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
|
||||
#ifndef GSP_AGG_OP_SWEEP_H
|
||||
#define GSP_AGG_OP_SWEEP_H
|
||||
|
||||
#include <CGAL/Sweep_line_2.h>
|
||||
#include <CGAL/Unique_hash_map.h>
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template <class Arrangement_,
|
||||
class MetaTraits_,
|
||||
class SweepVisitor,
|
||||
class CurveWrap,
|
||||
class SweepEvent,
|
||||
typename Allocator = CGAL_ALLOCATOR(int) >
|
||||
class Gps_agg_op_sweep_line_2 :
|
||||
public Sweep_line_2<MetaTraits_,
|
||||
SweepVisitor,
|
||||
CurveWrap,
|
||||
SweepEvent,
|
||||
Allocator>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Arrangement_ Arrangement_2;
|
||||
typedef MetaTraits_ Traits_2;
|
||||
typedef typename Traits_2::Point_2 Point_2;
|
||||
typedef typename Traits_2::X_monotone_curve_2 X_monotone_curve_2;
|
||||
|
||||
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
|
||||
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
|
||||
|
||||
typedef std::pair<Arrangement_2 *,
|
||||
std::vector<Vertex_handle> *> Arr_entry;
|
||||
|
||||
typedef Sweep_line_2<Traits_2,
|
||||
SweepVisitor,
|
||||
CurveWrap,
|
||||
SweepEvent,
|
||||
Allocator> Base;
|
||||
|
||||
typedef SweepEvent Event;
|
||||
typedef typename Base::EventQueueIter EventQueueIter;
|
||||
typedef typename Event::SubCurveIter EventCurveIter;
|
||||
|
||||
typedef typename Base::Base_event Base_event;
|
||||
typedef typename Base_event::Attribute Attribute;
|
||||
|
||||
typedef typename Base::Base_subcurve Base_subcurve;
|
||||
|
||||
typedef CurveWrap Subcurve;
|
||||
|
||||
typedef std::list<Subcurve*> SubCurveList;
|
||||
typedef typename SubCurveList::iterator SubCurveListIter;
|
||||
|
||||
typedef typename Base::StatusLineIter StatusLineIter;
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
* Constructor.
|
||||
* \param visitor A pointer to a sweep-line visitor object.
|
||||
*/
|
||||
Gps_agg_op_sweep_line_2 (SweepVisitor* visitor) :
|
||||
Base (visitor)
|
||||
{}
|
||||
|
||||
/*!
|
||||
* Constructor.
|
||||
* \param traits A pointer to a sweep-line traits object.
|
||||
* \param visitor A pointer to a sweep-line visitor object.
|
||||
*/
|
||||
Gps_agg_op_sweep_line_2 (Traits_2 *traits, SweepVisitor* visitor) :
|
||||
Base(traits, visitor)
|
||||
{}
|
||||
|
||||
/*! Perform the sweep. */
|
||||
template<class CurveInputIterator>
|
||||
void sweep (CurveInputIterator curves_begin,
|
||||
CurveInputIterator curves_end,
|
||||
unsigned int lower,
|
||||
unsigned int upper,
|
||||
unsigned int jump,
|
||||
std::vector<Arr_entry>& arr_vec)
|
||||
{
|
||||
CGAL_assertion (this->m_queue->empty() &&
|
||||
this->m_statusLine.size() == 0);
|
||||
|
||||
typedef Unique_hash_map<Vertex_handle, Event *> Vertices_map;
|
||||
typedef typename Traits_2::Compare_xy_2 Compare_xy_2;
|
||||
|
||||
// Allocate all of the Subcurve objects as one block.
|
||||
this->m_num_of_subCurves = std::distance (curves_begin, curves_end);
|
||||
this->m_subCurves =
|
||||
this->m_subCurveAlloc.allocate (this->m_num_of_subCurves);
|
||||
|
||||
this->m_curves_pair_set.resize (2 * this->m_num_of_subCurves);
|
||||
|
||||
// Initialize the event queue using the vertices vectors. Note that these
|
||||
// vertices are already sorted, we simply have to merge them
|
||||
Vertices_map vert_map;
|
||||
Vertex_handle vh;
|
||||
Vertex_handle invalid_v;
|
||||
unsigned int i = lower;
|
||||
unsigned int n = (arr_vec[i].second)->size();
|
||||
unsigned int j;
|
||||
EventQueueIter q_iter;
|
||||
bool first = true;
|
||||
Attribute event_type;
|
||||
Event *event;
|
||||
|
||||
for (j = 0;
|
||||
j < n && (vh = (*(arr_vec[i].second))[j]) != invalid_v;
|
||||
j++)
|
||||
{
|
||||
// Insert the vertices of the first vector one after the other.
|
||||
event_type = _type_of_vertex (vh);
|
||||
if (event_type == Base_event::DEFAULT)
|
||||
continue;
|
||||
|
||||
event = this->allocate_event (vh->point(), event_type);
|
||||
|
||||
if (! first)
|
||||
{
|
||||
q_iter = this->m_queue->insert_after (q_iter, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
q_iter = this->m_queue->insert (event);
|
||||
first = false;
|
||||
}
|
||||
|
||||
vert_map[vh] = event;
|
||||
}
|
||||
|
||||
Comparison_result res = LARGER;
|
||||
Compare_xy_2 comp_xy = this->m_traits->compare_xy_2_object();
|
||||
EventQueueIter q_end = this->m_queue->end();
|
||||
|
||||
for (i += jump; i <= upper; i += jump)
|
||||
{
|
||||
// Merge the vertices of the other vectors into the existing queue.
|
||||
q_iter = this->m_queue->begin();
|
||||
n = (arr_vec[i].second)->size();
|
||||
|
||||
for (j = 0;
|
||||
j < n && (vh = (*(arr_vec[i].second))[j]) != invalid_v;
|
||||
j++)
|
||||
{
|
||||
event_type = _type_of_vertex (vh);
|
||||
if (event_type == Base_event::DEFAULT)
|
||||
continue;
|
||||
|
||||
while (q_iter != q_end &&
|
||||
(res = comp_xy (vh->point(), (*q_iter)->get_point())) == LARGER)
|
||||
{
|
||||
++q_iter;
|
||||
}
|
||||
|
||||
if (res == SMALLER || q_iter == q_end)
|
||||
{
|
||||
event = this->allocate_event (vh->point(), event_type);
|
||||
this->m_queue->insert_before (q_iter, event);
|
||||
vert_map[vh] = event;
|
||||
}
|
||||
else if (res == EQUAL)
|
||||
{
|
||||
// In this case q_iter points to an event already associated with
|
||||
// the vertex, so we just update the map:
|
||||
vert_map[vh] = *q_iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Go over all curves (which are associated with halfedges) and associate
|
||||
// them with the events we have just created.
|
||||
unsigned int index = 0;
|
||||
CurveInputIterator iter;
|
||||
Halfedge_handle he;
|
||||
Event *e_left;
|
||||
Event *e_right;
|
||||
|
||||
for (iter = curves_begin; iter != curves_end; ++iter, index++)
|
||||
{
|
||||
// Get the events associated with the end-vertices of the current
|
||||
// halfedge.
|
||||
he = iter->data().halfedge();
|
||||
|
||||
CGAL_assertion (vert_map.is_defined (he->source()));
|
||||
CGAL_assertion (vert_map.is_defined (he->target()));
|
||||
|
||||
if (he->direction() == SMALLER)
|
||||
{
|
||||
e_left = vert_map[he->source()];
|
||||
e_right = vert_map[he->target()];
|
||||
}
|
||||
else
|
||||
{
|
||||
e_left = vert_map[he->target()];
|
||||
e_right = vert_map[he->source()];
|
||||
}
|
||||
|
||||
// Create the subcurve object.
|
||||
this->m_subCurveAlloc.construct (this->m_subCurves + index,
|
||||
this->m_masterSubcurve);
|
||||
|
||||
(this->m_subCurves + index)->init (*iter, e_left, e_right);
|
||||
|
||||
e_right->add_curve_to_left (this->m_subCurves + index);
|
||||
this->_add_curve_to_right (e_left, this->m_subCurves + index);
|
||||
}
|
||||
|
||||
// Perform the sweep:
|
||||
this->m_visitor->after_init();
|
||||
this->_sweep();
|
||||
this->_complete_sweep();
|
||||
this->m_visitor->after_sweep();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/*!
|
||||
* Check if the given vertex is an endpoint of an edge we are going
|
||||
* to use in the sweep.
|
||||
*/
|
||||
Attribute _type_of_vertex (Vertex_handle v)
|
||||
{
|
||||
typename Arrangement_2::Halfedge_around_vertex_circulator first, circ;
|
||||
|
||||
circ = first = v->incident_halfedges();
|
||||
do
|
||||
{
|
||||
// Check if the current edge separates two faces with unequal
|
||||
// containment flags (otherwise we will simply not keep it).
|
||||
if (circ->face()->contained() != circ->twin()->face()->contained())
|
||||
{
|
||||
if (circ->direction() == SMALLER)
|
||||
return (Base_event::RIGHT_END);
|
||||
else
|
||||
return (Base_event::LEFT_END);
|
||||
}
|
||||
++circ;
|
||||
|
||||
} while (circ != first);
|
||||
|
||||
// If we reached here, we should not keep this vertex.
|
||||
return (Base_event::DEFAULT);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
//
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
|
||||
#ifndef GSP_AGG_OP_VISITOR
|
||||
#define GSP_AGG_OP_VISITOR
|
||||
|
|
@ -26,7 +27,7 @@
|
|||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template<class Traits, class Arrangement_, class Event,class Subcurve>
|
||||
class Gps_agg_op_visitor :
|
||||
class Gps_agg_op_base_visitor :
|
||||
public Arr_construction_visitor<Traits,Arrangement_,Event,Subcurve>
|
||||
{
|
||||
protected:
|
||||
|
|
@ -38,11 +39,6 @@ class Gps_agg_op_visitor :
|
|||
Event,
|
||||
Subcurve> Base;
|
||||
|
||||
typedef Gps_agg_op_visitor<Traits,
|
||||
Arrangement,
|
||||
Event,
|
||||
Subcurve> Self;
|
||||
|
||||
typedef typename Base::SL_iterator SL_iterator;
|
||||
typedef typename Base::Halfedge_handle Halfedge_handle;
|
||||
typedef typename Base::Vertex_handle Vertex_handle;
|
||||
|
|
@ -51,8 +47,6 @@ class Gps_agg_op_visitor :
|
|||
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
|
||||
typedef typename Traits::Point_2 Point_2;
|
||||
|
||||
typedef typename Arrangement::Face_handle Face_handle;
|
||||
typedef typename Arrangement::Face_const_handle Face_const_handle;
|
||||
typedef Unique_hash_map<Halfedge_handle, unsigned int> Edges_hash;
|
||||
|
||||
protected:
|
||||
|
|
@ -62,7 +56,7 @@ protected:
|
|||
|
||||
public:
|
||||
|
||||
Gps_agg_op_visitor(Arrangement *arr,
|
||||
Gps_agg_op_base_visitor(Arrangement *arr,
|
||||
Edges_hash* hash): Base(arr),
|
||||
m_edges_hash(hash)
|
||||
{}
|
||||
|
|
@ -135,6 +129,145 @@ private:
|
|||
|
||||
};
|
||||
|
||||
template <class BaseEvent_>
|
||||
class Indexed_event : public BaseEvent_
|
||||
{
|
||||
private:
|
||||
|
||||
unsigned int m_index;
|
||||
|
||||
public:
|
||||
|
||||
Indexed_event () :
|
||||
BaseEvent_(),
|
||||
m_index (0)
|
||||
{}
|
||||
|
||||
unsigned int index () const
|
||||
{
|
||||
return (m_index);
|
||||
}
|
||||
|
||||
void set_index (unsigned int index)
|
||||
{
|
||||
m_index = index;
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
template<class Traits, class Arrangement_, class Event, class Subcurve>
|
||||
class Gps_agg_op_visitor :
|
||||
public Gps_agg_op_base_visitor<Traits, Arrangement_, Event, Subcurve>
|
||||
{
|
||||
protected:
|
||||
|
||||
typedef Arrangement_ Arrangement;
|
||||
|
||||
typedef Gps_agg_op_base_visitor<Traits,
|
||||
Arrangement,
|
||||
Event,
|
||||
Subcurve> Base;
|
||||
|
||||
typedef typename Base::SL_iterator SL_iterator;
|
||||
typedef typename Base::Halfedge_handle Halfedge_handle;
|
||||
typedef typename Base::Vertex_handle Vertex_handle;
|
||||
typedef typename Base::SubCurveIter SubCurveIter;
|
||||
typedef typename Base::SubCurveRevIter SubCurveRevIter;
|
||||
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
|
||||
typedef typename Traits::Point_2 Point_2;
|
||||
|
||||
protected:
|
||||
|
||||
unsigned int m_event_count; // The number of events so far.
|
||||
std::vector<Vertex_handle> *m_vertices_vec; // The vertices, sorted in
|
||||
// ascending order.
|
||||
|
||||
public:
|
||||
|
||||
Gps_agg_op_visitor (Arrangement *arr,
|
||||
typename Base::Edges_hash* hash,
|
||||
std::vector<Vertex_handle>* vertices_vec) :
|
||||
Base (arr, hash),
|
||||
m_event_count (0),
|
||||
m_vertices_vec (vertices_vec)
|
||||
{}
|
||||
|
||||
void before_handle_event (Event* event)
|
||||
{
|
||||
event->set_index (m_event_count);
|
||||
m_event_count++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
virtual Halfedge_handle
|
||||
insert_in_face_interior (const X_monotone_curve_2& cv,
|
||||
Subcurve* sc)
|
||||
{
|
||||
Halfedge_handle res_he = Base::insert_in_face_interior(cv, sc);
|
||||
|
||||
// We now have a halfedge whose source vertex is associated with the
|
||||
// last event and whose target vertex is associated with the current event:
|
||||
Event *curr_event = reinterpret_cast<Event*>(this->current_event());
|
||||
Event *last_event = reinterpret_cast<Event*>((sc)->get_last_event());
|
||||
|
||||
CGAL_assertion (res_he->direction() == SMALLER);
|
||||
_insert_vertex (curr_event, res_he->target());
|
||||
_insert_vertex (last_event, res_he->source());
|
||||
|
||||
return (res_he);
|
||||
}
|
||||
|
||||
virtual Halfedge_handle
|
||||
insert_from_right_vertex (const X_monotone_curve_2& cv,
|
||||
Halfedge_handle he,
|
||||
Subcurve* sc)
|
||||
{
|
||||
Halfedge_handle res_he = Base::insert_from_right_vertex (cv, he, sc);
|
||||
|
||||
// We now have a halfedge whose target vertex is associated with the
|
||||
// last event (we have already dealt with its source vertex).
|
||||
Event *last_event = reinterpret_cast<Event*>((sc)->get_last_event());
|
||||
|
||||
CGAL_assertion (res_he->direction() == LARGER);
|
||||
_insert_vertex (last_event, res_he->target());
|
||||
|
||||
return (res_he);
|
||||
}
|
||||
|
||||
virtual Halfedge_handle
|
||||
insert_from_left_vertex (const X_monotone_curve_2& cv,
|
||||
Halfedge_handle he,
|
||||
Subcurve* sc)
|
||||
{
|
||||
Halfedge_handle res_he = Base::insert_from_left_vertex (cv, he, sc);
|
||||
|
||||
// We now have a halfedge whose target vertex is associated with the
|
||||
// current event (we have already dealt with its source vertex).
|
||||
Event *curr_event = reinterpret_cast<Event*>(this->current_event());
|
||||
|
||||
CGAL_assertion (res_he->direction() == SMALLER);
|
||||
_insert_vertex (curr_event, res_he->target());
|
||||
|
||||
return (res_he);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void _insert_vertex (const Event* event,
|
||||
Vertex_handle v)
|
||||
{
|
||||
const unsigned int index = event->index();
|
||||
|
||||
if (index >= m_vertices_vec->size())
|
||||
m_vertices_vec->resize (2 * (index + 1));
|
||||
|
||||
(*m_vertices_vec)[index] = v;
|
||||
return;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// $Id$ $Date$
|
||||
//
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
|
|
@ -29,86 +29,113 @@
|
|||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template <class Arrangement>
|
||||
template <class Arrangement_>
|
||||
class Join_merge
|
||||
{
|
||||
typedef Arrangement_ Arrangement_2;
|
||||
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
|
||||
typedef std::pair<Arrangement_2 *,
|
||||
std::vector<Vertex_handle> *> Arr_entry;
|
||||
|
||||
public:
|
||||
void operator()(unsigned int i,
|
||||
unsigned int j,
|
||||
unsigned int jump,
|
||||
std::vector<Arrangement*>& arr_vec)
|
||||
std::vector<Arr_entry>& arr_vec)
|
||||
{
|
||||
if(i==j)
|
||||
return;
|
||||
|
||||
typename Arrangement::Traits_2* tr = arr_vec[i]->get_traits();
|
||||
Arrangement* res = new Arrangement(tr);
|
||||
Gps_agg_op<Arrangement, Gps_bfs_join_visitor<Arrangement> >
|
||||
agg_op(*res, *tr);
|
||||
typename Arrangement_2::Traits_2* tr = arr_vec[i].first->get_traits();
|
||||
Arrangement_2 *res = new Arrangement_2(tr);
|
||||
std::vector<Vertex_handle> *verts = new std::vector<Vertex_handle>;
|
||||
|
||||
Gps_agg_op<Arrangement_2, Gps_bfs_join_visitor<Arrangement_2> >
|
||||
agg_op(*res, *verts, *tr);
|
||||
agg_op.sweep_arrangements(i, j, jump, arr_vec);
|
||||
|
||||
for(unsigned int count=i; count<=j; count+=jump)
|
||||
{
|
||||
delete arr_vec[count];
|
||||
delete (arr_vec[count].first);
|
||||
delete (arr_vec[count].second);
|
||||
}
|
||||
|
||||
arr_vec[i] = res;
|
||||
arr_vec[i].first = res;
|
||||
arr_vec[i].second = verts;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <class Arrangement>
|
||||
template <class Arrangement_>
|
||||
class Intersection_merge
|
||||
{
|
||||
typedef Arrangement_ Arrangement_2;
|
||||
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
|
||||
typedef std::pair<Arrangement_2 *,
|
||||
std::vector<Vertex_handle> *> Arr_entry;
|
||||
|
||||
public:
|
||||
void operator()(unsigned int i,
|
||||
unsigned int j,
|
||||
unsigned int jump,
|
||||
std::vector<Arrangement*>& arr_vec)
|
||||
std::vector<Arr_entry>& arr_vec)
|
||||
{
|
||||
if(i==j)
|
||||
return;
|
||||
|
||||
typename Arrangement::Traits_2* tr = arr_vec[i]->get_traits();
|
||||
Arrangement* res = new Arrangement(tr);
|
||||
Gps_agg_op<Arrangement, Gps_bfs_intersection_visitor<Arrangement> >
|
||||
agg_op(*res, *tr);
|
||||
typename Arrangement_2::Traits_2* tr = arr_vec[i].first->get_traits();
|
||||
Arrangement_2 *res = new Arrangement_2 (tr);
|
||||
std::vector<Vertex_handle> *verts = new std::vector<Vertex_handle>;
|
||||
|
||||
Gps_agg_op<Arrangement_2, Gps_bfs_intersection_visitor<Arrangement_2> >
|
||||
agg_op(*res, *verts, *tr);
|
||||
agg_op.sweep_arrangements(i, j, jump, arr_vec);
|
||||
|
||||
for(unsigned int count=i; count<=j; count+=jump)
|
||||
{
|
||||
delete arr_vec[count];
|
||||
delete (arr_vec[count].first);
|
||||
delete (arr_vec[count].second);
|
||||
}
|
||||
|
||||
arr_vec[i] = res;
|
||||
arr_vec[i].first = res;
|
||||
arr_vec[i].second = verts;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Arrangement>
|
||||
template <class Arrangement_>
|
||||
class Xor_merge
|
||||
{
|
||||
typedef Arrangement_ Arrangement_2;
|
||||
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
|
||||
typedef std::pair<Arrangement_2 *,
|
||||
std::vector<Vertex_handle> *> Arr_entry;
|
||||
|
||||
public:
|
||||
void operator()(unsigned int i,
|
||||
unsigned int j,
|
||||
unsigned int jump,
|
||||
std::vector<Arrangement*>& arr_vec)
|
||||
std::vector<Arr_entry>& arr_vec)
|
||||
{
|
||||
if(i==j)
|
||||
return;
|
||||
|
||||
typename Arrangement::Traits_2* tr = arr_vec[i]->get_traits();
|
||||
Arrangement* res = new Arrangement(tr);
|
||||
Gps_agg_op<Arrangement, Gps_bfs_xor_visitor<Arrangement> >
|
||||
agg_op(*res, *tr);
|
||||
typename Arrangement_2::Traits_2* tr = arr_vec[i].first->get_traits();
|
||||
Arrangement_2 *res = new Arrangement_2(tr);
|
||||
std::vector<Vertex_handle> *verts = new std::vector<Vertex_handle>;
|
||||
|
||||
Gps_agg_op<Arrangement_2, Gps_bfs_xor_visitor<Arrangement_2> >
|
||||
agg_op(*res, *verts, *tr);
|
||||
agg_op.sweep_arrangements(i, j, jump, arr_vec);
|
||||
|
||||
for(unsigned int count=i; count<=j; count+=jump)
|
||||
{
|
||||
delete arr_vec[count];
|
||||
delete (arr_vec[count].first);
|
||||
delete (arr_vec[count].second);
|
||||
}
|
||||
|
||||
arr_vec[i] = res;
|
||||
arr_vec[i].first = res;
|
||||
arr_vec[i].second = verts;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ class Gps_polygon_simplifier
|
|||
Subcurve,
|
||||
Halfedge_handle> Event;
|
||||
|
||||
typedef Gps_agg_op_visitor<Meta_traits,
|
||||
typedef Gps_agg_op_base_visitor<Meta_traits,
|
||||
Arrangement_2,
|
||||
Event,
|
||||
Subcurve> Visitor;
|
||||
|
|
@ -71,6 +71,7 @@ class Gps_polygon_simplifier
|
|||
Visitor,
|
||||
Subcurve,
|
||||
Event> Sweep_line_2;
|
||||
|
||||
typedef Unique_hash_map<Halfedge_handle,
|
||||
unsigned int> Edges_hash;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// $Id$ $Date$
|
||||
//
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
|
|
@ -91,6 +91,8 @@ private:
|
|||
typedef typename Arrangement_2::Halfedge_around_vertex_const_circulator
|
||||
Halfedge_around_vertex_const_circulator;
|
||||
|
||||
typedef std::pair<Arrangement_2 *,
|
||||
std::vector<Vertex_handle> *> Arr_entry;
|
||||
typedef Arr_walk_along_line_point_location<Arrangement_2> Walk_pl;
|
||||
|
||||
protected:
|
||||
|
|
@ -587,21 +589,23 @@ inline void join(InputIterator begin,
|
|||
Polygon_2& pgn,
|
||||
unsigned int k=5)
|
||||
{
|
||||
std::vector<Arrangement_2*> arr_vec (std::distance(begin, end) + 1);
|
||||
std::vector<Arr_entry> arr_vec (std::distance(begin, end) + 1);
|
||||
|
||||
arr_vec[0] = this->m_arr;
|
||||
arr_vec[0].first = this->m_arr;
|
||||
unsigned int i = 1;
|
||||
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
||||
{
|
||||
arr_vec[i] = new Arrangement_2(m_traits);
|
||||
_insert(*itr, *arr_vec[i]);
|
||||
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||
_insert(*itr, *(arr_vec[i].first));
|
||||
}
|
||||
|
||||
Join_merge<Arrangement_2> join_merge;
|
||||
divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, join_merge);
|
||||
_build_sorted_vertices_vectors (arr_vec);
|
||||
_divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, join_merge);
|
||||
|
||||
//the result arrangement is at index 0
|
||||
this->m_arr = arr_vec[0];
|
||||
this->m_arr = arr_vec[0].first;
|
||||
delete arr_vec[0].second;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -612,21 +616,23 @@ inline void join(InputIterator begin,
|
|||
Polygon_with_holes_2& pgn,
|
||||
unsigned int k=5)
|
||||
{
|
||||
std::vector<Arrangement_2*> arr_vec (std::distance(begin, end) + 1);
|
||||
arr_vec[0] = this->m_arr;
|
||||
std::vector<Arr_entry> arr_vec (std::distance(begin, end) + 1);
|
||||
arr_vec[0].first = this->m_arr;
|
||||
|
||||
unsigned int i = 1;
|
||||
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
||||
{
|
||||
arr_vec[i] = new Arrangement_2(m_traits);
|
||||
_insert(*itr, *arr_vec[i]);
|
||||
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||
_insert(*itr, *(arr_vec[i].first));
|
||||
}
|
||||
|
||||
Join_merge<Arrangement_2> join_merge;
|
||||
divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, join_merge);
|
||||
_build_sorted_vertices_vectors (arr_vec);
|
||||
_divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, join_merge);
|
||||
|
||||
//the result arrangement is at index 0
|
||||
this->m_arr = arr_vec[0];
|
||||
this->m_arr = arr_vec[0].first;
|
||||
delete arr_vec[0].second;
|
||||
}
|
||||
|
||||
template <class InputIterator1, class InputIterator2>
|
||||
|
|
@ -636,29 +642,31 @@ inline void join(InputIterator1 begin1,
|
|||
InputIterator2 end2,
|
||||
unsigned int k=5)
|
||||
{
|
||||
std::vector<Arrangement_2*> arr_vec (std::distance(begin1, end1)+
|
||||
std::vector<Arr_entry> arr_vec (std::distance(begin1, end1)+
|
||||
std::distance(begin2, end2)+1);
|
||||
|
||||
arr_vec[0] = this->m_arr;
|
||||
arr_vec[0].first = this->m_arr;
|
||||
unsigned int i = 1;
|
||||
|
||||
for(InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i)
|
||||
{
|
||||
arr_vec[i] = new Arrangement_2(m_traits);
|
||||
_insert(*itr1, *arr_vec[i]);
|
||||
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||
_insert(*itr1, *(arr_vec[i].first));
|
||||
}
|
||||
|
||||
for(InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i)
|
||||
{
|
||||
arr_vec[i] = new Arrangement_2(m_traits);
|
||||
_insert(*itr2, *arr_vec[i]);
|
||||
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||
_insert(*itr2, *(arr_vec[i].first));
|
||||
}
|
||||
|
||||
Join_merge<Arrangement_2> join_merge;
|
||||
divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, join_merge);
|
||||
_build_sorted_vertices_vectors (arr_vec);
|
||||
_divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, join_merge);
|
||||
|
||||
//the result arrangement is at index 0
|
||||
this->m_arr = arr_vec[0];
|
||||
this->m_arr = arr_vec[0].first;
|
||||
delete arr_vec[0].second;
|
||||
this->remove_redundant_edges();
|
||||
this->_reset_faces();
|
||||
}
|
||||
|
|
@ -682,22 +690,24 @@ inline void intersection(InputIterator begin,
|
|||
Polygon_2& pgn,
|
||||
unsigned int k)
|
||||
{
|
||||
std::vector<Arrangement_2*> arr_vec (std::distance(begin, end) + 1);
|
||||
arr_vec[0] = this->m_arr;
|
||||
std::vector<Arr_entry> arr_vec (std::distance(begin, end) + 1);
|
||||
arr_vec[0].first = this->m_arr;
|
||||
unsigned int i = 1;
|
||||
|
||||
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
||||
{
|
||||
CGAL_precondition(m_traits->is_valid_2_object()(*itr));
|
||||
arr_vec[i] = new Arrangement_2(m_traits);
|
||||
_insert(*itr, *arr_vec[i]);
|
||||
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||
_insert(*itr, *(arr_vec[i].first));
|
||||
}
|
||||
|
||||
Intersection_merge<Arrangement_2> intersection_merge;
|
||||
divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, intersection_merge);
|
||||
_build_sorted_vertices_vectors (arr_vec);
|
||||
_divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, intersection_merge);
|
||||
|
||||
//the result arrangement is at index 0
|
||||
this->m_arr = arr_vec[0];
|
||||
this->m_arr = arr_vec[0].first;
|
||||
delete arr_vec[0].second;
|
||||
}
|
||||
|
||||
//intersect range of polygons with holes
|
||||
|
|
@ -707,22 +717,24 @@ inline void intersection(InputIterator begin,
|
|||
Polygon_with_holes_2& pgn,
|
||||
unsigned int k)
|
||||
{
|
||||
std::vector<Arrangement_2*> arr_vec (std::distance(begin, end) + 1);
|
||||
arr_vec[0] = this->m_arr;
|
||||
std::vector<Arr_entry> arr_vec (std::distance(begin, end) + 1);
|
||||
arr_vec[0].first = this->m_arr;
|
||||
unsigned int i = 1;
|
||||
|
||||
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
||||
{
|
||||
CGAL_precondition(m_traits->is_valid_2_object()(*itr));
|
||||
arr_vec[i] = new Arrangement_2(m_traits);
|
||||
_insert(*itr, *arr_vec[i]);
|
||||
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||
_insert(*itr, *(arr_vec[i].first));
|
||||
}
|
||||
|
||||
Intersection_merge<Arrangement_2> intersection_merge;
|
||||
divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, intersection_merge);
|
||||
_build_sorted_vertices_vectors (arr_vec);
|
||||
_divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, intersection_merge);
|
||||
|
||||
//the result arrangement is at index 0
|
||||
this->m_arr = arr_vec[0];
|
||||
this->m_arr = arr_vec[0].first;
|
||||
delete arr_vec[0].second;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -733,30 +745,32 @@ inline void intersection(InputIterator1 begin1,
|
|||
InputIterator2 end2,
|
||||
unsigned int k=5)
|
||||
{
|
||||
std::vector<Arrangement_2*> arr_vec (std::distance(begin1, end1)+
|
||||
std::vector<Arr_entry> arr_vec (std::distance(begin1, end1)+
|
||||
std::distance(begin2, end2)+1);
|
||||
arr_vec[0] = this->m_arr;
|
||||
arr_vec[0].first = this->m_arr;
|
||||
unsigned int i = 1;
|
||||
|
||||
for(InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i)
|
||||
{
|
||||
CGAL_precondition(m_traits->is_valid_2_object()(*itr1));
|
||||
arr_vec[i] = new Arrangement_2(m_traits);
|
||||
_insert(*itr1, *arr_vec[i]);
|
||||
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||
_insert(*itr1, *(arr_vec[i].first));
|
||||
}
|
||||
|
||||
for(InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i)
|
||||
{
|
||||
CGAL_precondition(m_traits->is_valid_2_object()(*itr2));
|
||||
arr_vec[i] = new Arrangement_2(m_traits);
|
||||
_insert(*itr2, *arr_vec[i]);
|
||||
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||
_insert(*itr2, *(arr_vec[i].first));
|
||||
}
|
||||
|
||||
Intersection_merge<Arrangement_2> intersection_merge;
|
||||
divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, intersection_merge);
|
||||
_build_sorted_vertices_vectors (arr_vec);
|
||||
_divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, intersection_merge);
|
||||
|
||||
//the result arrangement is at index 0
|
||||
this->m_arr = arr_vec[0];
|
||||
this->m_arr = arr_vec[0].first;
|
||||
delete arr_vec[0].second;
|
||||
this->remove_redundant_edges();
|
||||
this->_reset_faces();
|
||||
}
|
||||
|
|
@ -782,22 +796,24 @@ inline void symmetric_difference(InputIterator begin,
|
|||
Polygon_2& pgn,
|
||||
unsigned int k=5)
|
||||
{
|
||||
std::vector<Arrangement_2*> arr_vec (std::distance(begin, end) + 1);
|
||||
arr_vec[0] = this->m_arr;
|
||||
std::vector<Arr_entry> arr_vec (std::distance(begin, end) + 1);
|
||||
arr_vec[0].first = this->m_arr;
|
||||
unsigned int i = 1;
|
||||
|
||||
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
||||
{
|
||||
CGAL_precondition(m_traits->is_valid_2_object()(*itr));
|
||||
arr_vec[i] = new Arrangement_2(m_traits);
|
||||
_insert(*itr, *arr_vec[i]);
|
||||
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||
_insert(*itr, *(arr_vec[i].first));
|
||||
}
|
||||
|
||||
Xor_merge<Arrangement_2> xor_merge;
|
||||
divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, xor_merge);
|
||||
_build_sorted_vertices_vectors (arr_vec);
|
||||
_divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, xor_merge);
|
||||
|
||||
//the result arrangement is at index 0
|
||||
this->m_arr = arr_vec[0];
|
||||
this->m_arr = arr_vec[0].first;
|
||||
delete arr_vec[0].second;
|
||||
}
|
||||
|
||||
//intersect range of polygons with holes
|
||||
|
|
@ -807,22 +823,24 @@ inline void symmetric_difference(InputIterator begin,
|
|||
Polygon_with_holes_2& pgn,
|
||||
unsigned int k=5)
|
||||
{
|
||||
std::vector<Arrangement_2*> arr_vec (std::distance(begin, end) + 1);
|
||||
arr_vec[0] = this->m_arr;
|
||||
std::vector<Arr_entry> arr_vec (std::distance(begin, end) + 1);
|
||||
arr_vec[0].first = this->m_arr;
|
||||
unsigned int i = 1;
|
||||
|
||||
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
||||
{
|
||||
CGAL_precondition(m_traits->is_valid_2_object()(*itr));
|
||||
arr_vec[i] = new Arrangement_2(m_traits);
|
||||
_insert(*itr, *arr_vec[i]);
|
||||
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||
_insert(*itr, *(arr_vec[i].first));
|
||||
}
|
||||
|
||||
Xor_merge<Arrangement_2> xor_merge;
|
||||
divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, xor_merge);
|
||||
_build_sorted_vertices_vectors (arr_vec);
|
||||
_divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, xor_merge);
|
||||
|
||||
//the result arrangement is at index 0
|
||||
this->m_arr = arr_vec[0];
|
||||
this->m_arr = arr_vec[0].first;
|
||||
delete arr_vec[0].second;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -833,30 +851,32 @@ inline void symmetric_difference(InputIterator1 begin1,
|
|||
InputIterator2 end2,
|
||||
unsigned int k=5)
|
||||
{
|
||||
std::vector<Arrangement_2*> arr_vec (std::distance(begin1, end1)+
|
||||
std::vector<Arr_entry> arr_vec (std::distance(begin1, end1)+
|
||||
std::distance(begin2, end2)+1);
|
||||
arr_vec[0] = this->m_arr;
|
||||
arr_vec[0].first = this->m_arr;
|
||||
unsigned int i = 1;
|
||||
|
||||
for(InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i)
|
||||
{
|
||||
CGAL_precondition(m_traits->is_valid_2_object()(*itr1));
|
||||
arr_vec[i] = new Arrangement_2(m_traits);
|
||||
_insert(*itr1, *arr_vec[i]);
|
||||
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||
_insert(*itr1, *(arr_vec[i].first));
|
||||
}
|
||||
|
||||
for(InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i)
|
||||
{
|
||||
CGAL_precondition(m_traits->is_valid_2_object()(*itr2));
|
||||
arr_vec[i] = new Arrangement_2(m_traits);
|
||||
_insert(*itr2, *arr_vec[i]);
|
||||
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||
_insert(*itr2, *(arr_vec[i].first));
|
||||
}
|
||||
|
||||
Xor_merge<Arrangement_2> xor_merge;
|
||||
divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, xor_merge);
|
||||
_build_sorted_vertices_vectors (arr_vec);
|
||||
_divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, xor_merge);
|
||||
|
||||
//the result arrangement is at index 0
|
||||
this->m_arr = arr_vec[0];
|
||||
this->m_arr = arr_vec[0].first;
|
||||
delete arr_vec[0].second;
|
||||
this->remove_redundant_edges();
|
||||
this->_reset_faces();
|
||||
}
|
||||
|
|
@ -896,10 +916,57 @@ void _remove_redundant_edges(Arrangement_2* arr)
|
|||
}
|
||||
}
|
||||
|
||||
class Less_vertex_handle
|
||||
{
|
||||
typename Traits_2::Compare_xy_2 comp_xy;
|
||||
|
||||
public:
|
||||
|
||||
Less_vertex_handle (const typename Traits_2::Compare_xy_2& cmp) :
|
||||
comp_xy (cmp)
|
||||
{}
|
||||
|
||||
bool operator() (Vertex_handle v1, Vertex_handle v2) const
|
||||
{
|
||||
return (comp_xy (v1->point(), v2->point()) == SMALLER);
|
||||
}
|
||||
};
|
||||
|
||||
void _build_sorted_vertices_vectors (std::vector<Arr_entry>& arr_vec)
|
||||
{
|
||||
Less_vertex_handle comp (m_traits->compare_xy_2_object());
|
||||
Arrangement_2 *p_arr;
|
||||
Vertex_iterator vit;
|
||||
const unsigned int n = arr_vec.size();
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
// Allocate a vector of handles to all vertices in the current
|
||||
// arrangement.
|
||||
p_arr = arr_vec[i].first;
|
||||
arr_vec[i].second = new std::vector<Vertex_handle>;
|
||||
arr_vec[i].second->resize (p_arr->number_of_vertices());
|
||||
|
||||
for (j = 0, vit = p_arr->vertices_begin();
|
||||
vit != p_arr->vertices_end();
|
||||
j++, ++vit)
|
||||
{
|
||||
(*(arr_vec[i].second))[j] = vit;
|
||||
}
|
||||
|
||||
// Sort the vector.
|
||||
std::sort (arr_vec[i].second->begin(), arr_vec[i].second->end(),
|
||||
comp);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
template <class Merge>
|
||||
void divide_and_conquer(unsigned int lower,
|
||||
void _divide_and_conquer (unsigned int lower,
|
||||
unsigned int upper,
|
||||
std::vector<Arrangement_2*>& arr_vec,
|
||||
std::vector<Arr_entry>& arr_vec,
|
||||
unsigned int k,
|
||||
Merge merge_func)
|
||||
{
|
||||
|
|
@ -916,13 +983,13 @@ void divide_and_conquer(unsigned int lower,
|
|||
|
||||
for(; i<k-1; ++i, curr_lower += sub_size )
|
||||
{
|
||||
divide_and_conquer(curr_lower,
|
||||
_divide_and_conquer (curr_lower,
|
||||
curr_lower + sub_size-1,
|
||||
arr_vec,
|
||||
k,
|
||||
merge_func);
|
||||
}
|
||||
divide_and_conquer(curr_lower, upper,arr_vec, k, merge_func);
|
||||
_divide_and_conquer (curr_lower, upper,arr_vec, k, merge_func);
|
||||
merge_func (lower, curr_lower, sub_size ,arr_vec);
|
||||
|
||||
return;
|
||||
|
|
|
|||
Loading…
Reference in New Issue