mirror of https://github.com/CGAL/cgal
2148 lines
70 KiB
C++
2148 lines
70 KiB
C++
// 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$
|
|
//
|
|
//
|
|
// Author(s): Ron Wein <wein@post.tau.ac.il>
|
|
// Efi Fogel <efif@post.tau.ac.il>
|
|
// (based on old version by: Iddo Hanniel,
|
|
// Eyal Flato,
|
|
// Oren Nechushtan,
|
|
// Ester Ezra,
|
|
// Shai Hirsch,
|
|
// and Eugene Lipovetsky)
|
|
#ifndef CGAL_ARRANGEMENT_2_H
|
|
#define CGAL_ARRANGEMENT_2_H
|
|
|
|
/*! \file
|
|
* The header file for the Arrangement_2<Traits,Dcel> class.
|
|
*/
|
|
|
|
#include <CGAL/HalfedgeDS_iterator.h>
|
|
#include <CGAL/In_place_list.h>
|
|
#include <CGAL/Arr_default_dcel.h>
|
|
#include <CGAL/Arr_observer.h>
|
|
#include <CGAL/Arr_accessor.h>
|
|
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
|
|
#include <map>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
|
|
/*! \class
|
|
* The arrangement class, representing planar subdivisions induced by
|
|
* a set of arbitrary planar curves.
|
|
* The Traits parameter corresponds to a traits class that defines the
|
|
* Point_2 and X_monotone_curve_2 types and implements the geometric
|
|
* predicates and constructions for the family of curves it defines.
|
|
* The Dcel parameter should be a model of the ArrDcel concept and support
|
|
* the basic topological operations on a doubly-connected edge-list.
|
|
*/
|
|
template <class Traits_,
|
|
class Dcel_ = Arr_default_dcel<Traits_> >
|
|
class Arrangement_2
|
|
{
|
|
public:
|
|
|
|
typedef Traits_ Traits_2;
|
|
typedef Dcel_ Dcel;
|
|
typedef Arrangement_2<Traits_2,Dcel> Self;
|
|
|
|
typedef typename Traits_2::Point_2 Point_2;
|
|
typedef typename Traits_2::X_monotone_curve_2 X_monotone_curve_2;
|
|
|
|
typedef typename Dcel::Size Size;
|
|
|
|
protected:
|
|
|
|
friend class Arr_observer<Self>;
|
|
friend class Arr_accessor<Self>;
|
|
|
|
typedef Arr_traits_basic_adaptor_2<Traits_2> Traits_adaptor_2;
|
|
|
|
// Internal DCEL types:
|
|
typedef typename Dcel::Vertex DVertex;
|
|
typedef typename Dcel::Halfedge DHalfedge;
|
|
typedef typename Dcel::Face DFace;
|
|
typedef typename Dcel::Hole DHole;
|
|
typedef typename Dcel::Isolated_vertex DIso_vert;
|
|
|
|
typedef typename Dcel::difference_type DDifference;
|
|
|
|
typedef typename Dcel::iterator_category DIterator_category;
|
|
|
|
typedef typename Dcel::Vertex_iterator DVertex_iter;
|
|
typedef typename Dcel::Vertex_const_iterator DVertex_const_iter;
|
|
|
|
typedef typename Dcel::Halfedge_iterator DHalfedge_iter;
|
|
typedef typename Dcel::Halfedge_const_iterator DHalfedge_const_iter;
|
|
|
|
typedef typename Dcel::Edge_iterator DEdge_iter;
|
|
typedef typename Dcel::Edge_const_iterator DEdge_const_iter;
|
|
|
|
typedef typename Dcel::Face_iterator DFace_iter;
|
|
typedef typename Dcel::Face_const_iterator DFace_const_iter;
|
|
|
|
typedef typename DFace::Hole_iterator DHoles_iter;
|
|
typedef typename DFace::Hole_const_iterator DHoles_const_iter;
|
|
|
|
typedef typename DFace::Isolated_vertex_iterator
|
|
DIsolated_vertices_iter;
|
|
typedef typename DFace::Isolated_vertex_const_iterator
|
|
DIsolated_vertices_const_iter;
|
|
|
|
public:
|
|
|
|
// Forward declerations:
|
|
class Vertex;
|
|
class Halfedge;
|
|
class Face;
|
|
|
|
// Definition of the halfedge data-structure itereators and circulators:
|
|
typedef I_HalfedgeDS_iterator
|
|
<DVertex_iter, Vertex, DDifference,
|
|
DIterator_category> Vertex_iterator;
|
|
|
|
typedef I_HalfedgeDS_const_iterator
|
|
<DVertex_const_iter, DVertex_iter, Vertex,
|
|
DDifference, DIterator_category> Vertex_const_iterator;
|
|
|
|
typedef I_HalfedgeDS_iterator
|
|
<DHalfedge_iter, Halfedge, DDifference,
|
|
DIterator_category> Halfedge_iterator;
|
|
|
|
typedef I_HalfedgeDS_const_iterator
|
|
<DHalfedge_const_iter, DHalfedge_iter,
|
|
Halfedge, DDifference, DIterator_category> Halfedge_const_iterator;
|
|
|
|
/*! \class
|
|
* Edges iterator - defined as a derived class to make it assignable
|
|
* to the halfedge iterator type.
|
|
*/
|
|
class Edge_iterator :
|
|
public I_HalfedgeDS_iterator<DEdge_iter,
|
|
Halfedge, DDifference,
|
|
DIterator_category>
|
|
{
|
|
typedef I_HalfedgeDS_iterator<DEdge_iter,
|
|
Halfedge, DDifference,
|
|
DIterator_category> Base;
|
|
|
|
public:
|
|
|
|
Edge_iterator ()
|
|
{}
|
|
|
|
Edge_iterator (DEdge_iter iter) :
|
|
Base (iter)
|
|
{}
|
|
|
|
// Casting to a halfedge iterator.
|
|
operator Halfedge_iterator () const
|
|
{
|
|
return (Halfedge_iterator (DHalfedge_iter (this->current_iterator())));
|
|
}
|
|
|
|
operator Halfedge_const_iterator () const
|
|
{
|
|
return (Halfedge_const_iterator
|
|
(DHalfedge_const_iter (this->current_iterator())));
|
|
}
|
|
};
|
|
|
|
class Edge_const_iterator :
|
|
public I_HalfedgeDS_const_iterator<DEdge_const_iter, DEdge_iter,
|
|
Halfedge, DDifference,
|
|
DIterator_category>
|
|
{
|
|
typedef I_HalfedgeDS_const_iterator<DEdge_const_iter, DEdge_iter,
|
|
Halfedge, DDifference,
|
|
DIterator_category> Base;
|
|
|
|
public:
|
|
|
|
Edge_const_iterator ()
|
|
{}
|
|
|
|
Edge_const_iterator (Edge_iterator iter) :
|
|
Base (iter)
|
|
{}
|
|
|
|
Edge_const_iterator (DEdge_const_iter iter) :
|
|
Base (iter)
|
|
{}
|
|
|
|
// Casting to a halfedge iterator.
|
|
operator Halfedge_const_iterator () const
|
|
{
|
|
return (Halfedge_const_iterator
|
|
(DHalfedge_const_iter (this->current_iterator())));
|
|
}
|
|
};
|
|
|
|
typedef I_HalfedgeDS_iterator
|
|
<DFace_iter, Face, DDifference,
|
|
DIterator_category> Face_iterator;
|
|
|
|
typedef I_HalfedgeDS_const_iterator
|
|
<DFace_const_iter, DFace_iter, Face,
|
|
DDifference, DIterator_category> Face_const_iterator;
|
|
|
|
typedef _HalfedgeDS_vertex_circ
|
|
<Halfedge, Halfedge_iterator,
|
|
Bidirectional_circulator_tag> Halfedge_around_vertex_circulator;
|
|
|
|
typedef _HalfedgeDS_vertex_const_circ
|
|
<Halfedge,
|
|
Halfedge_const_iterator,
|
|
Bidirectional_circulator_tag> Halfedge_around_vertex_const_circulator;
|
|
|
|
typedef _HalfedgeDS_facet_circ
|
|
<Halfedge,
|
|
Halfedge_iterator,
|
|
Bidirectional_circulator_tag> Ccb_halfedge_circulator;
|
|
|
|
typedef _HalfedgeDS_facet_const_circ
|
|
<Halfedge,
|
|
Halfedge_const_iterator,
|
|
Bidirectional_circulator_tag> Ccb_halfedge_const_circulator;
|
|
|
|
typedef I_HalfedgeDS_iterator
|
|
<DHoles_iter, Ccb_halfedge_circulator,
|
|
DDifference,
|
|
DIterator_category> Hole_iterator;
|
|
|
|
typedef I_HalfedgeDS_const_iterator
|
|
<DHoles_const_iter, DHoles_iter,
|
|
Ccb_halfedge_const_circulator,
|
|
DDifference,
|
|
DIterator_category> Hole_const_iterator;
|
|
|
|
/*! \class
|
|
* Isolated vertices iterator - defined as a class to make it assignable
|
|
* to the vertex iterator type.
|
|
*/
|
|
class Isolated_vertex_iterator :
|
|
public I_HalfedgeDS_iterator<DIsolated_vertices_iter,
|
|
Vertex, DDifference,
|
|
DIterator_category>
|
|
{
|
|
typedef I_HalfedgeDS_iterator<DIsolated_vertices_iter,
|
|
Vertex, DDifference,
|
|
DIterator_category> Base;
|
|
|
|
public:
|
|
|
|
Isolated_vertex_iterator ()
|
|
{}
|
|
|
|
Isolated_vertex_iterator (DIsolated_vertices_iter iter) :
|
|
Base (iter)
|
|
{}
|
|
|
|
// Casting to a vertex iterator.
|
|
operator Vertex_iterator () const
|
|
{
|
|
return (Vertex_iterator (DVertex_iter (this->ptr())));
|
|
}
|
|
|
|
operator Vertex_const_iterator () const
|
|
{
|
|
return (Vertex_const_iterator (DVertex_const_iter (this->ptr())));
|
|
}
|
|
};
|
|
|
|
class Isolated_vertex_const_iterator :
|
|
public I_HalfedgeDS_const_iterator <DIsolated_vertices_const_iter,
|
|
DIsolated_vertices_iter,
|
|
Vertex, DDifference,
|
|
DIterator_category>
|
|
{
|
|
typedef I_HalfedgeDS_const_iterator <DIsolated_vertices_const_iter,
|
|
DIsolated_vertices_iter,
|
|
Vertex, DDifference,
|
|
DIterator_category> Base;
|
|
|
|
public:
|
|
|
|
Isolated_vertex_const_iterator ()
|
|
{}
|
|
|
|
Isolated_vertex_const_iterator (Isolated_vertex_iterator iter) :
|
|
Base (iter)
|
|
{}
|
|
|
|
Isolated_vertex_const_iterator (DIsolated_vertices_const_iter iter) :
|
|
Base (iter)
|
|
{}
|
|
|
|
// Casting to a vertex iterator.
|
|
operator Vertex_const_iterator () const
|
|
{
|
|
return (Vertex_const_iterator (DVertex_const_iter (this->ptr())));
|
|
}
|
|
};
|
|
|
|
// Definition of handles (equivalent to iterators):
|
|
typedef Vertex_iterator Vertex_handle;
|
|
typedef Halfedge_iterator Halfedge_handle;
|
|
typedef Face_iterator Face_handle;
|
|
|
|
typedef Vertex_const_iterator Vertex_const_handle;
|
|
typedef Halfedge_const_iterator Halfedge_const_handle;
|
|
typedef Face_const_iterator Face_const_handle;
|
|
|
|
/*!
|
|
* \class The arrangement vertex class.
|
|
*/
|
|
class Vertex : public DVertex
|
|
{
|
|
typedef DVertex Base;
|
|
|
|
public:
|
|
|
|
/*! Default constrcutor. */
|
|
Vertex()
|
|
{}
|
|
|
|
/*! Get the vertex degree (number of incident edges). */
|
|
Size degree () const
|
|
{
|
|
if (this->is_isolated())
|
|
return (0);
|
|
|
|
// Go around the vertex and count the incident halfedges.
|
|
const DHalfedge *he_first = Base::halfedge();
|
|
const DHalfedge *he_curr = he_first;
|
|
Size n = 0;
|
|
|
|
if (he_curr != NULL)
|
|
{
|
|
do
|
|
{
|
|
n++;
|
|
he_curr = he_curr->next()->opposite();
|
|
} while (he_curr != he_first);
|
|
}
|
|
return (n);
|
|
}
|
|
|
|
/*!
|
|
* Get the incident halfedges (non-const version).
|
|
* \pre The vertex is not isolated.
|
|
*/
|
|
Halfedge_around_vertex_circulator incident_halfedges()
|
|
{
|
|
CGAL_precondition (! this->is_isolated());
|
|
|
|
return Halfedge_around_vertex_circulator
|
|
(DHalfedge_iter (Base::halfedge()));
|
|
}
|
|
|
|
/*!
|
|
* Get the incident halfedges (const version).
|
|
* \pre The vertex is not isolated.
|
|
*/
|
|
Halfedge_around_vertex_const_circulator incident_halfedges() const
|
|
{
|
|
CGAL_precondition (! this->is_isolated());
|
|
|
|
return Halfedge_around_vertex_const_circulator
|
|
(DHalfedge_const_iter (Base::halfedge()));
|
|
}
|
|
|
|
/*!
|
|
* Get the face that contains the vertex (non-const version).
|
|
* \pre The vertex is isolated.
|
|
*/
|
|
Face_handle face()
|
|
{
|
|
CGAL_precondition (this->is_isolated());
|
|
|
|
return (DFace_iter (Base::isolated_vertex()->face()));
|
|
}
|
|
|
|
/*!
|
|
* Get the face that contains the vertex (const version).
|
|
* \pre The vertex is isolated.
|
|
*/
|
|
Face_const_handle face() const
|
|
{
|
|
CGAL_precondition (this->is_isolated());
|
|
|
|
return (DFace_const_iter (Base::isolated_vertex()->face()));
|
|
}
|
|
|
|
private:
|
|
|
|
// Blocking access to inherited functions from the Dcel::Vertex.
|
|
void set_point (Point_2* );
|
|
const DHalfedge* halfedge () const;
|
|
DHalfedge* halfedge ();
|
|
void set_halfedge (DHalfedge* );
|
|
const DIso_vert* isolated_vertex () const;
|
|
DIso_vert* isolated_vertex ();
|
|
void set_isolated_vertex (DIso_vert* );
|
|
};
|
|
|
|
/*!
|
|
* \class The arrangement halfedge class.
|
|
*/
|
|
class Halfedge : public DHalfedge
|
|
{
|
|
typedef DHalfedge Base;
|
|
|
|
public:
|
|
|
|
/*! Default constrcutor. */
|
|
Halfedge ()
|
|
{}
|
|
|
|
/*! Get the source vertex (non-const version). */
|
|
Vertex_handle source ()
|
|
{
|
|
return (DVertex_iter (Base::opposite()->vertex()));
|
|
}
|
|
|
|
/*! Get the source vertex (const version). */
|
|
Vertex_const_handle source () const
|
|
{
|
|
return (DVertex_const_iter (Base::opposite()->vertex()));
|
|
}
|
|
|
|
/*! Get the target vertex (non-const version). */
|
|
Vertex_handle target ()
|
|
{
|
|
return (DVertex_iter (Base::vertex()));
|
|
}
|
|
|
|
/*! Get the target vertex (const version). */
|
|
Vertex_const_handle target () const
|
|
{
|
|
return (DVertex_const_iter (Base::vertex()));
|
|
}
|
|
|
|
/*! Get the incident face (non-const version). */
|
|
Face_handle face()
|
|
{
|
|
if (! Base::is_on_hole())
|
|
return (DFace_iter (Base::face()));
|
|
else
|
|
return (DFace_iter (Base::hole()->face()));
|
|
}
|
|
|
|
/*! Get the incident face (const version). */
|
|
Face_const_handle face() const
|
|
{
|
|
if (! Base::is_on_hole())
|
|
return (DFace_const_iter (Base::face()));
|
|
else
|
|
return (DFace_const_iter (Base::hole()->face()));
|
|
}
|
|
|
|
/*! Get the twin halfedge (non-const version). */
|
|
Halfedge_handle twin()
|
|
{
|
|
return (DHalfedge_iter (Base::opposite()));
|
|
}
|
|
|
|
/*! Get the twin halfedge (const version). */
|
|
Halfedge_const_handle twin() const
|
|
{
|
|
return (DHalfedge_const_iter (Base::opposite()));
|
|
}
|
|
|
|
/*! Get the previous halfegde in the chain (non-const version). */
|
|
Halfedge_handle prev ()
|
|
{
|
|
return (DHalfedge_iter (Base::prev()));
|
|
}
|
|
|
|
/*! Get the previous halfegde in the chain (const version). */
|
|
Halfedge_const_handle prev () const
|
|
{
|
|
return (DHalfedge_const_iter (Base::prev()));
|
|
}
|
|
|
|
/*! Get the next halfegde in the chain (non-const version). */
|
|
Halfedge_handle next ()
|
|
{
|
|
return (DHalfedge_iter (Base::next()));
|
|
}
|
|
|
|
/*! Get the next halfegde in the chain (const version). */
|
|
Halfedge_const_handle next () const
|
|
{
|
|
return (DHalfedge_const_iter (Base::next()));
|
|
}
|
|
|
|
|
|
/*! Get the connected component of the halfedge (non-const version). */
|
|
Ccb_halfedge_circulator ccb ()
|
|
{
|
|
return Ccb_halfedge_circulator (DHalfedge_iter (this));
|
|
}
|
|
|
|
/*! Get the connected component of the halfedge (const version). */
|
|
Ccb_halfedge_const_circulator ccb () const
|
|
{
|
|
return Ccb_halfedge_const_circulator (DHalfedge_const_iter (this));
|
|
}
|
|
|
|
private:
|
|
|
|
// Blocking access to inherited functions from the Dcel::Halfedge.
|
|
void set_curve (X_monotone_curve_2* );
|
|
const DHalfedge* opposite () const;
|
|
DHalfedge* opposite ();
|
|
void set_opposite (DHalfedge* );
|
|
void set_direction (Comparison_result );
|
|
void set_prev (DHalfedge* );
|
|
void set_next (DHalfedge* );
|
|
const DVertex* vertex () const ;
|
|
DVertex* vertex ();
|
|
void set_vertex (DVertex* );
|
|
const DHole* hole () const;
|
|
DHole* hole ();
|
|
void set_hole (DHole* );
|
|
void set_face (DFace* );
|
|
};
|
|
|
|
/*!
|
|
* \class The arrangement face class.
|
|
*/
|
|
class Face : public DFace
|
|
{
|
|
typedef DFace Base;
|
|
|
|
public:
|
|
|
|
/*! Default constrcutor. */
|
|
Face()
|
|
{}
|
|
|
|
/*! Check whether the face is unbounded. */
|
|
bool is_unbounded () const
|
|
{
|
|
// Check whether the outer-boundary edge exists or not.
|
|
return (Base::halfedge() == NULL);
|
|
}
|
|
|
|
/*! Get an iterator for the holes inside the face (non-const version). */
|
|
Hole_iterator holes_begin()
|
|
{
|
|
return (DHoles_iter (Base::holes_begin()));
|
|
}
|
|
|
|
/*! Get an iterator for the holes inside the face (const version). */
|
|
Hole_const_iterator holes_begin() const
|
|
{
|
|
return (DHoles_const_iter (Base::holes_begin()));
|
|
}
|
|
|
|
/*! Get a past-the-end iterator for the holes (non-const version). */
|
|
Hole_iterator holes_end()
|
|
{
|
|
return (DHoles_iter (Base::holes_end()));
|
|
}
|
|
|
|
/*! Get a past-the-end iterator for the holes (const version). */
|
|
Hole_const_iterator holes_end() const
|
|
{
|
|
return (DHoles_const_iter (Base::holes_end()));
|
|
}
|
|
|
|
/*! Get an iterator for the isolated_vertices inside the face
|
|
* (non-const version). */
|
|
Isolated_vertex_iterator isolated_vertices_begin ()
|
|
{
|
|
return (DIsolated_vertices_iter (Base::isolated_vertices_begin()));
|
|
}
|
|
|
|
/*! Get an iterator for the isolated_vertices inside the face
|
|
* (const version). */
|
|
Isolated_vertex_const_iterator isolated_vertices_begin () const
|
|
{
|
|
return (DIsolated_vertices_const_iter (Base::isolated_vertices_begin()));
|
|
}
|
|
|
|
/*! Get a past-the-end iterator for the isolated_vertices
|
|
* (non-const version). */
|
|
Isolated_vertex_iterator isolated_vertices_end ()
|
|
{
|
|
return (DIsolated_vertices_iter (Base::isolated_vertices_end()));
|
|
}
|
|
|
|
/*! Get a past-the-end iterator for the isolated_vertices
|
|
* (const version). */
|
|
Isolated_vertex_const_iterator isolated_vertices_end () const
|
|
{
|
|
return (DIsolated_vertices_const_iter (Base::isolated_vertices_end()));
|
|
}
|
|
|
|
/*! Get a circulator for the outer boundary (non-const version). */
|
|
Ccb_halfedge_circulator outer_ccb ()
|
|
{
|
|
CGAL_precondition(Base::halfedge() != NULL);
|
|
return Ccb_halfedge_circulator (DHalfedge_iter (Base::halfedge()));
|
|
}
|
|
|
|
/*! Get a circulator for the outer boundary (const version). */
|
|
Ccb_halfedge_const_circulator outer_ccb () const
|
|
{
|
|
CGAL_precondition(Base::halfedge() != NULL);
|
|
return Ccb_halfedge_const_circulator
|
|
(DHalfedge_const_iter (Base::halfedge()));
|
|
}
|
|
|
|
private:
|
|
|
|
// Blocking access to inherited functions from the Dcel::Face.
|
|
const DHalfedge* halfedge () const;
|
|
DHalfedge* halfedge ();
|
|
void set_halfedge (DHalfedge* );
|
|
DHoles_iter add_hole (DHalfedge* );
|
|
void erase_hole (DHoles_iter );
|
|
DIsolated_vertices_iter add_isolated_vertex (DVertex* );
|
|
void erase_isolated_vertex (DIsolated_vertices_iter );
|
|
};
|
|
|
|
protected:
|
|
|
|
typedef Point_2 Stored_point_2;
|
|
typedef X_monotone_curve_2 Stored_curve_2;
|
|
|
|
typedef CGAL_ALLOCATOR(Point_2) Points_alloc;
|
|
typedef CGAL_ALLOCATOR(X_monotone_curve_2) Curves_alloc;
|
|
|
|
typedef Arr_observer<Self> Observer;
|
|
typedef std::list<Observer*> Observers_container;
|
|
typedef typename Observers_container::iterator Observers_iterator;
|
|
|
|
typedef typename Observers_container::reverse_iterator
|
|
Observers_rev_iterator;
|
|
|
|
// Data members:
|
|
Dcel dcel; // The DCEL representing the arrangement.
|
|
DFace *un_face; // The unbounded face of the DCEL.
|
|
Points_alloc points_alloc; // Allocator for the points.
|
|
Curves_alloc curves_alloc; // Allocator for the curves.
|
|
Observers_container observers; // Storing pointers to existing observers.
|
|
Traits_adaptor_2 *traits; // The traits adaptor.
|
|
bool own_traits; // Inidicate whether we should evetually
|
|
// free the traits object.
|
|
|
|
public:
|
|
|
|
/// \name Constructors.
|
|
//@{
|
|
|
|
/*! Default constructor. */
|
|
Arrangement_2 ();
|
|
|
|
/*! Copy constructor. */
|
|
Arrangement_2 (const Self& arr);
|
|
|
|
/*! Constructor given a traits object. */
|
|
Arrangement_2 (Traits_2 *tr);
|
|
//@}
|
|
|
|
/// \name Assignment functions.
|
|
//@{
|
|
|
|
/*! Assignment operator. */
|
|
Self& operator= (const Self& arr);
|
|
|
|
/*! Assign an arrangement. */
|
|
void assign (const Self& arr);
|
|
//@}
|
|
|
|
/// \name Destruction functions.
|
|
//@{
|
|
|
|
/*! Destructor. */
|
|
virtual ~Arrangement_2 ();
|
|
|
|
/*! Clear the arrangement. */
|
|
virtual void clear();
|
|
//@}
|
|
|
|
/*! Access the traits object (non-const version). */
|
|
Traits_2* get_traits ()
|
|
{
|
|
return (traits);
|
|
}
|
|
|
|
/*! Access the traits object (const version). */
|
|
const Traits_2* get_traits () const
|
|
{
|
|
return (traits);
|
|
}
|
|
|
|
/// \name Access the arrangement dimensions.
|
|
//@{
|
|
|
|
/*! Check whether the arrangement is empty. */
|
|
bool is_empty () const
|
|
{
|
|
return (vertices_begin() == vertices_end() &&
|
|
halfedges_begin() == halfedges_end());
|
|
}
|
|
|
|
/*!
|
|
* Check whether the arrangement is valid. In particular, check the
|
|
* validity of each vertex, halfedge and face, their incidence relations
|
|
* and the geometric properties of the arrangement.
|
|
*/
|
|
bool is_valid() const;
|
|
|
|
/*! Get the number of arrangement vertices. */
|
|
Size number_of_vertices () const
|
|
{
|
|
return (dcel.size_of_vertices());
|
|
}
|
|
|
|
/*! Get the number of isolated arrangement vertices. */
|
|
Size number_of_isolated_vertices () const
|
|
{
|
|
return (dcel.size_of_isolated_vertices());
|
|
}
|
|
|
|
/*! Get the number of arrangement halfedges (the result is always even). */
|
|
Size number_of_halfedges () const
|
|
{
|
|
return (dcel.size_of_halfedges());
|
|
}
|
|
|
|
/*! Get the number of arrangement edges. */
|
|
Size number_of_edges () const
|
|
{
|
|
return (dcel.size_of_halfedges() / 2);
|
|
}
|
|
|
|
/*! Get the number of arrangement faces. */
|
|
Size number_of_faces () const
|
|
{
|
|
return (dcel.size_of_faces());
|
|
}
|
|
//@}
|
|
|
|
/// \name Traversal functions for the arrangement vertices.
|
|
//@{
|
|
|
|
/*! Get an iterator for the first vertex in the arrangement. */
|
|
Vertex_iterator vertices_begin()
|
|
{
|
|
return (Vertex_iterator (dcel.vertices_begin()));
|
|
}
|
|
|
|
/*! Get a past-the-end iterator for the arrangement vertices. */
|
|
Vertex_iterator vertices_end()
|
|
{
|
|
return (Vertex_iterator(dcel.vertices_end()));
|
|
}
|
|
|
|
/*! Get a const iterator for the first vertex in the arrangement. */
|
|
Vertex_const_iterator vertices_begin() const
|
|
{
|
|
return (Vertex_const_iterator (dcel.vertices_begin()));
|
|
}
|
|
|
|
/*! Get a past-the-end const iterator for the arrangement vertices. */
|
|
Vertex_const_iterator vertices_end() const
|
|
{
|
|
return (Vertex_const_iterator (dcel.vertices_end()));
|
|
}
|
|
//@}
|
|
|
|
/// \name Traversal functions for the arrangement halfedges.
|
|
//@{
|
|
|
|
/*! Get an iterator for the first halfedge in the arrangement. */
|
|
Halfedge_iterator halfedges_begin()
|
|
{
|
|
return (Halfedge_iterator (dcel.halfedges_begin()));
|
|
}
|
|
|
|
/*! Get a past-the-end iterator for the arrangement halfedges. */
|
|
Halfedge_iterator halfedges_end()
|
|
{
|
|
return (Halfedge_iterator(dcel.halfedges_end()));
|
|
}
|
|
|
|
/*! Get a const iterator for the first halfedge in the arrangement. */
|
|
Halfedge_const_iterator halfedges_begin() const
|
|
{
|
|
return (Halfedge_const_iterator (dcel.halfedges_begin()));
|
|
}
|
|
|
|
/*! Get a past-the-end const iterator for the arrangement halfedges. */
|
|
Halfedge_const_iterator halfedges_end() const
|
|
{
|
|
return (Halfedge_const_iterator (dcel.halfedges_end()));
|
|
}
|
|
//@}
|
|
|
|
/// \name Traversal functions for the arrangement edges.
|
|
//@{
|
|
|
|
/*! Get an iterator for the first edge in the arrangement. */
|
|
Edge_iterator edges_begin()
|
|
{
|
|
return (Edge_iterator (dcel.edges_begin()));
|
|
}
|
|
|
|
/*! Get a past-the-end iterator for the arrangement edges. */
|
|
Edge_iterator edges_end()
|
|
{
|
|
return (Edge_iterator(dcel.edges_end()));
|
|
}
|
|
|
|
/*! Get a const iterator for the first edge in the arrangement. */
|
|
Edge_const_iterator edges_begin() const
|
|
{
|
|
return (Edge_const_iterator (dcel.edges_begin()));
|
|
}
|
|
|
|
/*! Get a past-the-end const iterator for the arrangement edges. */
|
|
Edge_const_iterator edges_end() const
|
|
|
|
{
|
|
return (Edge_const_iterator (dcel.edges_end()));
|
|
}
|
|
//@}
|
|
|
|
/// \name Traversal functions for the arrangement faces.
|
|
//@{
|
|
|
|
/*! Get the unbounded face (non-const version). */
|
|
Face_handle unbounded_face ()
|
|
{
|
|
return (Face_handle (un_face));
|
|
}
|
|
|
|
/*! Get the unbounded face (const version). */
|
|
Face_const_handle unbounded_face () const
|
|
{
|
|
|
|
return (Face_const_handle (un_face));
|
|
}
|
|
|
|
/*! Get an iterator for the first face in the arrangement. */
|
|
Face_iterator faces_begin()
|
|
{
|
|
return (Face_iterator (dcel.faces_begin()));
|
|
}
|
|
|
|
/*! Get a past-the-end iterator for the arrangement faces. */
|
|
Face_iterator faces_end()
|
|
{
|
|
return (Face_iterator(dcel.faces_end()));
|
|
}
|
|
|
|
/*! Get a const iterator for the first face in the arrangement. */
|
|
Face_const_iterator faces_begin() const
|
|
{
|
|
return (Face_const_iterator (dcel.faces_begin()));
|
|
}
|
|
|
|
/*! Get a past-the-end const iterator for the arrangement faces. */
|
|
Face_const_iterator faces_end() const
|
|
{
|
|
return (Face_const_iterator (dcel.faces_end()));
|
|
}
|
|
//@}
|
|
|
|
/// \name Casting away constness for handle types.
|
|
//@{
|
|
Vertex_handle non_const_handle (Vertex_const_handle vh)
|
|
{
|
|
DVertex *p_v = (DVertex*) &(*vh);
|
|
return (Vertex_handle (p_v));
|
|
}
|
|
|
|
Halfedge_handle non_const_handle (Halfedge_const_handle hh)
|
|
{
|
|
DHalfedge *p_he = (DHalfedge*) &(*hh);
|
|
return (Halfedge_handle (p_he));
|
|
}
|
|
|
|
Face_handle non_const_handle (Face_const_handle fh)
|
|
{
|
|
DFace *p_f = (DFace*) &(*fh);
|
|
return (Face_handle (p_f));
|
|
}
|
|
//@}
|
|
|
|
/// \name Specilaized insertion functions.
|
|
//@{
|
|
|
|
/*!
|
|
* Insert a point that forms an isolated vertex in the interior of a given
|
|
* face.
|
|
* \param p The given point.
|
|
* \param f The face into which we insert the new isolated vertex.
|
|
* \return A handle for the isolated vertex that has been created.
|
|
*/
|
|
Vertex_handle insert_in_face_interior (const Point_2& p,
|
|
Face_handle f);
|
|
|
|
/*!
|
|
* Insert an x-monotone curve into the arrangement as a new hole (inner
|
|
* component) inside the given face.
|
|
* \param cv The given x-monotone curve.
|
|
* \param f The face into which we insert the new hole.
|
|
* \return A handle for one of the halfedges corresponding to the inserted
|
|
* curve, directed (lexicographically) from left to right.
|
|
*/
|
|
Halfedge_handle insert_in_face_interior (const X_monotone_curve_2& cv,
|
|
Face_handle f);
|
|
|
|
/*!
|
|
* Insert an x-monotone curve into the arrangement, such that its left
|
|
* endpoint corresponds to a given arrangement vertex.
|
|
* \param cv The given x-monotone curve.
|
|
* \param v The given vertex.
|
|
* \pre The left endpoint of cv is incident to the vertex v.
|
|
* \return A handle for one of the halfedges corresponding to the inserted
|
|
* curve, whose target is the new vertex.
|
|
*/
|
|
Halfedge_handle insert_from_left_vertex (const X_monotone_curve_2& cv,
|
|
Vertex_handle v);
|
|
|
|
/*!
|
|
* Insert an x-monotone curve into the arrangement, such that its left
|
|
* endpoints corresponds to a given arrangement vertex, given the exact
|
|
* place for the curve in the circular list around this vertex.
|
|
* \param cv The given x-monotone curve.
|
|
* \param prev The reference halfedge. We should represent cv as a pair
|
|
* of edges, one of them should become prev's successor.
|
|
* \pre The target vertex of prev is cv's left endpoint.
|
|
* \return A handle for one of the halfedges corresponding to the inserted
|
|
* curve, whose target is the new vertex that was created.
|
|
*/
|
|
Halfedge_handle insert_from_left_vertex (const X_monotone_curve_2& cv,
|
|
Halfedge_handle prev);
|
|
|
|
/*!
|
|
* Insert an x-monotone curve into the arrangement, such that its right
|
|
* endpoint corresponds to a given arrangement vertex.
|
|
* \param cv The given x-monotone curve.
|
|
* \param v The given vertex.
|
|
* \pre The right endpoint of cv is incident to the vertex v.
|
|
* \return A handle for one of the halfedges corresponding to the inserted
|
|
* curve, whose target is the new vertex.
|
|
*/
|
|
Halfedge_handle insert_from_right_vertex (const X_monotone_curve_2& cv,
|
|
Vertex_handle v);
|
|
|
|
/*!
|
|
* Insert an x-monotone curve into the arrangement, such that its right
|
|
* endpoints corresponds to a given arrangement vertex, given the exact
|
|
* place for the curve in the circular list around this vertex.
|
|
|
|
* \param cv The given x-monotone curve.
|
|
* \param prev The reference halfedge. We should represent cv as a pair
|
|
* of edges, one of them should become prev's successor.
|
|
* \pre The target vertex of prev is cv's right endpoint.
|
|
* \return A handle for one of the halfedges corresponding to the inserted
|
|
* curve, whose target is the new vertex that was created.
|
|
*/
|
|
Halfedge_handle insert_from_right_vertex (const X_monotone_curve_2& cv,
|
|
Halfedge_handle prev);
|
|
|
|
/*!
|
|
* Insert an x-monotone curve into the arrangement, such that both its
|
|
* endpoints correspond to given arrangement vertices.
|
|
* \param cv The given x-monotone curve.
|
|
* \param v1 The first vertex.
|
|
* \param v2 The second vertex.
|
|
* \pre v1 and v2 corresponds to cv's endpoints.
|
|
* \return A handle for one of the halfedges corresponding to the inserted
|
|
* curve directed from v1 to v2.
|
|
*/
|
|
Halfedge_handle insert_at_vertices (const X_monotone_curve_2& cv,
|
|
Vertex_handle v1,
|
|
Vertex_handle v2);
|
|
|
|
/*!
|
|
* Insert an x-monotone curve into the arrangement, such that both its
|
|
* endpoints correspond to given arrangement vertices, given the exact
|
|
* place for the curve in one of the circular lists around a vertex.
|
|
* \param cv The given x-monotone curve.
|
|
* \param prev1 The reference halfedge for the first vertex.
|
|
* \param v2 The second vertex.
|
|
* \pre The target vertex of prev1 and v2 corresponds to cv's endpoints.
|
|
* \return A handle for one of the halfedges corresponding to the inserted
|
|
* curve directed from prev1 to v2.
|
|
*/
|
|
Halfedge_handle insert_at_vertices (const X_monotone_curve_2& cv,
|
|
Halfedge_handle h1,
|
|
Vertex_handle v2);
|
|
|
|
/*!
|
|
* Insert an x-monotone curve into the arrangement, such that both its
|
|
* endpoints correspond to given arrangement vertices, given the exact
|
|
* place for the curve in both circular lists around these two vertices.
|
|
* \param cv the given curve.
|
|
* \param prev1 The reference halfedge for the first vertex.
|
|
* \param prev2 The reference halfedge for the second vertex.
|
|
* \pre The target vertices of prev1 and prev2 are cv's endpoints.
|
|
* \return A handle for one of the halfedges corresponding to the inserted
|
|
* curve directed from prev1's target to prev2's target.
|
|
*/
|
|
Halfedge_handle insert_at_vertices (const X_monotone_curve_2 & cv,
|
|
Halfedge_handle prev1,
|
|
Halfedge_handle prev2);
|
|
|
|
//@}
|
|
|
|
/// \name Vertex manipulation functions.
|
|
//@{
|
|
|
|
/*!
|
|
* Replace the point associated with the given vertex.
|
|
* \param v The vertex to modify.
|
|
* \param p The point that should be associated with the edge.
|
|
* \pre p is geometrically equivalent to the current point
|
|
* associated with v.
|
|
* \return A handle for a the modified vertex (same as v).
|
|
*/
|
|
Vertex_handle modify_vertex (Vertex_handle v,
|
|
const Point_2& p);
|
|
|
|
/*!
|
|
* Remove an isolated vertex from the interior of a given face.
|
|
* \param v The vertex to remove.
|
|
* \pre v is an isolated vertex (it has no incident halfedges).
|
|
* \return A handle for the face containing v.
|
|
*/
|
|
Face_handle remove_isolated_vertex (Vertex_handle v);
|
|
|
|
///@}
|
|
|
|
/// \name Halfedge manipulation functions.
|
|
//@{
|
|
|
|
/*!
|
|
* Replace the x-monotone curve associated with the given edge.
|
|
* \param e The edge to modify.
|
|
* \param cv The curve that should be associated with the edge.
|
|
* \pre cv is geometrically equivalent to the current curve
|
|
* associated with e.
|
|
* \return A handle for a the modified halfedge (same as e).
|
|
*/
|
|
Halfedge_handle modify_edge (Halfedge_handle e,
|
|
const X_monotone_curve_2& cv);
|
|
|
|
/*!
|
|
* Split a given edge into two, and associate the given x-monotone
|
|
* curves with the split edges.
|
|
* \param e The edge to split (one of the pair of twin halfegdes).
|
|
* \param cv1 The curve that should be associated with the first split edge.
|
|
* \param cv2 The curve that should be associated with the second split edge.
|
|
|
|
* \pre cv1's source and cv2's target equal the endpoints of the curve
|
|
* currently assoicated with e (respectively), and cv1's target equals
|
|
* cv2's target, and this is the split point (ot vice versa).
|
|
* \return A handle for the halfedge whose source is the source of the the
|
|
* original halfedge e, and whose target is the split point.
|
|
*/
|
|
Halfedge_handle split_edge (Halfedge_handle e,
|
|
const X_monotone_curve_2& cv1,
|
|
const X_monotone_curve_2& cv2);
|
|
|
|
/*!
|
|
* Merge two edges to form a single edge, and associate the given x-monotone
|
|
* curve with the merged edge.
|
|
* \param e1 The first edge to merge (one of the pair of twin halfegdes).
|
|
* \param e2 The second edge to merge (one of the pair of twin halfegdes).
|
|
* \param cv The curve that should be associated with merged edge.
|
|
* \return A handle for the merged halfedge.
|
|
*/
|
|
Halfedge_handle merge_edge (Halfedge_handle e1,
|
|
Halfedge_handle e2,
|
|
const X_monotone_curve_2& cv);
|
|
|
|
/*!
|
|
* Remove an edge from the arrangement.
|
|
* \param e The edge to remove (one of the pair of twin halfegdes).
|
|
* \param remove_source Should the source vertex of e be removed if it
|
|
* becomes isolated (true by default).
|
|
* \param remove_target Should the target vertex of e be removed if it
|
|
* becomes isolated (true by default).
|
|
|
|
* \return A handle for the remaining face.
|
|
*/
|
|
Face_handle remove_edge (Halfedge_handle e,
|
|
bool remove_source = true,
|
|
bool remove_target = true);
|
|
|
|
//@}
|
|
|
|
protected:
|
|
|
|
/// \name Allocating and de-allocating points and curves.
|
|
//@{
|
|
|
|
/*! Allocate a new point. */
|
|
Point_2 *_new_point (const Point_2& pt)
|
|
{
|
|
Point_2 *p_pt = points_alloc.allocate (1);
|
|
|
|
points_alloc.construct (p_pt, pt);
|
|
return (p_pt);
|
|
}
|
|
|
|
/*! De-allocate a point. */
|
|
void _delete_point (Point_2& pt)
|
|
{
|
|
Point_2 *p_pt = &pt;
|
|
|
|
points_alloc.destroy (p_pt);
|
|
points_alloc.deallocate (p_pt, 1);
|
|
}
|
|
|
|
/*! Allocate a new curve. */
|
|
X_monotone_curve_2 *_new_curve (const X_monotone_curve_2& cv)
|
|
{
|
|
X_monotone_curve_2 *p_cv = curves_alloc.allocate (1);
|
|
|
|
curves_alloc.construct (p_cv, cv);
|
|
return (p_cv);
|
|
}
|
|
|
|
/*! De-allocate a curve. */
|
|
void _delete_curve (X_monotone_curve_2& cv)
|
|
{
|
|
X_monotone_curve_2 *p_cv = &cv;
|
|
|
|
curves_alloc.destroy (p_cv);
|
|
curves_alloc.deallocate (p_cv, 1);
|
|
}
|
|
//@}
|
|
|
|
/// \name Converting handles to pointers (for the arrangement accessor).
|
|
//@{
|
|
|
|
/*! Convert a vertex handle to a pointer to a DCEL vertex. */
|
|
/*! Convert a vertex handle to a pointer to a DCEL vertex. */
|
|
inline DVertex* _vertex (Vertex_handle vh) const
|
|
{
|
|
return (&(*vh));
|
|
}
|
|
|
|
/*! Convert a constant vertex handle to a pointer to a DCEL vertex. */
|
|
inline const DVertex* _vertex (Vertex_const_handle vh) const
|
|
{
|
|
return (&(*vh));
|
|
}
|
|
|
|
/*! Convert a halfedge handle to a pointer to a DCEL halfedge. */
|
|
inline DHalfedge* _halfedge (Halfedge_handle hh) const
|
|
{
|
|
return (&(*hh));
|
|
}
|
|
|
|
/*! Convert a constant halfedge handle to a pointer to a DCEL halfedge. */
|
|
inline const DHalfedge* _halfedge (Halfedge_const_handle hh) const
|
|
{
|
|
return (&(*hh));
|
|
}
|
|
|
|
/*! Convert a face handle to a pointer to a DCEL face. */
|
|
inline DFace* _face (Face_handle fh) const
|
|
{
|
|
return (&(*fh));
|
|
}
|
|
|
|
/*! Convert a constant face handle to a pointer to a DCEL face. */
|
|
inline const DFace* _face (Face_const_handle fh) const
|
|
{
|
|
return (&(*fh));
|
|
}
|
|
//@}
|
|
|
|
/// \name Converting pointers to handles (for the arrangement accessor).
|
|
//@{
|
|
|
|
/*! Convert a pointer to a DCEL vertex to a vertex handle. */
|
|
Vertex_handle _handle_for (DVertex *v)
|
|
{
|
|
return (Vertex_handle (v));
|
|
}
|
|
|
|
/*! Convert a pointer to a DCEL vertex to a constant vertex handle. */
|
|
Vertex_const_handle _const_handle_for (const DVertex *v) const
|
|
{
|
|
return (Vertex_const_handle (v));
|
|
}
|
|
|
|
/*! Convert a pointer to a DCEL halfedge to a halfedge handle. */
|
|
Halfedge_handle _handle_for (DHalfedge *he)
|
|
{
|
|
return (Halfedge_handle (he));
|
|
}
|
|
|
|
|
|
/*! Convert a pointer to a DCEL halfedge to a constant halfedge handle. */
|
|
Halfedge_const_handle _const_handle_for (const DHalfedge *he) const
|
|
{
|
|
return (Halfedge_const_handle (he));
|
|
}
|
|
|
|
/*! Convert a pointer to a DCEL face to a face handle. */
|
|
Face_handle _handle_for (DFace *f)
|
|
{
|
|
return (Face_handle (f));
|
|
}
|
|
|
|
/*! Convert a pointer to a DCEL face to a constant face handle. */
|
|
Face_const_handle _const_handle_for (const DFace *f) const
|
|
{
|
|
return (Face_const_handle (f));
|
|
}
|
|
//@}
|
|
|
|
/// \name Auxiliary (protected) functions.
|
|
//@{
|
|
|
|
/*!
|
|
* Locate the place for the given curve around the given vertex.
|
|
* \param v The given arrangement vertex.
|
|
* \param cv The given x-monotone curve.
|
|
* \pre v is one of cv's endpoints.
|
|
* \return A pointer to a halfedge whose target is v, where cv should be
|
|
* inserted between this halfedge and the next halfedge around this
|
|
* vertex (in a clockwise order).
|
|
* A NULL return value indicates a precondition violation.
|
|
*/
|
|
DHalfedge* _locate_around_vertex (DVertex *v,
|
|
const X_monotone_curve_2& cv) const;
|
|
|
|
/*!
|
|
* Compute the distance (in halfedges) between two halfedges.
|
|
* \param e1 The source halfedge.
|
|
* \param e2 The destination halfedge.
|
|
* \pre e1 and e2 belong to the same connected component
|
|
* \return The number of halfedges along the component boundary between the
|
|
* two halfedges.
|
|
*/
|
|
unsigned int _halfedge_distance (const DHalfedge *e1,
|
|
const DHalfedge *e2) const;
|
|
|
|
/*!
|
|
* Determine whether a given query halfedge lies in the interior of a new
|
|
* face we are about to create, by connecting it with another halfedge
|
|
* using a given x-monotone curve.
|
|
* \param prev1 The query halfedge.
|
|
* \param prev2 The other halfedge we are about to connect with prev1.
|
|
* \param cv The x-monotone curve we use to connect prev1 and prev2.
|
|
* \pre prev1 and prev2 belong to the same connected component, and by
|
|
* connecting them using cv we form a new face.
|
|
* \return (true) if prev1 lies in the interior of the face we are about
|
|
* to create, (false) otherwise - in which case prev2 must lie
|
|
* inside this new face.
|
|
*/
|
|
bool _is_inside_new_face (const DHalfedge *prev1,
|
|
const DHalfedge *prev2,
|
|
const X_monotone_curve_2& cv) const;
|
|
|
|
/*!
|
|
* Determine whether a given point lies within the region bounded by
|
|
* a boundary of a connected component.
|
|
* \param p The query point.
|
|
* \param v A vertex associated with the point p (or NULL if no such vertex
|
|
* exists or a vertex may exist but it is not known).
|
|
* \param he A halfedge on the boundary of the connected component.
|
|
* \return (true) if the point lies within region, (false) otherwise.
|
|
*/
|
|
bool _point_is_in (const Point_2& p,
|
|
const DVertex* v,
|
|
const DHalfedge* he) const;
|
|
|
|
/*!
|
|
* Move a given hole from one face to another.
|
|
* \param from_face The face currently containing the hole.
|
|
* \param to_face The face into which we should move the hole.
|
|
* \param hole A DCEL holes iterator pointing at the hole.
|
|
*/
|
|
void _move_hole (DFace *from_face,
|
|
DFace *to_face,
|
|
DHoles_iter hole);
|
|
|
|
/*!
|
|
* Insert the given vertex as an isolated vertex inside the given face.
|
|
* \param f The face that should contain the isolated vertex.
|
|
* \param v The isolated vertex.
|
|
*/
|
|
void _insert_isolated_vertex (DFace *f,
|
|
DVertex *v);
|
|
|
|
/*!
|
|
* Move a given isolated vertex from one face to another.
|
|
* \param from_face The face currently containing the isolated vertex.
|
|
* \param to_face The face into which we should move the isolated vertex.
|
|
* \param vit A DCEL isolated vertices iterator pointing at the vertex.
|
|
*/
|
|
void _move_isolated_vertex (DFace *from_face,
|
|
DFace *to_face,
|
|
DIsolated_vertices_iter vit);
|
|
|
|
/*!
|
|
* Create a new vertex and associate it with the given point.
|
|
* \param p The point.
|
|
* \return A pointer to the newly created vertex.
|
|
*/
|
|
DVertex* _create_vertex (const Point_2& p);
|
|
|
|
/*!
|
|
* Insert an x-monotone curve into the arrangement, such that both its
|
|
* endpoints correspond to free arrangement vertices (newly created vertices
|
|
* or existing isolated vertices), so a new hole is formed in the face
|
|
* that contains the two vertices.
|
|
* \param cv The given x-monotone curve.
|
|
* \param f The face containing the two end vertices.
|
|
* \param v1 The free vertex that corresponds to the left endpoint of cv.
|
|
* \param v2 The free vertex that corresponds to the right endpoint of cv.
|
|
* \param res The comparison result of the points associated with v1 and v2.
|
|
* \return A pointer to one of the halfedges corresponding to the inserted
|
|
* curve, directed from v1 to v2.
|
|
*/
|
|
DHalfedge* _insert_in_face_interior (const X_monotone_curve_2& cv,
|
|
DFace *f,
|
|
DVertex *v1, DVertex *v2,
|
|
Comparison_result res);
|
|
|
|
/*!
|
|
* Insert an x-monotone curve into the arrangement, such that one of its
|
|
* endpoints corresponds to a given arrangement vertex, given the exact
|
|
* place for the curve in the circular list around this vertex. The other
|
|
* endpoint corrsponds to a free vertex (a newly created vertex or an
|
|
* isolated vertex).
|
|
* \param cv The given x-monotone curve.
|
|
* \param prev The reference halfedge. We should represent cv as a pair
|
|
* of edges, one of them should become prev's successor.
|
|
* \param v The free vertex that corresponds to the other endpoint.
|
|
* \param res The comparison result of the points associated with prev's
|
|
* target and v.
|
|
* \return A pointer to one of the halfedges corresponding to the inserted
|
|
* curve, whose target is the vertex v.
|
|
*/
|
|
DHalfedge* _insert_from_vertex (const X_monotone_curve_2& cv,
|
|
DHalfedge *prev,
|
|
DVertex *v,
|
|
Comparison_result res);
|
|
|
|
/*!
|
|
* Insert an x-monotone curve into the arrangement, where the end vertices
|
|
* are given by the target points of two given halfedges.
|
|
* The two halfedges should be given such that in case a new face is formed,
|
|
* it will be the incident face of the halfedge directed from the first
|
|
* vertex to the second vertex.
|
|
* \param cv the given curve.
|
|
* \param prev1 The reference halfedge for the first vertex.
|
|
* \param prev2 The reference halfedge for the second vertex.
|
|
* \param res The comparison result of the points associated with prev1's
|
|
* target vertex and prev2's target vertex.
|
|
* \param new_face Output - whether a new face has been created.
|
|
* \return A pointer to one of the halfedges corresponding to the inserted
|
|
* curve directed from prev1's target to prev2's target.
|
|
* In case a new face has been created, it is given as the incident
|
|
* face of this halfedge.
|
|
*/
|
|
DHalfedge* _insert_at_vertices (const X_monotone_curve_2& cv,
|
|
DHalfedge *prev1,
|
|
DHalfedge *prev2,
|
|
Comparison_result res,
|
|
bool& new_face);
|
|
|
|
/*!
|
|
* Relocate all holes and isolated vertices to their proper position,
|
|
* immediately after a face has split due to the insertion of a new halfedge.
|
|
* \param new_he The new halfedge that caused the split, such that the new
|
|
* face lies to its left and the old face to its right.
|
|
*/
|
|
void _relocate_in_new_face (DHalfedge *new_he);
|
|
|
|
/*!
|
|
* Relocate all holes to their proper position,
|
|
* immediately after a face has split due to the insertion of a new halfedge.
|
|
* \param new_he The new halfedge that caused the split, such that the new
|
|
* face lies to its left and the old face to its right.
|
|
*/
|
|
void _relocate_holes_in_new_face (DHalfedge *new_he);
|
|
|
|
/*!
|
|
* Relocate all vertices to their proper position,
|
|
* immediately after a face has split due to the insertion of a new halfedge.
|
|
* \param new_he The new halfedge that caused the split, such that the new
|
|
* face lies to its left and the old face to its right.
|
|
*/
|
|
void _relocate_isolated_vertices_in_new_face (DHalfedge *new_he);
|
|
|
|
/*!
|
|
* Replace the point associated with the given vertex.
|
|
* \param v The vertex to modify.
|
|
* \param p The point that should be associated with the edge.
|
|
*/
|
|
void _modify_vertex (DVertex *v,
|
|
const Point_2& p);
|
|
|
|
/*!
|
|
* Replace the x-monotone curve associated with the given edge.
|
|
* \param e The edge to modify.
|
|
* \param cv The curve that should be associated with the edge.
|
|
*/
|
|
void _modify_edge (DHalfedge *he,
|
|
const X_monotone_curve_2& cv);
|
|
|
|
/*!
|
|
* Split a given edge into two at a given point, and associate the given
|
|
* x-monotone curves with the split edges.
|
|
* \param e The edge to split (one of the pair of twin halfegdes).
|
|
* \param p The split point.
|
|
* \param cv1 The curve that should be associated with the first split edge,
|
|
* whose source equals e's source and its target is p.
|
|
* \param cv2 The curve that should be associated with the second split edge,
|
|
* whose source is p and its target equals e's target.
|
|
* \return A pointer to the first split halfedge, whose source equals the
|
|
* source of e, and whose target is the split point.
|
|
*/
|
|
DHalfedge* _split_edge (DHalfedge *e,
|
|
const Point_2& p,
|
|
const X_monotone_curve_2& cv1,
|
|
const X_monotone_curve_2& cv2);
|
|
|
|
/*!
|
|
* Split a given edge into two at a given vertex, and associate the given
|
|
* x-monotone curves with the split edges.
|
|
* \param e The edge to split (one of the pair of twin halfegdes).
|
|
* \param v The split vertex.
|
|
* \param cv1 The curve that should be associated with the first split edge,
|
|
* whose source equals e's source and its target is v.
|
|
* \param cv2 The curve that should be associated with the second split edge,
|
|
* whose source is v and its target equals e's target.
|
|
* \return A pointer to the first split halfedge, whose source equals the
|
|
* source of e, and whose target is v.
|
|
*/
|
|
DHalfedge* _split_edge (DHalfedge *e,
|
|
DVertex *v,
|
|
const X_monotone_curve_2& cv1,
|
|
const X_monotone_curve_2& cv2);
|
|
|
|
/*!
|
|
* Remove a pair of twin halfedges from the arrangement.
|
|
* \param e One of the halfedges to be removed.
|
|
* \param remove_source Should the source vertex of e be removed if it
|
|
* becomes isolated.
|
|
* \param remove_target Should the target vertex of e be removed if it
|
|
* becomes isolated.
|
|
* \pre In case the removal causes the creation of a new hole, e should
|
|
* point at this hole.
|
|
* \return A pointer to the remaining face.
|
|
*/
|
|
DFace *_remove_edge (DHalfedge *e,
|
|
bool remove_source, bool remove_target);
|
|
|
|
/*!
|
|
* Remove an isolated vertex from the interior of its face (but not from
|
|
* the dcel)
|
|
* \param v The isolated vertex to remove.
|
|
*/
|
|
void _remove_isolated_vertex (DVertex* v);
|
|
|
|
//@}
|
|
|
|
/// \name Auxiliary (protected) functions for validity checking.
|
|
//@{
|
|
|
|
/*! Check the validity of a given vertex. */
|
|
bool _is_valid (Vertex_const_handle v) const;
|
|
|
|
/*! Check the validity of a given halfedge. */
|
|
bool _is_valid (Halfedge_const_handle he) const;
|
|
|
|
/*! Check the validity of a given face. */
|
|
bool _is_valid (Face_const_handle f) const;
|
|
|
|
/*! Check the validity of a CCB of a given face. */
|
|
bool _is_valid (Ccb_halfedge_const_circulator start,
|
|
Face_const_handle f) const;
|
|
|
|
/*!
|
|
* Check that all vertices are unique (no two vertices with the same
|
|
* geometric point.
|
|
*/
|
|
bool _are_vertices_unique() const;
|
|
|
|
/*! Check that the curves around a given vertex are ordered clockwise. */
|
|
bool _are_curves_ordered_cw_around_vertrex (Vertex_const_handle v) const;
|
|
|
|
//@}
|
|
|
|
protected:
|
|
|
|
/// \name Managing and notifying the arrangement observers.
|
|
//@{
|
|
|
|
/*!
|
|
* Register a new observer (so it starts receiving notifications).
|
|
* \param p_obs A pointer to the observer object.
|
|
*/
|
|
void _register_observer (Observer *p_obs)
|
|
{
|
|
observers.push_back (p_obs);
|
|
}
|
|
|
|
/*!
|
|
* Unregister a new observer (so it stops receiving notifications).
|
|
* \param p_obs A pointer to the observer object.
|
|
* \return Whether the observer was successfully unregistered.
|
|
*/
|
|
bool _unregister_observer (Observer *p_obs)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
{
|
|
if ((*iter) == p_obs)
|
|
{
|
|
// Remove the p_ob pointer from the list of observers.
|
|
observers.erase (iter);
|
|
return (true);
|
|
}
|
|
}
|
|
|
|
// If we reached here, the observer was not registered.
|
|
return (false);
|
|
}
|
|
|
|
private:
|
|
|
|
/* Notify the observers on global arrangement operations: */
|
|
|
|
void _notify_before_assign (const Self& arr)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_assign (arr);
|
|
}
|
|
|
|
void _notify_after_assign ()
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_assign();
|
|
}
|
|
|
|
void _notify_before_clear ()
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_clear();
|
|
}
|
|
|
|
void _notify_after_clear (Face_handle u)
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_clear (u);
|
|
}
|
|
|
|
void _notify_before_global_change ()
|
|
{
|
|
Observers_iterator iter;
|
|
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_global_change();
|
|
|
|
}
|
|
|
|
void _notify_after_global_change ()
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_global_change();
|
|
}
|
|
|
|
/* Notify the observers on local changes in the arrangement: */
|
|
|
|
void _notify_before_create_vertex (const Point_2& p)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_create_vertex (p);
|
|
}
|
|
|
|
void _notify_after_create_vertex (Vertex_handle v)
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_create_vertex (v);
|
|
}
|
|
|
|
void _notify_before_create_edge (const X_monotone_curve_2& c,
|
|
Vertex_handle v1, Vertex_handle v2)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_create_edge (c, v1, v2);
|
|
}
|
|
|
|
void _notify_after_create_edge (Halfedge_handle e)
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_create_edge (e);
|
|
}
|
|
|
|
void _notify_before_modify_vertex (Vertex_handle v,
|
|
const Point_2& p)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_modify_vertex (v, p);
|
|
}
|
|
|
|
void _notify_after_modify_vertex (Vertex_handle v)
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_modify_vertex (v);
|
|
}
|
|
|
|
void _notify_before_modify_edge (Halfedge_handle e,
|
|
const X_monotone_curve_2& c)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_modify_edge (e, c);
|
|
}
|
|
|
|
void _notify_after_modify_edge (Halfedge_handle e)
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_modify_edge (e);
|
|
}
|
|
|
|
void _notify_before_split_edge (Halfedge_handle e,
|
|
Vertex_handle v,
|
|
const X_monotone_curve_2& c1,
|
|
const X_monotone_curve_2& c2)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_split_edge (e, v, c1, c2);
|
|
}
|
|
|
|
void _notify_after_split_edge (Halfedge_handle e1,
|
|
Halfedge_handle e2)
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_split_edge (e1, e2);
|
|
}
|
|
|
|
void _notify_before_split_face (Face_handle f,
|
|
Halfedge_handle e)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_split_face (f, e);
|
|
}
|
|
|
|
void _notify_after_split_face (Face_handle f,
|
|
Face_handle new_f,
|
|
bool is_hole)
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_split_face (f, new_f, is_hole);
|
|
}
|
|
|
|
void _notify_before_split_hole (Face_handle f,
|
|
Ccb_halfedge_circulator h,
|
|
Halfedge_handle e)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_split_hole (f, h, e);
|
|
}
|
|
|
|
void _notify_after_split_hole (Face_handle f,
|
|
Ccb_halfedge_circulator h1,
|
|
Ccb_halfedge_circulator h2)
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_split_hole (f, h1, h2);
|
|
}
|
|
|
|
void _notify_before_add_hole (Face_handle f,
|
|
Halfedge_handle e)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_add_hole (f, e);
|
|
}
|
|
|
|
void _notify_after_add_hole (Ccb_halfedge_circulator h)
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_add_hole (h);
|
|
}
|
|
|
|
void _notify_before_add_isolated_vertex (Face_handle f,
|
|
Vertex_handle v)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_add_isolated_vertex (f, v);
|
|
}
|
|
|
|
void _notify_after_add_isolated_vertex (Vertex_handle v)
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_add_isolated_vertex (v);
|
|
}
|
|
|
|
void _notify_before_merge_edge (Halfedge_handle e1,
|
|
Halfedge_handle e2,
|
|
const X_monotone_curve_2& c)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_merge_edge (e1, e2, c);
|
|
}
|
|
|
|
void _notify_after_merge_edge (Halfedge_handle e)
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_merge_edge (e);
|
|
}
|
|
|
|
void _notify_before_merge_face (Face_handle f1,
|
|
Face_handle f2,
|
|
Halfedge_handle e)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_merge_face (f1, f2, e);
|
|
}
|
|
|
|
void _notify_after_merge_face (Face_handle f)
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_merge_face (f);
|
|
}
|
|
|
|
void _notify_before_merge_hole (Face_handle f,
|
|
Ccb_halfedge_circulator h1,
|
|
Ccb_halfedge_circulator h2,
|
|
Halfedge_handle e)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_merge_hole (f, h1, h2, e);
|
|
}
|
|
|
|
void _notify_after_merge_hole (Face_handle f,
|
|
Ccb_halfedge_circulator h)
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_merge_hole (f, h);
|
|
}
|
|
|
|
void _notify_before_move_hole (Face_handle from_f,
|
|
Face_handle to_f,
|
|
Ccb_halfedge_circulator h)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_move_hole (from_f, to_f, h);
|
|
}
|
|
|
|
void _notify_after_move_hole (Ccb_halfedge_circulator h)
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_move_hole (h);
|
|
}
|
|
|
|
void _notify_before_move_isolated_vertex (Face_handle from_f,
|
|
Face_handle to_f,
|
|
Vertex_handle v)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_move_isolated_vertex (from_f, to_f, v);
|
|
}
|
|
|
|
|
|
void _notify_after_move_isolated_vertex (Vertex_handle v)
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_move_isolated_vertex (v);
|
|
}
|
|
|
|
void _notify_before_remove_vertex (Vertex_handle v)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_remove_vertex (v);
|
|
}
|
|
|
|
void _notify_after_remove_vertex ()
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_remove_vertex ();
|
|
}
|
|
|
|
void _notify_before_remove_edge (Halfedge_handle e)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_remove_edge (e);
|
|
}
|
|
|
|
void _notify_after_remove_edge ()
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_remove_edge ();
|
|
}
|
|
|
|
void _notify_before_remove_hole (Face_handle f,
|
|
Ccb_halfedge_circulator h)
|
|
{
|
|
Observers_iterator iter;
|
|
Observers_iterator end = observers.end();
|
|
|
|
for (iter = observers.begin(); iter != end; ++iter)
|
|
(*iter)->before_remove_hole (f, h);
|
|
}
|
|
|
|
void _notify_after_remove_hole (Face_handle f)
|
|
{
|
|
Observers_rev_iterator iter;
|
|
Observers_rev_iterator end = observers.rend();
|
|
|
|
for (iter = observers.rbegin(); iter != end; ++iter)
|
|
(*iter)->after_remove_hole (f);
|
|
}
|
|
//@}
|
|
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Declarations of the various global insertion and removal functions.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* Insert a curve into the arrangement (incremental insertion).
|
|
* The inserted curve may not necessarily be x-monotone and may intersect the
|
|
* existing arrangement.
|
|
* \param arr The arrangement.
|
|
* \param cv The curve to be inserted.
|
|
* \param pl A point-location object associated with the arrangement.
|
|
*/
|
|
template <class Traits, class Dcel, class PointLocation>
|
|
void insert_curve (Arrangement_2<Traits,Dcel>& arr,
|
|
const typename Traits::Curve_2& c,
|
|
const PointLocation& pl);
|
|
|
|
/*!
|
|
* Insert a curve into the arrangement (incremental insertion).
|
|
* The inserted curve may not necessarily be x-monotone and may intersect the
|
|
* existing arrangement. The default "walk" point-location strategy is used
|
|
* for the curve insertion.
|
|
* \param arr The arrangement.
|
|
* \param cv The curve to be inserted.
|
|
*/
|
|
template <class Traits, class Dcel>
|
|
void insert_curve (Arrangement_2<Traits,Dcel>& arr,
|
|
const typename Traits::Curve_2& c);
|
|
|
|
/*!
|
|
* Insert a range of curves into the arrangement (aggregated insertion).
|
|
* The inserted curves may intersect one another and may also intersect the
|
|
* existing arrangement.
|
|
* \param arr The arrangement.
|
|
* \param begin An iterator for the first curve in the range.
|
|
* \param end A past-the-end iterator for the curve range.
|
|
* \pre The value type of the iterators must be Curve_2.
|
|
*/
|
|
template <class Traits, class Dcel, class InputIterator>
|
|
void insert_curves (Arrangement_2<Traits,Dcel>& arr,
|
|
InputIterator begin, InputIterator end);
|
|
|
|
/*!
|
|
* Insert an x-monotone curve into the arrangement (incremental insertion).
|
|
* The inserted x-monotone curve may intersect the existing arrangement.
|
|
* \param arr The arrangement.
|
|
* \param cv The x-monotone curve to be inserted.
|
|
* \param pl A point-location object associated with the arrangement.
|
|
*/
|
|
template <class Traits, class Dcel, class PointLocation>
|
|
void insert_x_monotone_curve (Arrangement_2<Traits,Dcel>& arr,
|
|
const typename Traits::X_monotone_curve_2& c,
|
|
const PointLocation& pl);
|
|
|
|
/*!
|
|
* Insert an x-monotone curve into the arrangement (incremental insertion)
|
|
* when the location of the left endpoint of the curve is known and is
|
|
* given as an isertion hint.
|
|
* The inserted x-monotone curve may intersect the existing arrangement.
|
|
* \param arr The arrangement.
|
|
* \param cv The x-monotone curve to be inserted.
|
|
* \param obj An object that represents the location of cv's left endpoint
|
|
* in the arrangement.
|
|
*/
|
|
|
|
template <class Traits, class Dcel>
|
|
void insert_x_monotone_curve (Arrangement_2<Traits,Dcel>& arr,
|
|
const typename Traits::X_monotone_curve_2& c,
|
|
const Object& obj);
|
|
|
|
/*!
|
|
* Insert an x-monotone curve into the arrangement (incremental insertion).
|
|
* The inserted x-monotone curve may intersect the existing arrangement.
|
|
* The default "walk" point-location strategy is used for the curve insertion.
|
|
* \param arr The arrangement.
|
|
* \param cv The x-monotone curve to be inserted.
|
|
*/
|
|
template <class Traits, class Dcel>
|
|
void insert_x_monotone_curve (Arrangement_2<Traits,Dcel>& arr,
|
|
const typename Traits::X_monotone_curve_2& c);
|
|
|
|
/*!
|
|
* Insert a range of x-monotone curves into the arrangement (aggregated
|
|
* insertion). The inserted x-monotone curves may intersect one another and
|
|
* may also intersect the existing arrangement.
|
|
* \param arr The arrangement.
|
|
* \param begin An iterator for the first curve in the range.
|
|
* \param end A past-the-end iterator for the curve range.
|
|
* \pre The value type of the iterators must be X_monotone_curve_2.
|
|
*/
|
|
template <class Traits, class Dcel, class InputIterator>
|
|
void insert_x_monotone_curves (Arrangement_2<Traits,Dcel>& arr,
|
|
InputIterator begin, InputIterator end);
|
|
|
|
/*!
|
|
* Insert an x-monotone curve into the arrangement, such that the curve
|
|
* interior does not intersect with any existing edge or vertex in the
|
|
* arragement (incremental insertion).
|
|
* \param arr The arrangement.
|
|
* \param c The x-monotone curve to be inserted.
|
|
* \param pl A point-location object associated with the arrangement.
|
|
* \pre The interior of c does not intersect any existing edge or vertex.
|
|
* \return A handle for one of the new halfedges corresponding to the inserted
|
|
* curve, directed (lexicographically) from left to right.
|
|
*/
|
|
template <class Traits, class Dcel, class PointLocation>
|
|
typename Arrangement_2<Traits,Dcel>::Halfedge_handle
|
|
insert_non_intersecting_curve (Arrangement_2<Traits,Dcel>& arr,
|
|
const typename Traits::X_monotone_curve_2& c,
|
|
const PointLocation& pl);
|
|
|
|
/*!
|
|
* Insert an x-monotone curve into the arrangement, such that the curve
|
|
* interior does not intersect with any existing edge or vertex in the
|
|
* arragement (incremental insertion). The default "walk" point-location
|
|
* strategy is used for the curve insertion.
|
|
* \param arr The arrangement.
|
|
* \param c The x-monotone curve to be inserted.
|
|
* \pre The interior of c does not intersect any existing edge or vertex.
|
|
|
|
* \return A handle for one of the new halfedges corresponding to the inserted
|
|
* curve, directed (lexicographically) from left to right.
|
|
*/
|
|
template <class Traits, class Dcel>
|
|
typename Arrangement_2<Traits,Dcel>::Halfedge_handle
|
|
insert_non_intersecting_curve (Arrangement_2<Traits,Dcel>& arr,
|
|
const typename Traits::X_monotone_curve_2& c);
|
|
|
|
/*!
|
|
* Insert a range of pairwise interior-disjoint x-monotone curves into
|
|
* the arrangement, such that the curve interiors do not intersect with
|
|
* any existing edge or vertex in the arragement (aggregated insertion).
|
|
* \param arr The arrangement.
|
|
* \param begin An iterator for the first x-monotone curve in the range.
|
|
* \param end A past-the-end iterator for the x-monotone curve range.
|
|
* \pre The value type of the iterators must be X_monotone_curve_2.
|
|
* The curves in the range are pairwise interior-disjoint, and their
|
|
* interiors do not intersect any existing edge or vertex.
|
|
*/
|
|
template <class Traits, class Dcel, class InputIterator>
|
|
void insert_non_intersecting_curves (Arrangement_2<Traits,Dcel>& arr,
|
|
InputIterator begin, InputIterator end);
|
|
|
|
/*!
|
|
* Remove an edge from the arrangement. In case it is possible to merge
|
|
* the edges incident to the end-vertices of the removed edge after its
|
|
* deletion, the function performs these merges as well.
|
|
* \param arr The arrangement.
|
|
* \param e The edge to remove (one of the pair of twin halfegdes).
|
|
* \return A handle for the remaining face.
|
|
*/
|
|
template <class Traits, class Dcel>
|
|
typename Arrangement_2<Traits,Dcel>::Face_handle
|
|
remove_edge (Arrangement_2<Traits,Dcel>& arr,
|
|
typename Arrangement_2<Traits,Dcel>::Halfedge_handle e);
|
|
|
|
/*!
|
|
* Insert a vertex that corresponds to a given point into the arrangement.
|
|
* The inserted point may lie on any existing arrangement feature.
|
|
* \param arr The arrangement.
|
|
* \param p The point to be inserted.
|
|
* \param pl A point-location object associated with the arrangement.
|
|
* \return A handle to the vertex that corresponds to the given point.
|
|
*/
|
|
template <class Traits, class Dcel, class PointLocation>
|
|
typename Arrangement_2<Traits,Dcel>::Vertex_handle
|
|
insert_point (Arrangement_2<Traits,Dcel>& arr,
|
|
const typename Traits::Point_2& p,
|
|
const PointLocation& pl);
|
|
|
|
/*!
|
|
* Insert a vertex that corresponds to a given point into the arrangement.
|
|
* The inserted point may lie on any existing arrangement feature.
|
|
* \param arr The arrangement.
|
|
* \param p The point to be inserted.
|
|
* \return A handle to the vertex that corresponds to the given point.
|
|
*/
|
|
template <class Traits, class Dcel>
|
|
typename Arrangement_2<Traits,Dcel>::Vertex_handle
|
|
insert_point (Arrangement_2<Traits,Dcel>& arr,
|
|
const typename Traits::Point_2& p);
|
|
|
|
/*!
|
|
* Remove a vertex from the arrangement.
|
|
* \param arr The arrangement.
|
|
* \param v The vertex to remove.
|
|
* \return Whether the vertex has been removed or not.
|
|
*/
|
|
template <class Traits, class Dcel>
|
|
bool remove_vertex (Arrangement_2<Traits,Dcel>& arr,
|
|
typename Arrangement_2<Traits,Dcel>::Vertex_handle v);
|
|
|
|
|
|
/*!
|
|
* Check the validity of the arrangement. In particular, check that the
|
|
* edegs are disjoint-interior, and the holes are located in their proper
|
|
* position.
|
|
* \param arr The arrangement.
|
|
* \return Whether the arrangement is valid.
|
|
*/
|
|
template <class Traits, class Dcel>
|
|
bool is_valid (const Arrangement_2<Traits,Dcel>& arr);
|
|
|
|
CGAL_END_NAMESPACE
|
|
|
|
// The function definitions can be found under:
|
|
#include <CGAL/Arrangement_2/Arrangement_2_functions.h>
|
|
#include <CGAL/Arrangement_2/Arrangement_2_insert.h>
|
|
|
|
#endif
|
|
|