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.
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$ $Date$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
#define GSP_AGG_OP_H
|
#define GSP_AGG_OP_H
|
||||||
|
|
||||||
#include <CGAL/Boolean_set_operations_2/Gps_agg_meta_traits.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_curve.h>
|
||||||
#include <CGAL/Sweep_line_2/Arr_construction_event.h>
|
#include <CGAL/Sweep_line_2/Arr_construction_event.h>
|
||||||
|
|
||||||
|
|
@ -52,20 +52,28 @@ class Gps_agg_op
|
||||||
Ccb_halfedge_const_circulator;
|
Ccb_halfedge_const_circulator;
|
||||||
typedef typename Arrangement_2::Ccb_halfedge_circulator
|
typedef typename Arrangement_2::Ccb_halfedge_circulator
|
||||||
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_curve<Meta_traits> Subcurve;
|
||||||
typedef Arr_construction_event<Meta_traits,
|
typedef Arr_construction_event<Meta_traits,
|
||||||
Subcurve,
|
Subcurve,
|
||||||
Halfedge_handle> Event;
|
Halfedge_handle> Base_event;
|
||||||
|
|
||||||
|
typedef Indexed_event<Base_event> Event;
|
||||||
|
|
||||||
typedef Gps_agg_op_visitor<Meta_traits,
|
typedef Gps_agg_op_visitor<Meta_traits,
|
||||||
Arrangement_2,
|
Arrangement_2,
|
||||||
Event,
|
Event,
|
||||||
Subcurve> Visitor;
|
Subcurve> Visitor;
|
||||||
|
|
||||||
typedef Sweep_line_2<Meta_traits,
|
typedef Gps_agg_op_sweep_line_2<Arrangement_2,
|
||||||
|
Meta_traits,
|
||||||
Visitor,
|
Visitor,
|
||||||
Subcurve,
|
Subcurve,
|
||||||
Event> Sweep_line_2;
|
Event> Sweep_line_2;
|
||||||
|
|
||||||
typedef Unique_hash_map<Halfedge_handle,
|
typedef Unique_hash_map<Halfedge_handle,
|
||||||
unsigned int> Edges_hash;
|
unsigned int> Edges_hash;
|
||||||
|
|
||||||
|
|
@ -85,19 +93,18 @@ protected:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*! Constructor. */
|
/*! 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_arr (&arr),
|
||||||
m_traits(new Meta_traits(tr)),
|
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)
|
m_sweep_line (m_traits, &m_visitor)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void sweep_arrangements(unsigned int lower,
|
void sweep_arrangements(unsigned int lower,
|
||||||
unsigned int upper,
|
unsigned int upper,
|
||||||
unsigned int jump,
|
unsigned int jump,
|
||||||
std::vector<Arrangement_2*>& arr_vec)
|
std::vector<Arr_entry>& arr_vec)
|
||||||
{
|
{
|
||||||
std::list<Meta_X_monotone_curve_2> curves_list;
|
std::list<Meta_X_monotone_curve_2> curves_list;
|
||||||
|
|
||||||
|
|
@ -107,10 +114,12 @@ public:
|
||||||
unsigned int n_inf_pgn = 0; // number of infinte polygons (arrangement
|
unsigned int n_inf_pgn = 0; // number of infinte polygons (arrangement
|
||||||
// with a contained unbounded face
|
// with a contained unbounded face
|
||||||
unsigned int n_pgn = 0; // number of polygons (arrangements)
|
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())
|
if (arr->unbounded_face()->contained())
|
||||||
++n_inf_pgn;
|
++n_inf_pgn;
|
||||||
|
|
||||||
Edge_iterator itr = arr->edges_begin();
|
Edge_iterator itr = arr->edges_begin();
|
||||||
|
|
@ -129,7 +138,10 @@ public:
|
||||||
curves_list.push_back(Meta_X_monotone_curve_2(he->curve(), cv_data));
|
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;
|
m_faces_hash[m_arr->unbounded_face()] = n_inf_pgn;
|
||||||
Bfs_visitor visitor(&m_edges_hash, &m_faces_hash, n_pgn);
|
Bfs_visitor visitor(&m_edges_hash, &m_faces_hash, n_pgn);
|
||||||
|
|
@ -139,48 +151,6 @@ public:
|
||||||
visitor.after_scan(*m_arr);
|
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()
|
~Gps_agg_op()
|
||||||
{
|
{
|
||||||
delete m_traits;
|
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>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
|
// Ron Wein <wein@post.tau.ac.il>
|
||||||
|
|
||||||
#ifndef GSP_AGG_OP_VISITOR
|
#ifndef GSP_AGG_OP_VISITOR
|
||||||
#define GSP_AGG_OP_VISITOR
|
#define GSP_AGG_OP_VISITOR
|
||||||
|
|
@ -26,7 +27,7 @@
|
||||||
CGAL_BEGIN_NAMESPACE
|
CGAL_BEGIN_NAMESPACE
|
||||||
|
|
||||||
template<class Traits, class Arrangement_, class Event,class Subcurve>
|
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>
|
public Arr_construction_visitor<Traits,Arrangement_,Event,Subcurve>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -38,11 +39,6 @@ class Gps_agg_op_visitor :
|
||||||
Event,
|
Event,
|
||||||
Subcurve> Base;
|
Subcurve> Base;
|
||||||
|
|
||||||
typedef Gps_agg_op_visitor<Traits,
|
|
||||||
Arrangement,
|
|
||||||
Event,
|
|
||||||
Subcurve> Self;
|
|
||||||
|
|
||||||
typedef typename Base::SL_iterator SL_iterator;
|
typedef typename Base::SL_iterator SL_iterator;
|
||||||
typedef typename Base::Halfedge_handle Halfedge_handle;
|
typedef typename Base::Halfedge_handle Halfedge_handle;
|
||||||
typedef typename Base::Vertex_handle Vertex_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::X_monotone_curve_2 X_monotone_curve_2;
|
||||||
typedef typename Traits::Point_2 Point_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;
|
typedef Unique_hash_map<Halfedge_handle, unsigned int> Edges_hash;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -62,7 +56,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Gps_agg_op_visitor(Arrangement *arr,
|
Gps_agg_op_base_visitor(Arrangement *arr,
|
||||||
Edges_hash* hash): Base(arr),
|
Edges_hash* hash): Base(arr),
|
||||||
m_edges_hash(hash)
|
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
|
CGAL_END_NAMESPACE
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$ $Date$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
|
|
@ -29,86 +29,113 @@
|
||||||
|
|
||||||
CGAL_BEGIN_NAMESPACE
|
CGAL_BEGIN_NAMESPACE
|
||||||
|
|
||||||
template <class Arrangement>
|
template <class Arrangement_>
|
||||||
class Join_merge
|
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:
|
public:
|
||||||
void operator()(unsigned int i,
|
void operator()(unsigned int i,
|
||||||
unsigned int j,
|
unsigned int j,
|
||||||
unsigned int jump,
|
unsigned int jump,
|
||||||
std::vector<Arrangement*>& arr_vec)
|
std::vector<Arr_entry>& arr_vec)
|
||||||
{
|
{
|
||||||
if(i==j)
|
if(i==j)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
typename Arrangement::Traits_2* tr = arr_vec[i]->get_traits();
|
typename Arrangement_2::Traits_2* tr = arr_vec[i].first->get_traits();
|
||||||
Arrangement* res = new Arrangement(tr);
|
Arrangement_2 *res = new Arrangement_2(tr);
|
||||||
Gps_agg_op<Arrangement, Gps_bfs_join_visitor<Arrangement> >
|
std::vector<Vertex_handle> *verts = new std::vector<Vertex_handle>;
|
||||||
agg_op(*res, *tr);
|
|
||||||
|
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);
|
agg_op.sweep_arrangements(i, j, jump, arr_vec);
|
||||||
|
|
||||||
for(unsigned int count=i; count<=j; count+=jump)
|
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
|
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:
|
public:
|
||||||
void operator()(unsigned int i,
|
void operator()(unsigned int i,
|
||||||
unsigned int j,
|
unsigned int j,
|
||||||
unsigned int jump,
|
unsigned int jump,
|
||||||
std::vector<Arrangement*>& arr_vec)
|
std::vector<Arr_entry>& arr_vec)
|
||||||
{
|
{
|
||||||
if(i==j)
|
if(i==j)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
typename Arrangement::Traits_2* tr = arr_vec[i]->get_traits();
|
typename Arrangement_2::Traits_2* tr = arr_vec[i].first->get_traits();
|
||||||
Arrangement* res = new Arrangement(tr);
|
Arrangement_2 *res = new Arrangement_2 (tr);
|
||||||
Gps_agg_op<Arrangement, Gps_bfs_intersection_visitor<Arrangement> >
|
std::vector<Vertex_handle> *verts = new std::vector<Vertex_handle>;
|
||||||
agg_op(*res, *tr);
|
|
||||||
|
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);
|
agg_op.sweep_arrangements(i, j, jump, arr_vec);
|
||||||
|
|
||||||
for(unsigned int count=i; count<=j; count+=jump)
|
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
|
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:
|
public:
|
||||||
void operator()(unsigned int i,
|
void operator()(unsigned int i,
|
||||||
unsigned int j,
|
unsigned int j,
|
||||||
unsigned int jump,
|
unsigned int jump,
|
||||||
std::vector<Arrangement*>& arr_vec)
|
std::vector<Arr_entry>& arr_vec)
|
||||||
{
|
{
|
||||||
if(i==j)
|
if(i==j)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
typename Arrangement::Traits_2* tr = arr_vec[i]->get_traits();
|
typename Arrangement_2::Traits_2* tr = arr_vec[i].first->get_traits();
|
||||||
Arrangement* res = new Arrangement(tr);
|
Arrangement_2 *res = new Arrangement_2(tr);
|
||||||
Gps_agg_op<Arrangement, Gps_bfs_xor_visitor<Arrangement> >
|
std::vector<Vertex_handle> *verts = new std::vector<Vertex_handle>;
|
||||||
agg_op(*res, *tr);
|
|
||||||
|
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);
|
agg_op.sweep_arrangements(i, j, jump, arr_vec);
|
||||||
|
|
||||||
for(unsigned int count=i; count<=j; count+=jump)
|
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,
|
Subcurve,
|
||||||
Halfedge_handle> Event;
|
Halfedge_handle> Event;
|
||||||
|
|
||||||
typedef Gps_agg_op_visitor<Meta_traits,
|
typedef Gps_agg_op_base_visitor<Meta_traits,
|
||||||
Arrangement_2,
|
Arrangement_2,
|
||||||
Event,
|
Event,
|
||||||
Subcurve> Visitor;
|
Subcurve> Visitor;
|
||||||
|
|
@ -71,6 +71,7 @@ class Gps_polygon_simplifier
|
||||||
Visitor,
|
Visitor,
|
||||||
Subcurve,
|
Subcurve,
|
||||||
Event> Sweep_line_2;
|
Event> Sweep_line_2;
|
||||||
|
|
||||||
typedef Unique_hash_map<Halfedge_handle,
|
typedef Unique_hash_map<Halfedge_handle,
|
||||||
unsigned int> Edges_hash;
|
unsigned int> Edges_hash;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$ $Date$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
|
|
@ -91,6 +91,8 @@ private:
|
||||||
typedef typename Arrangement_2::Halfedge_around_vertex_const_circulator
|
typedef typename Arrangement_2::Halfedge_around_vertex_const_circulator
|
||||||
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;
|
typedef Arr_walk_along_line_point_location<Arrangement_2> Walk_pl;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -587,21 +589,23 @@ inline void join(InputIterator begin,
|
||||||
Polygon_2& pgn,
|
Polygon_2& pgn,
|
||||||
unsigned int k=5)
|
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;
|
unsigned int i = 1;
|
||||||
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
||||||
{
|
{
|
||||||
arr_vec[i] = new Arrangement_2(m_traits);
|
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||||
_insert(*itr, *arr_vec[i]);
|
_insert(*itr, *(arr_vec[i].first));
|
||||||
}
|
}
|
||||||
|
|
||||||
Join_merge<Arrangement_2> join_merge;
|
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
|
//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,
|
Polygon_with_holes_2& pgn,
|
||||||
unsigned int k=5)
|
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;
|
unsigned int i = 1;
|
||||||
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
||||||
{
|
{
|
||||||
arr_vec[i] = new Arrangement_2(m_traits);
|
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||||
_insert(*itr, *arr_vec[i]);
|
_insert(*itr, *(arr_vec[i].first));
|
||||||
}
|
}
|
||||||
|
|
||||||
Join_merge<Arrangement_2> join_merge;
|
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
|
//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>
|
template <class InputIterator1, class InputIterator2>
|
||||||
|
|
@ -636,29 +642,31 @@ inline void join(InputIterator1 begin1,
|
||||||
InputIterator2 end2,
|
InputIterator2 end2,
|
||||||
unsigned int k=5)
|
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);
|
std::distance(begin2, end2)+1);
|
||||||
|
|
||||||
arr_vec[0] = this->m_arr;
|
arr_vec[0].first = this->m_arr;
|
||||||
unsigned int i = 1;
|
unsigned int i = 1;
|
||||||
|
|
||||||
for(InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i)
|
for(InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i)
|
||||||
{
|
{
|
||||||
arr_vec[i] = new Arrangement_2(m_traits);
|
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||||
_insert(*itr1, *arr_vec[i]);
|
_insert(*itr1, *(arr_vec[i].first));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i)
|
for(InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i)
|
||||||
{
|
{
|
||||||
arr_vec[i] = new Arrangement_2(m_traits);
|
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||||
_insert(*itr2, *arr_vec[i]);
|
_insert(*itr2, *(arr_vec[i].first));
|
||||||
}
|
}
|
||||||
|
|
||||||
Join_merge<Arrangement_2> join_merge;
|
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
|
//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->remove_redundant_edges();
|
||||||
this->_reset_faces();
|
this->_reset_faces();
|
||||||
}
|
}
|
||||||
|
|
@ -682,22 +690,24 @@ inline void intersection(InputIterator begin,
|
||||||
Polygon_2& pgn,
|
Polygon_2& pgn,
|
||||||
unsigned int k)
|
unsigned int k)
|
||||||
{
|
{
|
||||||
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;
|
unsigned int i = 1;
|
||||||
|
|
||||||
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
||||||
{
|
{
|
||||||
CGAL_precondition(m_traits->is_valid_2_object()(*itr));
|
CGAL_precondition(m_traits->is_valid_2_object()(*itr));
|
||||||
arr_vec[i] = new Arrangement_2(m_traits);
|
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||||
_insert(*itr, *arr_vec[i]);
|
_insert(*itr, *(arr_vec[i].first));
|
||||||
}
|
}
|
||||||
|
|
||||||
Intersection_merge<Arrangement_2> intersection_merge;
|
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
|
//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
|
//intersect range of polygons with holes
|
||||||
|
|
@ -707,22 +717,24 @@ inline void intersection(InputIterator begin,
|
||||||
Polygon_with_holes_2& pgn,
|
Polygon_with_holes_2& pgn,
|
||||||
unsigned int k)
|
unsigned int k)
|
||||||
{
|
{
|
||||||
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;
|
unsigned int i = 1;
|
||||||
|
|
||||||
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
||||||
{
|
{
|
||||||
CGAL_precondition(m_traits->is_valid_2_object()(*itr));
|
CGAL_precondition(m_traits->is_valid_2_object()(*itr));
|
||||||
arr_vec[i] = new Arrangement_2(m_traits);
|
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||||
_insert(*itr, *arr_vec[i]);
|
_insert(*itr, *(arr_vec[i].first));
|
||||||
}
|
}
|
||||||
|
|
||||||
Intersection_merge<Arrangement_2> intersection_merge;
|
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
|
//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,
|
InputIterator2 end2,
|
||||||
unsigned int k=5)
|
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);
|
std::distance(begin2, end2)+1);
|
||||||
arr_vec[0] = this->m_arr;
|
arr_vec[0].first = this->m_arr;
|
||||||
unsigned int i = 1;
|
unsigned int i = 1;
|
||||||
|
|
||||||
for(InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i)
|
for(InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i)
|
||||||
{
|
{
|
||||||
CGAL_precondition(m_traits->is_valid_2_object()(*itr1));
|
CGAL_precondition(m_traits->is_valid_2_object()(*itr1));
|
||||||
arr_vec[i] = new Arrangement_2(m_traits);
|
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||||
_insert(*itr1, *arr_vec[i]);
|
_insert(*itr1, *(arr_vec[i].first));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i)
|
for(InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i)
|
||||||
{
|
{
|
||||||
CGAL_precondition(m_traits->is_valid_2_object()(*itr2));
|
CGAL_precondition(m_traits->is_valid_2_object()(*itr2));
|
||||||
arr_vec[i] = new Arrangement_2(m_traits);
|
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||||
_insert(*itr2, *arr_vec[i]);
|
_insert(*itr2, *(arr_vec[i].first));
|
||||||
}
|
}
|
||||||
|
|
||||||
Intersection_merge<Arrangement_2> intersection_merge;
|
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
|
//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->remove_redundant_edges();
|
||||||
this->_reset_faces();
|
this->_reset_faces();
|
||||||
}
|
}
|
||||||
|
|
@ -782,22 +796,24 @@ inline void symmetric_difference(InputIterator begin,
|
||||||
Polygon_2& pgn,
|
Polygon_2& pgn,
|
||||||
unsigned int k=5)
|
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;
|
unsigned int i = 1;
|
||||||
|
|
||||||
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
||||||
{
|
{
|
||||||
CGAL_precondition(m_traits->is_valid_2_object()(*itr));
|
CGAL_precondition(m_traits->is_valid_2_object()(*itr));
|
||||||
arr_vec[i] = new Arrangement_2(m_traits);
|
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||||
_insert(*itr, *arr_vec[i]);
|
_insert(*itr, *(arr_vec[i].first));
|
||||||
}
|
}
|
||||||
|
|
||||||
Xor_merge<Arrangement_2> xor_merge;
|
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
|
//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
|
//intersect range of polygons with holes
|
||||||
|
|
@ -807,22 +823,24 @@ inline void symmetric_difference(InputIterator begin,
|
||||||
Polygon_with_holes_2& pgn,
|
Polygon_with_holes_2& pgn,
|
||||||
unsigned int k=5)
|
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;
|
unsigned int i = 1;
|
||||||
|
|
||||||
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
for(InputIterator itr = begin; itr!=end; ++itr, ++i)
|
||||||
{
|
{
|
||||||
CGAL_precondition(m_traits->is_valid_2_object()(*itr));
|
CGAL_precondition(m_traits->is_valid_2_object()(*itr));
|
||||||
arr_vec[i] = new Arrangement_2(m_traits);
|
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||||
_insert(*itr, *arr_vec[i]);
|
_insert(*itr, *(arr_vec[i].first));
|
||||||
}
|
}
|
||||||
|
|
||||||
Xor_merge<Arrangement_2> xor_merge;
|
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
|
//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,
|
InputIterator2 end2,
|
||||||
unsigned int k=5)
|
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);
|
std::distance(begin2, end2)+1);
|
||||||
arr_vec[0] = this->m_arr;
|
arr_vec[0].first = this->m_arr;
|
||||||
unsigned int i = 1;
|
unsigned int i = 1;
|
||||||
|
|
||||||
for(InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i)
|
for(InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i)
|
||||||
{
|
{
|
||||||
CGAL_precondition(m_traits->is_valid_2_object()(*itr1));
|
CGAL_precondition(m_traits->is_valid_2_object()(*itr1));
|
||||||
arr_vec[i] = new Arrangement_2(m_traits);
|
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||||
_insert(*itr1, *arr_vec[i]);
|
_insert(*itr1, *(arr_vec[i].first));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i)
|
for(InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i)
|
||||||
{
|
{
|
||||||
CGAL_precondition(m_traits->is_valid_2_object()(*itr2));
|
CGAL_precondition(m_traits->is_valid_2_object()(*itr2));
|
||||||
arr_vec[i] = new Arrangement_2(m_traits);
|
arr_vec[i].first = new Arrangement_2(m_traits);
|
||||||
_insert(*itr2, *arr_vec[i]);
|
_insert(*itr2, *(arr_vec[i].first));
|
||||||
}
|
}
|
||||||
|
|
||||||
Xor_merge<Arrangement_2> xor_merge;
|
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
|
//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->remove_redundant_edges();
|
||||||
this->_reset_faces();
|
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>
|
template <class Merge>
|
||||||
void divide_and_conquer(unsigned int lower,
|
void _divide_and_conquer (unsigned int lower,
|
||||||
unsigned int upper,
|
unsigned int upper,
|
||||||
std::vector<Arrangement_2*>& arr_vec,
|
std::vector<Arr_entry>& arr_vec,
|
||||||
unsigned int k,
|
unsigned int k,
|
||||||
Merge merge_func)
|
Merge merge_func)
|
||||||
{
|
{
|
||||||
|
|
@ -916,14 +983,14 @@ void divide_and_conquer(unsigned int lower,
|
||||||
|
|
||||||
for(; i<k-1; ++i, curr_lower += sub_size )
|
for(; i<k-1; ++i, curr_lower += sub_size )
|
||||||
{
|
{
|
||||||
divide_and_conquer(curr_lower,
|
_divide_and_conquer (curr_lower,
|
||||||
curr_lower + sub_size-1,
|
curr_lower + sub_size-1,
|
||||||
arr_vec,
|
arr_vec,
|
||||||
k,
|
k,
|
||||||
merge_func);
|
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);
|
merge_func (lower, curr_lower, sub_size ,arr_vec);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue