Merge branch 'Aos_2-test_spherical_blp_vd-tau'

* Enhancing the testsuite---adding tests for
    batched, point location
    vertical decomposition, and
    triangulation point location.
* Various bug fixes:
    bugs in point location.
    memory leaks found by Andreas.

* Resolving several small issues to remove compiler warnings.
Tested last in CGAL-4.4-Ic-54.
Approved by the release manager
This commit is contained in:
Efi Fogel 2013-12-11 15:15:40 +02:00
commit 32b8625a46
110 changed files with 4088 additions and 2452 deletions

View File

@ -76,7 +76,7 @@ QColor ArrangementDemoGraphicsView::getBackgroundColor( ) const
}
void ArrangementDemoGraphicsView::drawForeground( QPainter* painter,
const QRectF& rect )
const QRectF& /* rect */)
{
QRectF viewportRect = this->getViewportRect( );
if ( this->showGrid )

View File

@ -45,7 +45,7 @@
#include "ColorItemEditor.h"
ColorItemEditor::ColorItemEditor( QWidget* widget ) : QPushButton( widget )
{
{
this->setText( tr("Select a color") );
}
@ -59,14 +59,13 @@ void ColorItemEditor::setColor( QColor color )
this->m_color = color;
}
void ColorItemEditor::mousePressEvent( QMouseEvent* e )
void ColorItemEditor::mousePressEvent(QMouseEvent* /* e */)
{
QColor selectedColor = QColorDialog::getColor( this->m_color );
if ( selectedColor.isValid( ) )
{
// std::cout << selectedColor.name( ).toStdString( ) << std::endl;
QColor selectedColor = QColorDialog::getColor(this->m_color);
if (selectedColor.isValid()) {
// std::cout << selectedColor.name().toStdString() << std::endl;
this->setColor( selectedColor );
}
emit confirmed( );
emit confirmed();
}

View File

@ -43,13 +43,13 @@ QGraphicsScene* GraphicsViewSegmentInputBase::getScene( ) const
return this->scene;
}
void
GraphicsViewSegmentInputBase::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
void GraphicsViewSegmentInputBase::
mouseMoveEvent(QGraphicsSceneMouseEvent* /* event */)
{ }
void
GraphicsViewSegmentInputBase::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
void GraphicsViewSegmentInputBase::
mousePressEvent(QGraphicsSceneMouseEvent* /* event */)
{
// std::cout << "GraphicsViewSegmentInputBase::mousePressEvent" << std::endl;
}
@ -67,7 +67,7 @@ bool GraphicsViewSegmentInputBase::eventFilter( QObject* obj, QEvent* event )
static_cast< QGraphicsSceneMouseEvent* >( event );
this->mousePressEvent( mouseEvent );
}
return QObject::eventFilter( obj, event );
}

View File

@ -28,9 +28,9 @@ PointsGraphicsItem::PointsGraphicsItem( ) :
color( ::Qt::blue )
{ }
void PointsGraphicsItem::paint( QPainter* painter,
const QStyleOptionGraphicsItem* option,
QWidget* widget )
void PointsGraphicsItem::paint(QPainter* painter,
const QStyleOptionGraphicsItem* /* option */,
QWidget* /* widget */)
{
double scale = painter->worldTransform( ).m11( );
double radius = this->pointRadius;
@ -53,19 +53,19 @@ QRectF PointsGraphicsItem::boundingRect( ) const
{
return QRectF( );
}
double xmin = std::numeric_limits< double >::max( );
double xmax = -std::numeric_limits< double >::max( );
double ymin = std::numeric_limits< double >::max( );
double ymax = -std::numeric_limits< double >::max( );
for ( unsigned int i = 0; i < this->points.size( ); ++i )
double xmin = (std::numeric_limits< double >::max)( );
double xmax = -(std::numeric_limits< double >::max)( );
double ymin = (std::numeric_limits< double >::max)( );
double ymax = -(std::numeric_limits< double >::max)( );
for ( unsigned int i = 0; i < this->points.size(); ++i )
{
QPointF pt = this->points[ i ];
double x = pt.x( );
double y = pt.y( );
xmin = std::min( xmin, x );
xmax = std::max( xmax, x );
ymin = std::min( ymin, y );
ymax = std::max( ymax, y );
xmin = (std::min)( xmin, x );
xmax = (std::max)( xmax, x );
ymin = (std::min)( ymin, y );
ymax = (std::max)( ymax, y );
}
QRectF res( QPointF( xmin, ymin ), QPointF( xmax, ymax ) );
res.adjust( -5, -5, 5, 5 ); // pad the borders a bit

View File

@ -870,9 +870,12 @@ print_point_location
\subsection arr_sssecpl_strat Choosing a Point-Location Strategy
Each of the various point-location class templates employs a different
algorithm or <I>strategy</I>\cgalFootnote{We use the term <I>strategy</I>
is borrowed from the design-pattern taxonomy \cgalCite{cgal:ghjv-dpero-95}, Chapter 5.}
for answering queries:
algorithm or <I>strategy</I>\cgalFootnote{The term <I>strategy</I>
is borrowed from the design-pattern taxonomy \cgalCite{cgal:ghjv-dpero-95},
Chapter 5. A <I>strategy</I> provides the means to define a family of
algorithms, each implemented by a separate class. All classes that implement
the various algorithms are made interchangeable, letting the algorithm in use
vary according to the user choice.} for answering queries:
<UL>
<LI> `Arr_naive_point_location<Arrangement>` employes the
<I>naive</I> strategy. It locates the query point naively,
@ -883,14 +886,15 @@ for answering queries:
It simulates a traversal, in reverse order, along an imaginary
vertical ray emanating from the query point. It starts from the
unbounded face of the arrangement and moves downward toward the
query point until locating the arrangement cell containing it.
query point until it locates the arrangement cell containing it.
%
<LI>`Arr_landmarks_point_location<Arrangement,Generator>`
uses a set of <I>landmark</I> points the location of which in the
arrangement is known. It employs the
<I>landmark</I> strategy. Given a query point, it uses a
nearest-neighbor search-structure (a <span class="textsc">Kd</span>-tree is used by default)
to find the nearest landmark and then traverses the straight-line
segment connecting this landmark to the query point.
uses a set of <I>landmark</I> points, the location of which in the
arrangement is known. It employs the <I>landmark</I> strategy. Given a
query point, it uses a nearest-neighbor search-structure (a
<span class="textsc">Kd</span>-tree is used by default) to find the
nearest landmark, and then traverses the straight-line segment
connecting this landmark to the query point.
There are various ways to select the landmark set in the
arrangement. The selection is governed by the `Generator`
@ -910,15 +914,20 @@ for answering queries:
Section \ref arr_sssectr_lanmarks_concept for details. Most traits
classes included in the <I>2D Arrangement</I> package are models of
this refined concept.
<LI>`Arr_trapezoid_ric_point_location<Arrangement>` implements
Mulmuley's point-location algorithm \cgalCite{m-fppa-90}; see
also \cgalCite{bkos-cgaa-00}, Chapter 6. The arrangement faces are
decomposed into simpler cells each of constant complexity, known as
<I>pseudo-trapezoids</I>, and a search structure (a directed acyclic
%
<LI>`Arr_trapezoid_ric_point_location<Arrangement>` implements an
improved variant of Mulmuley's point-location algorithm
\cgalCite{m-fppa-90}; see also \cgalCite{bkos-cgaa-00}, Chapter 6.
The (expected) query-time is logarithmic. The arrangement faces
are decomposed into simpler cells each of constant complexity, known
as <I>pseudo-trapezoids</I>, and a search structure (a directed acyclic
graph) is constructed on top of these cells, facilitating the search
of the pseudo trapezoid (hence the arrangement cell) containing a
query point in expected logarithmic time. The trapezoidal map and
the search structure are built by a algorithm (RIC).
the search structure are built by a randomized incremental construction
algorithm (RIC).
%
</UL>
The first two strategies do not require any extra data. The class

View File

@ -10,4 +10,3 @@ include/CGAL/Arr_extended_rational_arc_traits_d_1.h
include/CGAL/Arr_hyperbolic_arc_traits_2.h
include/CGAL/Arr_polycurve_traits_2.h
include/CGAL/Arr_rational_arc_traits_2.h
include/CGAL/Arr_triangulation_point_location.h

View File

@ -15,7 +15,7 @@
#include "arr_print.h"
// A property map that reads/writes the information to/from the extended
// A property map that reads/writes the information to/from the extended
// face.
template <typename Arrangement, class Type> class Extended_face_property_map {
public:
@ -28,11 +28,12 @@ public:
typedef Face_handle key_type;
// The get function is required by the property map concept.
friend reference get(const Extended_face_property_map& map, key_type key)
friend reference get(const Extended_face_property_map& /* map */,
key_type key)
{ return key->data(); }
// The put function is required by the property map concept.
friend void put(Extended_face_property_map,
friend void put(Extended_face_property_map /* map */,
key_type key, value_type val)
{ key->set_data(val); }
};

View File

@ -17,12 +17,11 @@ typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
typedef Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef Arrangement_2::Face_const_handle Face_const_handle;
typedef std::pair<Vertex_const_handle, std::pair<CGAL::Object, CGAL::Object> >
Vert_decomp_entry;
typedef std::pair<CGAL::Object, CGAL::Object> Object_pair;
typedef std::pair<Vertex_const_handle, Object_pair> Vert_decomp_entry;
typedef std::list<Vert_decomp_entry> Vert_decomp_list;
int main ()
int main()
{
// Construct the arrangement.
Arrangement_2 arr;
@ -38,37 +37,35 @@ int main ()
// Perform vertical ray-shooting from every vertex and locate the feature
// that lie below it and the feature that lies above it.
Vert_decomp_list vd_list;
CGAL::decompose (arr, std::back_inserter(vd_list));
Vert_decomp_list vd_list;
CGAL::decompose(arr, std::back_inserter(vd_list));
// Print the results.
Vert_decomp_list::const_iterator vd_iter;
std::pair<CGAL::Object, CGAL::Object> curr;
Vertex_const_handle vh;
Halfedge_const_handle hh;
Face_const_handle fh;
Vert_decomp_list::const_iterator vd_iter;
for (vd_iter = vd_list.begin(); vd_iter != vd_list.end(); ++vd_iter) {
curr = vd_iter->second;
const Object_pair& curr = vd_iter->second;
std::cout << "Vertex (" << vd_iter->first->point() << ") : ";
Vertex_const_handle vh;
Halfedge_const_handle hh;
Face_const_handle fh;
std::cout << " feature below: ";
if (CGAL::assign (hh, curr.first))
if (CGAL::assign(hh, curr.first))
std::cout << '[' << hh->curve() << ']';
else if (CGAL::assign (vh, curr.first))
else if (CGAL::assign(vh, curr.first))
std::cout << '(' << vh->point() << ')';
else if (CGAL::assign (fh, curr.first))
else if (CGAL::assign(fh, curr.first))
std::cout << "NONE";
else
std::cout << "EMPTY";
std::cout << " feature above: ";
if (CGAL::assign (hh, curr.second))
if (CGAL::assign(hh, curr.second))
std::cout << '[' << hh->curve() << ']' << std::endl;
else if (CGAL::assign (vh, curr.second))
else if (CGAL::assign(vh, curr.second))
std::cout << '(' << vh->point() << ')' << std::endl;
else if (CGAL::assign (fh, curr.second))
else if (CGAL::assign(fh, curr.second))
std::cout << "NONE" << std::endl;
else
std::cout << "EMPTY" << std::endl;

View File

@ -14,7 +14,7 @@
//
// $URL$
// $Id$
//
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
@ -39,24 +39,22 @@
namespace CGAL {
// Forward declaration:
template <class GeomTraits_, class TopTraits_>
template <typename GeomTraits_, typename TopTraits_>
class Arrangement_on_surface_2;
/*! \class Arr_bounded_planar_topology_traits_2
* A topology-traits class that encapsulates the embedding of 2D arrangements
* of bounded curves on the plane.
*/
template <class GeomTraits_,
class Dcel_ = Arr_default_dcel<GeomTraits_> >
template <typename GeomTraits_,
typename Dcel_ = Arr_default_dcel<GeomTraits_> >
class Arr_bounded_planar_topology_traits_2 :
public Arr_planar_topology_traits_base_2<GeomTraits_, Dcel_>
{
private:
typedef Arr_planar_topology_traits_base_2<GeomTraits_, Dcel_> Base;
public:
///! \name The geometry-traits types.
//@{
typedef GeomTraits_ Geometry_traits_2;
@ -81,14 +79,14 @@ public:
typedef Arr_bounded_planar_topology_traits_2<Geometry_traits_2, Dcel> Self;
typedef Arr_traits_basic_adaptor_2<Geometry_traits_2> Traits_adaptor_2;
//!@}
///! \name The side tags
//@{
typedef typename Traits_adaptor_2::Left_side_category Left_side_category;
typedef typename Traits_adaptor_2::Bottom_side_category Bottom_side_category;
typedef typename Traits_adaptor_2::Top_side_category Top_side_category;
typedef typename Traits_adaptor_2::Right_side_category Right_side_category;
BOOST_MPL_ASSERT
((boost::is_same< Left_side_category, Arr_oblivious_side_tag >));
BOOST_MPL_ASSERT
@ -100,50 +98,47 @@ public:
//@}
/*! \struct
* An auxiliary structure for rebinding the topology traits with a new
* An auxiliary structure for rebinding the topology traits with a new
* geometry-traits class and a new DCEL class.
*/
template<typename T, typename D>
struct rebind
{
typedef Arr_bounded_planar_topology_traits_2<T,D> other;
struct rebind {
typedef Arr_bounded_planar_topology_traits_2<T, D> other;
};
protected:
// Data members:
Face *unb_face; // The unbounded face.
Face* unb_face; // The unbounded face.
// Copy constructor and assignment operator - not supported.
Arr_bounded_planar_topology_traits_2 (const Self& );
Self& operator= (const Self& );
Arr_bounded_planar_topology_traits_2(const Self&);
Self& operator=(const Self&);
public:
///! \name Construction methods.
//@{
/*! Default constructor. */
Arr_bounded_planar_topology_traits_2 () :
Arr_bounded_planar_topology_traits_2() :
Base(),
unb_face (NULL)
unb_face(NULL)
{}
/*! Constructor with a geometry-traits class. */
Arr_bounded_planar_topology_traits_2 (const Geometry_traits_2 *tr) :
Base (tr),
unb_face (NULL)
/*! Constructor from a geometry-traits object. */
Arr_bounded_planar_topology_traits_2(const Geometry_traits_2* traits) :
Base(traits),
unb_face(NULL)
{}
/*! Assign the contents of another topology-traits class. */
void assign (const Self& other);
void assign(const Self& other);
//@}
///! \name Accessing the DCEL and constructing iterators.
//@{
/*! Determine whether the DCEL reprsenets an empty structure. */
bool is_empty_dcel () const
bool is_empty_dcel() const
{
// An empty bounded arrangement has no edges or vertices.
return (this->m_dcel.size_of_vertices() == 0 &&
@ -151,52 +146,40 @@ public:
}
/*! Check if the given vertex is concrete (associated with a point). */
inline bool is_concrete_vertex (const Vertex *) const
{
return (true);
}
inline bool is_concrete_vertex(const Vertex*) const { return true; }
/*! Get the number of concrete vertices. */
Size number_of_concrete_vertices () const
Size number_of_concrete_vertices() const
{
// All vertices are concrete.
return (this->m_dcel.size_of_vertices());
}
/*! Check if the given vertex is valid (not a fictitious one). */
inline bool is_valid_vertex (const Vertex *) const
{
return (true);
}
inline bool is_valid_vertex(const Vertex*) const { return true; }
/*! Get the number of valid vertices. */
Size number_of_valid_vertices () const
Size number_of_valid_vertices() const
{
// All vertices are valid.
return (this->m_dcel.size_of_vertices());
}
/*! Check if the given halfedge is valid (not a fictitious one). */
inline bool is_valid_halfedge (const Halfedge *) const
{
return (true);
}
inline bool is_valid_halfedge(const Halfedge*) const { return true; }
/*! Get the number of valid halfedges. */
Size number_of_valid_halfedges () const
Size number_of_valid_halfedges() const
{
// All halfedges are valid.
return (this->m_dcel.size_of_halfedges());
}
/*! Check if the given face is valid (not a fictitious one). */
inline bool is_valid_face (const Face *) const
{
return (true);
}
inline bool is_valid_face (const Face*) const { return true; }
/*! Get the number of valid faces. */
Size number_of_valid_faces () const
Size number_of_valid_faces() const
{
// All faces are valid.
return (this->m_dcel.size_of_faces());
@ -207,13 +190,12 @@ private:
/// \name Auxiliary type definitions.
//@{
typedef Arrangement_on_surface_2<Geometry_traits_2, Self> Arr;
typedef Arrangement_on_surface_2<Geometry_traits_2, Self> Arr;
// Type definition for the constuction sweep-line visitor.
typedef Arr_construction_subcurve<Geometry_traits_2> CSubcurve;
typedef Arr_construction_event<Geometry_traits_2,
CSubcurve,
Arr> CEvent;
typedef Arr_construction_subcurve<Geometry_traits_2> CSubcurve;
typedef Arr_construction_event<Geometry_traits_2, CSubcurve, Arr>
CEvent;
typedef Arr_bounded_planar_construction_helper<Geometry_traits_2,
Arr,
CEvent,
@ -221,24 +203,18 @@ private:
// Type definition for the basic insertion sweep-line visitor.
typedef Arr_basic_insertion_traits_2<Geometry_traits_2, Arr> BInsTraits;
typedef Arr_construction_subcurve<BInsTraits> BISubcurve;
typedef Arr_construction_event<BInsTraits,
BISubcurve,
Arr> BIEvent;
typedef Arr_bounded_planar_insertion_helper<BInsTraits,
Arr,
BIEvent,
typedef Arr_construction_subcurve<BInsTraits> BISubcurve;
typedef Arr_construction_event<BInsTraits, BISubcurve, Arr>
BIEvent;
typedef Arr_bounded_planar_insertion_helper<BInsTraits, Arr, BIEvent,
BISubcurve> BIHelper;
// Type definition for the insertion sweep-line visitor.
typedef Arr_insertion_traits_2<Geometry_traits_2, Arr> InsTraits;
typedef Arr_construction_subcurve<InsTraits> ISubcurve;
typedef Arr_construction_event<InsTraits,
ISubcurve,
Arr> IEvent;
typedef Arr_bounded_planar_insertion_helper<InsTraits,
Arr,
IEvent,
typedef Arr_construction_subcurve<InsTraits> ISubcurve;
typedef Arr_construction_event<InsTraits, ISubcurve, Arr>
IEvent;
typedef Arr_bounded_planar_insertion_helper<InsTraits, Arr, IEvent,
ISubcurve> IHelper;
// Type definition for the batched point-location sweep-line visitor.
@ -273,9 +249,8 @@ private:
typedef typename Base::Subcurve Subcurve;
typedef typename Base::Construction_helper Construction_helper;
_Overlay_helper (const ArrangementA_ *arrA,
const ArrangementB_ *arrB) :
Base (arrA, arrB)
_Overlay_helper(const ArrangementA_* arr_a, const ArrangementB_* arr_b) :
Base(arr_a, arr_b)
{}
};
//@}
@ -293,7 +268,7 @@ public:
typedef Sweep_line_construction_visitor
Sweep_line_non_intersecting_construction_visitor;
typedef Arr_basic_insertion_sl_visitor<BIHelper>
Sweep_line_non_intersecting_insertion_visitor;
@ -308,9 +283,9 @@ public:
typedef typename Base::Event Event;
typedef typename Base::Subcurve Subcurve;
Sweep_line_batched_point_location_visitor (const Arr *arr,
Sweep_line_batched_point_location_visitor(const Arr* arr,
Output_iterator& oi) :
Base (arr, oi)
Base(arr, oi)
{}
};
@ -325,9 +300,9 @@ public:
typedef typename Base::Event Event;
typedef typename Base::Subcurve Subcurve;
Sweep_line_vertical_decomposition_visitor (const Arr *arr,
Output_iterator *oi) :
Base (arr, oi)
Sweep_line_vertical_decomposition_visitor(const Arr* arr,
Output_iterator* oi) :
Base(arr, oi)
{}
};
@ -338,7 +313,7 @@ public:
Arr_overlay_traits_2< Arr_traits_basic_adaptor_2<Geometry_traits_2>,
ArrangementA_,
ArrangementB_>,
ArrangementA_,
ArrangementA_,
ArrangementB_>,
OverlayTraits_>
{
@ -347,7 +322,7 @@ public:
typedef Arr Arrangement_result_2;
typedef OverlayTraits_ Overlay_traits;
typedef Arr_overlay_traits_2<
typedef Arr_overlay_traits_2<
Arr_traits_basic_adaptor_2<Geometry_traits_2>,
ArrangementA_2,
ArrangementB_2> Geom_ovl_traits_2;
@ -362,20 +337,22 @@ public:
typedef typename Base::Event Event;
typedef typename Base::Subcurve Subcurve;
Sweep_line_overlay_visitor (const ArrangementA_2 *arrA,
const ArrangementB_2 *arrB,
Arrangement_result_2 *arr_res,
Overlay_traits *overlay_tr) :
Sweep_line_overlay_visitor (const ArrangementA_2* arrA,
const ArrangementB_2* arrB,
Arrangement_result_2* arr_res,
Overlay_traits* overlay_tr) :
Base (arrA, arrB, arr_res, overlay_tr)
{}
};
typedef Arr_inc_insertion_zone_visitor<Arr>
Zone_insertion_visitor;
Zone_insertion_visitor;
typedef Arr_walk_along_line_point_location<Arr>
Default_point_location_strategy;
Default_point_location_strategy;
typedef Arr_walk_along_line_point_location<Arr>
Default_vertical_ray_shooting_strategy;
//@}
///! \name Topology-traits methods.
@ -384,12 +361,12 @@ public:
/*!
* Initialize an empty DCEL structure.
*/
void init_dcel ();
void init_dcel();
/*!
* Make the necessary updates after the DCEL structure have been updated.
*/
void dcel_updated ();
void dcel_updated();
/*!
* Check if the given vertex is associated with the given curve end.
@ -401,24 +378,22 @@ public:
* \pre The curve has a boundary condition in either x or y.
* \return Whether v represents the given curve end.
*/
bool are_equal (const Vertex *v,
const X_monotone_curve_2& cv, Arr_curve_end ind,
Arr_parameter_space ps_x, Arr_parameter_space ps_y) const
bool are_equal(const Vertex* v,
const X_monotone_curve_2& cv, Arr_curve_end ind,
Arr_parameter_space ps_x, Arr_parameter_space ps_y) const
{
CGAL_assertion ((ps_x == ARR_INTERIOR) && (ps_y == ARR_INTERIOR));
CGAL_assertion((ps_x == ARR_INTERIOR) && (ps_y == ARR_INTERIOR));
if (ind == ARR_MIN_END)
{
if (ind == ARR_MIN_END) {
// Compare v with the left endpoint of cv.
return (this->traits->equal_2_object()
(this->traits->construct_min_vertex_2_object() (cv),
return (this->m_geom_traits->equal_2_object()
(this->m_geom_traits->construct_min_vertex_2_object()(cv),
v->point()));
}
else
{
else {
// Compare v with the right endpoint of cv.
return (this->traits->equal_2_object()
(this->traits->construct_max_vertex_2_object() (cv),
return (this->m_geom_traits->equal_2_object()
(this->m_geom_traits->construct_max_vertex_2_object()(cv),
v->point()));
}
}
@ -435,11 +410,11 @@ public:
* \pre The curve has a boundary condition in either x or y.
* \return An object that contains the curve end.
*/
CGAL::Object place_boundary_vertex (Face *,
const X_monotone_curve_2&,
Arr_curve_end,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
CGAL::Object place_boundary_vertex(Face*,
const X_monotone_curve_2&,
Arr_curve_end,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
{
// This function should never be called:
CGAL_error();
@ -459,14 +434,14 @@ public:
* \return An object that contains the curve end.
*/
Halfedge*
locate_around_boundary_vertex (Vertex *,
const X_monotone_curve_2&,
Arr_curve_end,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */) const
locate_around_boundary_vertex(Vertex*,
const X_monotone_curve_2&,
Arr_curve_end,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */) const
{
CGAL_error();
return (NULL);
return NULL;
}
/*!
@ -478,10 +453,10 @@ public:
* \pre The curve end is incident to the boundary.
* \return An object that contains the curve end.
*/
CGAL::Object locate_curve_end (const X_monotone_curve_2&,
Arr_curve_end,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
CGAL::Object locate_curve_end(const X_monotone_curve_2&,
Arr_curve_end,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
{
// This function should never be called:
CGAL_error();
@ -496,34 +471,28 @@ public:
* \return A halfedge whose direction is the same as e's and whose target is
* the split vertex v.
*/
Halfedge* split_fictitious_edge (Halfedge *, Vertex *)
Halfedge* split_fictitious_edge (Halfedge*, Vertex*)
{
// This function should never be called:
CGAL_error();
return (NULL);
return NULL;
}
/*!
* Determine whether the given face is unbounded.
* \param f The face.
* \return Whether f is unbounded.
* There is only one unbounded face in the arrangement:
*/
bool is_unbounded (const Face *f) const
{
// There is only one unbounded face in the arrangement:
return (f == unb_face);
}
bool is_unbounded(const Face* f) const { return (f == unb_face); }
/*!
* Determine whether the given boundary vertex is redundant.
* \param v The vertex.
* \return Whether v is redundant, and should be erased.
* There are no redundant vertices.
*/
bool is_redundant (const Vertex *) const
{
// There are no redundant vertices.
return (false);
}
bool is_redundant(const Vertex*) const { return false; }
/*!
* Erase the given redundant vertex by merging a fictitious edge.
@ -532,11 +501,11 @@ public:
* \pre v is a redundant vertex.
* \return One of the pair of halfedges that form the merged edge.
*/
Halfedge* erase_redundant_vertex (Vertex *)
Halfedge* erase_redundant_vertex(Vertex*)
{
// This function should never be called:
CGAL_error();
return (NULL);
return NULL;
}
//! reference_face (const version).
@ -545,21 +514,15 @@ public:
point.
\return A pointer to the reference face.
*/
const Face* reference_face() const
{
return unbounded_face();
}
const Face* reference_face() const { return unbounded_face(); }
//! reference_face (non-const version).
/*! The function returns a reference face of the arrangement.
All reference faces of arrangements of the same type have a common
point.
\return A pointer to the reference face.
*/
Face* reference_face()
{
return unbounded_face();
}
Face* reference_face() { return unbounded_face(); }
//@}
@ -567,22 +530,18 @@ public:
//@{
/*! This function is used by the "walk" point-location strategy. */
const Face* initial_face () const
const Face* initial_face() const
{
return (unb_face);
}
/*! Get the unbounded face (const version). */
const Face* unbounded_face () const
{
return (unb_face);
}
const Face* unbounded_face() const
{ return (unb_face); }
/*! Get the unbounded face (non-const version). */
Face* unbounded_face ()
{
return (unb_face);
}
Face* unbounded_face()
{ return (unb_face); }
//@}
/// \name Additional predicates, specialized for this topology-traits class.
@ -594,11 +553,8 @@ public:
* \param v The vertex.
* \return The result of the comparison of the x-coordinates of p and v.
*/
virtual Comparison_result compare_x (const Point_2& p,
const Vertex* v) const
{
return (this->traits->compare_x_2_object() (p, v->point()));
}
virtual Comparison_result compare_x(const Point_2& p, const Vertex* v) const
{ return (this->m_geom_traits->compare_x_2_object()(p, v->point())); }
/*!
* Compare the given vertex and the given point.
@ -606,11 +562,8 @@ public:
* \param v The vertex.
* \return The result of the xy-lexicographic comparison of p and v.
*/
virtual Comparison_result compare_xy (const Point_2& p,
const Vertex* v) const
{
return (this->traits->compare_xy_2_object() (p, v->point()));
}
virtual Comparison_result compare_xy(const Point_2& p, const Vertex* v) const
{ return (this->m_geom_traits->compare_xy_2_object()(p, v->point())); }
/*!
* Compare the relative y-position of the given point and the given edge
@ -620,11 +573,9 @@ public:
* \pre p should lie in the x-range of the given edge.
* \return The relative y-position of the point p and the edge.
*/
virtual Comparison_result compare_y_at_x (const Point_2& p,
const Halfedge* he) const
{
return (this->traits->compare_y_at_x_2_object() (p, he->curve()));
}
virtual Comparison_result compare_y_at_x(const Point_2& p,
const Halfedge* he) const
{ return (this->m_geom_traits->compare_y_at_x_2_object()(p, he->curve())); }
//@}
};

View File

@ -14,7 +14,7 @@
//
// $URL$
// $Id$
//
//
//
// Author(s) : Idit Haran <haranidi@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
@ -46,7 +46,7 @@ namespace CGAL {
* Generator is a class that generates the set of landmarks.
*/
template <class Arrangement_,
template <class Arrangement_,
class Generator_ = Arr_landmarks_vertices_generator<Arrangement_> >
class Arr_landmarks_point_location
{
@ -105,10 +105,10 @@ protected:
template<typename T>
Result_type make_result(T t) const { return Result::make_result(t); }
inline Result_type default_result() const { return Result::default_result(); }
public:
/*! Default constructor. */
Arr_landmarks_point_location() :
Arr_landmarks_point_location() :
p_arr(NULL),
m_traits(NULL),
lm_gen(NULL),
@ -117,30 +117,29 @@ public:
/*! Constructor given an arrangement only. */
Arr_landmarks_point_location(const Arrangement_2& arr) :
p_arr(&arr)
{
// Allocate the landmarks generator.
m_traits = static_cast<const Traits_adaptor_2*>(p_arr->geometry_traits());
lm_gen = new Generator(arr);
own_gen = true;
}
p_arr(&arr),
m_traits(static_cast<const Traits_adaptor_2*>(p_arr->geometry_traits())),
lm_gen(new Generator(arr)), // allocate the landmarks generator.
own_gen(true)
{ }
/*! Constructor given an arrangement, and landmarks generator. */
Arr_landmarks_point_location(const Arrangement_2& arr, Generator *gen) :
Arr_landmarks_point_location(const Arrangement_2& arr, Generator* gen) :
p_arr(&arr),
m_traits(static_cast<const Traits_adaptor_2*>(p_arr->geometry_traits())),
lm_gen(gen),
own_gen(false)
{
m_traits = static_cast<const Traits_adaptor_2*>(p_arr->geometry_traits());
}
{ }
/*! Destructor. */
~Arr_landmarks_point_location()
~Arr_landmarks_point_location()
{
if (own_gen)
if (own_gen) {
delete lm_gen;
lm_gen = NULL;
}
}
/*! Attach an arrangement object (and a generator, if supplied). */
void attach(const Arrangement_2& arr, Generator* gen = NULL)
{
@ -158,8 +157,8 @@ public:
else if (lm_gen != NULL) {
// In case a generator exists internally, make sure it is attached to
// the given arrangement.
Arrangement_2 &non_const_arr = const_cast<Arrangement_2&>(*p_arr);
lm_gen->attach(non_const_arr);
Arrangement_2& non_const_arr = const_cast<Arrangement_2&>(*p_arr);
lm_gen->attach(non_const_arr);
}
else {
// Allocate a new generator, attached to the given arrangement.
@ -169,7 +168,7 @@ public:
}
/*! Detach the instance from the arrangement object. */
void detach()
void detach()
{
p_arr = NULL;
m_traits = NULL;
@ -178,7 +177,7 @@ public:
if (lm_gen)
lm_gen->detach();
}
/*!
* Locate the arrangement feature containing the given point.
* \param p The query point.
@ -189,9 +188,7 @@ public:
result_type locate(const Point_2& p) const;
protected:
/*!
* Walks from the given vertex to the query point.
/*! Walk from the given vertex to the query point.
* \param vh The given vertex handle.
* \param p The query point.
* \param crossed_edges In/Out: The set of edges crossed so far.
@ -200,11 +197,10 @@ protected:
* Halfedge_const_handle or a Vertex_const_handle.
*/
result_type _walk_from_vertex(Vertex_const_handle vh,
const Point_2 & p,
const Point_2& p,
Halfedge_set& crossed_edges) const;
/*!
* Locate an edge around a given vertex that is the predecessor of the
/*! Locate an edge around a given vertex that is the predecessor of the
* curve connecting the vertex to the query point in a clockwise order.
* \param vh The vertex.
* \param p The query point.
@ -212,11 +208,10 @@ protected:
* \return The desired object (a halfedge handle or a vertex handle).
*/
result_type _find_face_around_vertex(Vertex_const_handle vh,
const Point_2& p,
const Point_2& p,
bool& new_vertex) const;
/*!
* Walks from a point on a given halfedge to the query point.
/*! Walk from a point on a given halfedge to the query point.
* \param eh The given halfedge handle.
* \param np The point that the walk starts from.
* \param p The query point.
@ -226,11 +221,10 @@ protected:
* Halfedge_const_handle or a Vertex_const_handle.
*/
result_type _walk_from_edge(Halfedge_const_handle eh,
const Point_2& np,
const Point_2& np,
const Point_2& p,
Halfedge_set& crossed_edges) const;
/*!
* In case the arrangement's curve contained in the segment
/*! In case the arrangement's curve contained in the segment
* from the nearest landmark to the query point
* \param he The given halfedge handle.
* \param p_is_left Is the query point the left endpoint of seg.
@ -246,8 +240,7 @@ protected:
const Point_2& p,
Halfedge_set& crossed_edges) const;
/*!
* Walks from a point in a face to the query point.
/*! Walk from a point in a face to the query point.
* \param fh A halfedge handle that points to the face.
* \param np The point that the walk starts from.
* \param p The query point.
@ -257,12 +250,11 @@ protected:
* Halfedge_const_handle or a Vertex_const_handle.
*/
result_type _walk_from_face(Face_const_handle fh,
const Point_2 & np,
const Point_2 & p,
const Point_2& np,
const Point_2& p,
Halfedge_set& crossed_edges) const;
/*!
* Find a halfedge on the given CCB that intersects the given x-monotone
/*! Find a halfedge on the given CCB that intersects the given x-monotone
* curve, connecting the current landmark to the query point.
* \param circ The CCB circulator.
* \param seg The segment connecting the landmark and the query point.
@ -287,8 +279,7 @@ protected:
bool& cv_is_contained_in_seg,
Vertex_const_handle& new_vertex) const;
/*!
* Return the halfedge that contains the query point.
/*! Return the halfedge that contains the query point.
* \param he The halfedge handle.
* \param crossed_edges In/Out: The set of edges crossed so far.
* \param p The query point.
@ -300,8 +291,7 @@ protected:
const Point_2& p,
bool& is_target) const;
/*!
* Check whether the given curve intersects a simple segment, which connects
/*! Check whether the given curve intersects a simple segment, which connects
* the current landmark to the query point, an odd number of times.
* \param cv The curve.
* \param seg The segment connecting the landmark and the query point.

View File

@ -1,4 +1,4 @@
// Copyright (c) 2006,2007,2009,2010,2011 Tel-Aviv University (Israel).
// Copyright (c) 2006,2007,2009,2010,2011,2013 Tel-Aviv University (Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
@ -636,17 +636,17 @@ public:
public:
Comparison_result operator()(const Point_2 & p1, const Point_2 & p2) const
{
return m_base->compare_x_on_boundary_2_object()(p1.base(), p2.base());
return m_base->compare_y_on_boundary_2_object()(p1.base(), p2.base());
}
Comparison_result operator() (const Point_2 & pt,
const X_monotone_curve_2& xcv, Arr_curve_end ce) const
{
return m_base->compare_x_on_boundary_2_object()(pt.base(), xcv.base(), ce);
return m_base->compare_y_on_boundary_2_object()(pt.base(), xcv.base(), ce);
}
Comparison_result operator() (const X_monotone_curve_2& xcv1, Arr_curve_end ce1,
const X_monotone_curve_2& xcv2, Arr_curve_end ce2) const
{
return m_base->compare_x_on_boundary_2_object()(xcv1.base(), ce1, xcv2.base(), ce2);
return m_base->compare_y_on_boundary_2_object()(xcv1.base(), ce1, xcv2.base(), ce2);
}
};

View File

@ -18,8 +18,8 @@
// Author(s) : Idit Haran <haranidi@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
#ifndef CGAL_ARR_LANDMARKS_GENERATOR_H
#define CGAL_ARR_LANDMARKS_GENERATOR_H
#ifndef CGAL_ARR_LANDMARKS_GENERATOR_BASE_H
#define CGAL_ARR_LANDMARKS_GENERATOR_BASE_H
/*! \file
* Definition of the Arr_landmarks_generator_base<Arrangement> template.
@ -87,70 +87,71 @@ protected:
typedef Arr_traits_basic_adaptor_2<Geometry_traits_2> Traits_adaptor_2;
// Data members:
const Traits_adaptor_2 *m_traits; // The associated traits object.
Nearest_neighbor nn; // The associated nearest neighbor object.
bool ignore_notifications;
bool updated;
int num_small_not_updated_changes;
const Traits_adaptor_2* m_traits; // The associated traits object.
Nearest_neighbor nn; // The associated nearest neighbor object.
bool m_ignore_notifications;
bool m_ignore_remove_edge;
bool updated;
int num_small_not_updated_changes;
template<typename T>
PL_result_type pl_make_result(T t) { return PL_result::make_result(t); }
inline PL_result_type pl_default_result() { return PL_result::default_result(); }
inline PL_result_type pl_default_result()
{ return PL_result::default_result(); }
public:
bool is_empty() const { return nn.is_empty(); }
private:
/*! Copy constructor - not supported. */
Arr_landmarks_generator_base (const Self& );
Arr_landmarks_generator_base(const Self&);
/*! Assignment operator - not supported. */
Self& operator= (const Self& );
Self& operator=(const Self& );
public:
/*! Constructor. */
Arr_landmarks_generator_base (const Arrangement_2& arr) :
/*! Constructor from an arrangement.
* \param arr (in) The arrangement.
*/
Arr_landmarks_generator_base(const Arrangement_2& arr) :
Arr_observer<Arrangement_2> (const_cast<Arrangement_2 &>(arr)),
ignore_notifications (false),
updated (false),
m_traits(static_cast<const Traits_adaptor_2*>(arr.geometry_traits())),
m_ignore_notifications(false),
m_ignore_remove_edge(false),
updated(false),
num_small_not_updated_changes(0)
{
m_traits = static_cast<const Traits_adaptor_2*> (arr.geometry_traits());
// One needs to call build_landmark_set() in the constructor of any
// inherited class.
}
/*!
* Creates the landmarks set (choosing the landmarks) ,
/*! Create the landmarks set (choosing the landmarks) ,
* and saving them in the nearest-neighbor search structure.
*/
virtual void build_landmark_set ()
virtual void build_landmark_set()
{
// Create the landmark points.
NN_Points_set nn_points;
NN_Points_set nn_points;
_create_nn_points_set(nn_points);
// Update the search structure.
nn.clear();
nn.init (nn_points.begin(), nn_points.end());
nn.init(nn_points.begin(), nn_points.end());
num_small_not_updated_changes = 0;
updated = true;
}
/*!
* clear the set of landmarks.
/*! clear the set of landmarks.
*/
virtual void clear_landmark_set ()
virtual void clear_landmark_set()
{
nn.clear();
num_small_not_updated_changes = 0;
updated = false;
}
/*!
* Get the nearest neighbor (landmark) to the given point.
/*! Obtain the nearest neighbor (landmark) to the given point.
* \param p The query point.
* \param obj Output: The location of the nearest landmark point in the
* arrangement (a vertex, halfedge, or face handle).
@ -170,208 +171,295 @@ public:
* arrangement.
* \param arr The arrangement to be copied.
*/
virtual void before_assign (const Arrangement_2& arr)
virtual void before_assign(const Arrangement_2& arr)
{
this->clear_landmark_set();
m_traits = static_cast<const Traits_adaptor_2*> (arr.geometry_traits());
ignore_notifications = true;
m_traits = static_cast<const Traits_adaptor_2*>(arr.geometry_traits());
m_ignore_notifications = true;
}
/*!
* Notification after the arrangement has been assigned with another
/*! Notification after the arrangement has been assigned with another
* arrangement.
*/
virtual void after_assign ()
virtual void after_assign()
{
this->build_landmark_set();
ignore_notifications = false;
m_ignore_notifications = false;
}
/*!
* Notification before the observer is attached to an arrangement.
/*! Notification before the observer is attached to an arrangement.
* \param arr The arrangement we are about to attach the observer to.
*/
virtual void before_attach (const Arrangement_2& arr)
virtual void before_attach(const Arrangement_2& arr)
{
this->clear_landmark_set();
m_traits = static_cast<const Traits_adaptor_2*> (arr.geometry_traits());
ignore_notifications = true;
m_traits = static_cast<const Traits_adaptor_2*>(arr.geometry_traits());
m_ignore_notifications = true;
}
/*!
* Notification after the observer has been attached to an arrangement.
/*! Notification after the observer has been attached to an arrangement.
*/
virtual void after_attach ()
virtual void after_attach()
{
this->build_landmark_set();
ignore_notifications = false;
m_ignore_notifications = false;
}
/*!
* Notification before the observer is detached from the arrangement.
/*! Notification before the observer is detached from the arrangement.
*/
virtual void before_detach ()
{
this->clear_landmark_set();
}
virtual void before_detach()
{ this->clear_landmark_set(); }
/*!
* Notification after the arrangement is cleared.
/*! Notification after the arrangement is cleared.
* \param u A handle to the unbounded face.
*/
virtual void after_clear ()
virtual void after_clear()
{
this->clear_landmark_set();
this->build_landmark_set();
}
/*! Notification before a global operation modifies the arrangement. */
virtual void before_global_change ()
/*! Notification before a global operation modifies the arrangement.
*/
virtual void before_global_change()
{
this->clear_landmark_set();
ignore_notifications = true;
m_ignore_notifications = true;
}
/*! Notification after a global operation is completed. */
virtual void after_global_change ()
/*! Notification after a global operation is completed.
*/
virtual void after_global_change()
{
this->build_landmark_set();
ignore_notifications = false;
m_ignore_notifications = false;
}
//@}
/// \name Overloaded observer functions on local changes.
//@{
/*! Notification before the removal of an edge.
* \param e (in) A handle to one of the twin halfedges to be removed.
*/
virtual void before_remove_edge(Halfedge_handle /* e */)
{ m_ignore_remove_edge = true; }
/*! Notification after the creation of a new vertex. */
virtual void after_create_vertex (Vertex_handle )
virtual void after_create_vertex(Vertex_handle)
{
this->_handle_local_change_notification();
}
/*! Notification after the creation of a new edge. */
virtual void after_create_edge (Halfedge_handle )
{ this->_handle_local_change_notification(); }
/*! Notification after an edge was split. */
virtual void after_split_edge(Halfedge_handle, Halfedge_handle)
{ this->_handle_local_change_notification(); }
/*! Notification after a face was split. */
virtual void after_split_face(Face_handle, Face_handle, bool)
{ this->_handle_local_change_notification(); }
/*! Notification after an outer CCB was split.*/
virtual void after_split_outer_ccb (Face_handle ,
Ccb_halfedge_circulator ,
Ccb_halfedge_circulator )
{ this->_handle_local_change_notification(); }
/*! Notification after an inner CCB was split. */
virtual void after_split_inner_ccb (Face_handle ,
Ccb_halfedge_circulator ,
Ccb_halfedge_circulator )
{ this->_handle_local_change_notification(); }
/*! Notification after an outer CCB was added to a face. */
virtual void after_add_outer_ccb (Ccb_halfedge_circulator )
{
this->_handle_local_change_notification();
}
/*! Notification after an inner CCB was created inside a face. */
virtual void after_add_inner_ccb (Ccb_halfedge_circulator )
{ this->_handle_local_change_notification(); }
/*! Notification after an isolated vertex was created inside a face. */
virtual void after_add_isolated_vertex (Vertex_handle )
{ this->_handle_local_change_notification(); }
/*! Notification after an edge was merged. */
virtual void after_merge_edge (Halfedge_handle )
{ this->_handle_local_change_notification(); }
/*! Notification after a face was merged. */
virtual void after_merge_face (Face_handle )
{ this->_handle_local_change_notification(); }
/*! Notification after an outer CCB was merged. */
virtual void after_merge_outer_ccb(Face_handle, Ccb_halfedge_circulator)
{ this->_handle_local_change_notification(); }
/*! Notification after an inner CCB was merged. */
virtual void after_merge_inner_ccb(Face_handle, Ccb_halfedge_circulator)
{ this->_handle_local_change_notification(); }
/*! Notification after an outer CCB is moved from one face to another. */
virtual void after_move_outer_ccb (Ccb_halfedge_circulator )
{ this->_handle_local_change_notification(); }
/*! Notification after an inner CCB is moved from one face to another. */
virtual void after_move_inner_ccb (Ccb_halfedge_circulator )
{ this->_handle_local_change_notification(); }
/*! Notification after an isolated vertex is moved. */
virtual void after_move_isolated_vertex (Vertex_handle )
{ this->_handle_local_change_notification(); }
/*! Notificaion after the removal of a vertex. */
virtual void after_remove_vertex ()
{ this->_handle_local_change_notification(); }
/*! Notification after the removal of an edge. */
virtual void after_remove_edge ()
{ this->_handle_local_change_notification(); }
/*! Notificaion after the removal of an outer CCB. */
virtual void after_remove_outer_ccb (Face_handle )
{ this->_handle_local_change_notification(); }
/*! Notificaion after the removal of an inner CCB. */
virtual void after_remove_inner_ccb (Face_handle )
{ this->_handle_local_change_notification(); }
//@}
protected:
/*! Handle a change notification. */
void _handle_local_change_notification ()
{
if (! ignore_notifications) {
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
}
}
/*!
* This function creates the list of landmarks with their location.
/*! Notification after the creation of a new edge. */
virtual void after_create_edge(Halfedge_handle)
{
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notification after an edge was split. */
virtual void after_split_edge(Halfedge_handle, Halfedge_handle)
{
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notification after a face was split. */
virtual void after_split_face(Face_handle, Face_handle, bool)
{
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notification after an outer CCB was split.*/
virtual void after_split_outer_ccb(Face_handle,
Ccb_halfedge_circulator,
Ccb_halfedge_circulator)
{
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notification after an inner CCB was split. */
virtual void after_split_inner_ccb(Face_handle,
Ccb_halfedge_circulator,
Ccb_halfedge_circulator)
{
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notification after an outer CCB was added to a face. */
virtual void after_add_outer_ccb(Ccb_halfedge_circulator)
{
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notification after an inner CCB was created inside a face. */
virtual void after_add_inner_ccb(Ccb_halfedge_circulator)
{
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notification after an isolated vertex was created inside a face. */
virtual void after_add_isolated_vertex(Vertex_handle)
{
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notification after an edge was merged. */
virtual void after_merge_edge(Halfedge_handle)
{
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notification after a face was merged. */
virtual void after_merge_face(Face_handle)
{
if (! m_ignore_notifications && ! m_ignore_remove_edge) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notification after an outer CCB was merged. */
virtual void after_merge_outer_ccb(Face_handle, Ccb_halfedge_circulator)
{
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notification after an inner CCB was merged. */
virtual void after_merge_inner_ccb(Face_handle, Ccb_halfedge_circulator)
{
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notification after an outer CCB is moved from one face to another. */
virtual void after_move_outer_ccb(Ccb_halfedge_circulator )
{
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notification after an inner CCB is moved from one face to another. */
virtual void after_move_inner_ccb(Ccb_halfedge_circulator )
{
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notification after an isolated vertex is moved. */
virtual void after_move_isolated_vertex(Vertex_handle )
{
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notificaion after the removal of a vertex. */
virtual void after_remove_vertex()
{
if (! m_ignore_notifications && ! m_ignore_remove_edge) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notification after the removal of an edge. */
virtual void after_remove_edge()
{
if (! m_ignore_notifications) {
clear_landmark_set();
build_landmark_set();
}
m_ignore_remove_edge = false;
}
/*! Notificaion after the removal of an outer CCB. */
virtual void after_remove_outer_ccb(Face_handle)
{
if (! m_ignore_notifications && ! m_ignore_remove_edge) {
clear_landmark_set();
build_landmark_set();
}
}
/*! Notificaion after the removal of an inner CCB. */
virtual void after_remove_inner_ccb(Face_handle)
{
if (! m_ignore_notifications && ! m_ignore_remove_edge) {
clear_landmark_set();
build_landmark_set();
}
}
//@}
protected:
/*! Create the list of landmarks with their location.
* This is a pure virtual function, and the class that inherites from
* this generator must implement it.
*/
virtual void _create_points_set (Points_set &) = 0;
virtual void _create_points_set(Points_set&) = 0;
virtual void _create_nn_points_set (NN_Points_set &nn_points)
virtual void _create_nn_points_set(NN_Points_set& nn_points)
{
Points_set points;
Pairs_set pairs;
Points_set points;
Pairs_set pairs;
// Create the set of landmark points.
_create_points_set(points);
// Locate the landmarks in the arrangement using batched point-location
// global function.
locate (*(this->arrangement()), points.begin(), points.end(),
std::back_inserter(pairs));
locate(*(this->arrangement()), points.begin(), points.end(),
std::back_inserter(pairs));
// Apply a random shuffle on the points, since the batched point-location
// returns them sorted.
std::random_shuffle (pairs.begin(), pairs.end());
std::random_shuffle(pairs.begin(), pairs.end());
// Insert all landmarks (paired with their current location in the
// arrangement) into the nearest-neighbor search structure.
Pairs_iterator itr;
Pairs_iterator itr;
for (itr = pairs.begin(); itr != pairs.end(); ++itr) {
NN_Point_2 np(itr->first, itr->second);
NN_Point_2 np(itr->first, itr->second);
nn_points.push_back(np);
}
}

View File

@ -17,8 +17,9 @@
//
// Author(s) : Idit Haran <haranidi@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
#ifndef CGAL_ARR_LM_GRID_GENERATOR_H
#define CGAL_ARR_LM_GRID_GENERATOR_H
#ifndef CGAL_ARR_LANDMARKS_GRID_GENERATOR_H
#define CGAL_ARR_LANDMARKS_GRID_GENERATOR_H
/*! \file
* Definition of the Arr_grid_landmarks_generator<Arrangement> template.
@ -73,17 +74,17 @@ protected:
typedef Arr_traits_basic_adaptor_2<Geometry_traits_2> Traits_adaptor_2;
// Data members:
const Traits_adaptor_2* m_traits;
unsigned int num_landmarks;
Pairs_set lm_pairs;
const Traits_adaptor_2* m_traits;
unsigned int num_landmarks;
Pairs_set lm_pairs;
ANT x_min, y_min; // Bounding box for the
ANT x_max, y_max; // arrangement vertices.
ANT step_x, step_y; // Grid step sizes.
unsigned int sqrt_n;
ANT x_min, y_min; // Bounding box for the
ANT x_max, y_max; // arrangement vertices.
ANT step_x, step_y; // Grid step sizes.
unsigned int sqrt_n;
bool fixed_number_of_lm; // indicates if the constructor got
// number of landmarks as parameter
bool fixed_number_of_lm; // indicates if the constructor got
// number of landmarks as parameter
private:
/*! Copy constructor - not supported. */
@ -93,34 +94,35 @@ private:
Self& operator=(const Self&);
public:
/*! Constructor. */
/*! Constructor from an arrangement.
* \param arr (in) The arrangement.
*/
Arr_grid_landmarks_generator(const Arrangement_2& arr) :
Base(arr),
m_traits(static_cast<const Traits_adaptor_2*>(arr.geometry_traits())),
num_landmarks(0),
fixed_number_of_lm(false)
{
m_traits = static_cast<const Traits_adaptor_2*>(arr.geometry_traits());
build_landmark_set();//this->
}
Arr_grid_landmarks_generator(const Arrangement_2& arr,
unsigned int n_landmarks) :
Base(arr),
m_traits(static_cast<const Traits_adaptor_2*>(arr.geometry_traits())),
num_landmarks(n_landmarks),
fixed_number_of_lm(true)
{
m_traits = static_cast<const Traits_adaptor_2*>(arr.geometry_traits());
build_landmark_set();//this->
}
/*!
* Create the landmarks set (choosing the landmarks),
/*! Create the landmarks set (choosing the landmarks),
* and store them in the nearest neighbor search structure.
*/
virtual void build_landmark_set()
{
// Create a set of points on a grid.
Points_set points;
Points_set points;
_create_points_set(points);
// Locate the landmarks in the arrangement using batched point-location
// global function. Note that the resulting pairs are returned sorted by
@ -131,8 +133,7 @@ public:
this->updated = true;
}
/*!
* Clear the set of landmarks.
/*! Clear the set of landmarks.
*/
virtual void clear_landmark_set()
{
@ -140,11 +141,10 @@ public:
this->updated = false;
}
/*!
* Get the nearest neighbor (landmark) to the given point.
/*! Obtain the nearest neighbor (landmark) to the given point.
* \param q The query point.
* \param obj Output: The location of the nearest landmark point in the
* arrangement (a vertex, halfedge, or face handle).
* \param obj (out) The location of the nearest landmark point in the
* arrangement (a vertex, halfedge, or face handle).
* \return The nearest landmark point.
*/
virtual Point_2 closest_landmark(const Point_2& q, PL_result_type& obj)
@ -152,26 +152,17 @@ public:
CGAL_assertion(this->updated);
// Calculate the index of the nearest grid point point to q.
const ANT qx = m_traits->approximate_2_object()(q, 0);
const ANT qy = m_traits->approximate_2_object()(q, 1);
unsigned int i, j;
unsigned int index;
if (CGAL::compare(qx, x_min) == SMALLER)
i = 0;
else if (CGAL::compare(qx, x_max) == LARGER)
i = sqrt_n - 1;
else
i = static_cast<int>(((qx - x_min) / step_x) + 0.5);
if (CGAL::compare(qy, y_min) == SMALLER)
j = 0;
else if (CGAL::compare(qy, y_max) == LARGER)
j = sqrt_n - 1;
else
j = static_cast<int>(((qy - y_min) / step_y) + 0.5);
index = sqrt_n * i + j;
typename Geometry_traits_2::Approximate_2 approximate =
m_traits->approximate_2_object();
const ANT qx = approximate(q, 0);
const ANT qy = approximate(q, 1);
unsigned int i = (CGAL::compare(qx, x_min) == SMALLER) ? 0 :
(CGAL::compare(qx, x_max) == LARGER) ? (sqrt_n - 1) :
static_cast<int>(((qx - x_min) / step_x) + 0.5);
unsigned int j = (CGAL::compare(qy, y_min) == SMALLER) ? 0 :
(CGAL::compare(qy, y_max) == LARGER) ? (sqrt_n - 1) :
static_cast<int>(((qy - y_min) / step_y) + 0.5);
unsigned int index = sqrt_n * i + j;
// Return the result.
obj = lm_pairs[index].second;
@ -179,8 +170,7 @@ public:
}
protected:
/*!
* Create a set of landmark points on a grid.
/*! Create a set of landmark points on a grid.
*/
virtual void _create_points_set(Points_set& points)
{
@ -203,34 +193,29 @@ protected:
return;
}
ANT x, y;
Vertex_const_iterator left, right, top, bottom;
ANT x, y;
Vertex_const_iterator left, right, top, bottom;
left = right = top = bottom = vit;
for (++vit; vit != arr->vertices_end(); ++vit)
{
for (++vit; vit != arr->vertices_end(); ++vit) {
x = m_traits->approximate_2_object()(vit->point(), 0);
y = m_traits->approximate_2_object()(vit->point(), 1);
if (CGAL::compare(x, x_min) == SMALLER)
{
if (CGAL::compare(x, x_min) == SMALLER) {
x_min = x;
left = vit;
}
else if (CGAL::compare(x, x_max) == LARGER)
{
else if (CGAL::compare(x, x_max) == LARGER) {
x_max = x;
right = vit;
}
if (CGAL::compare(y, y_min) == SMALLER)
{
if (CGAL::compare(y, y_min) == SMALLER) {
y_min = y;
bottom = vit;
}
else if (CGAL::compare(y, y_max) == LARGER)
{
else if (CGAL::compare(y, y_max) == LARGER) {
y_max = y;
top = vit;
}
@ -249,20 +234,15 @@ protected:
CGAL_assertion(sqrt_n > 1);
// Calculate the step sizes for the grid.
ANT delta_x = m_traits->approximate_2_object()(right->point(), 0) -
m_traits->approximate_2_object()(left->point(), 0);
ANT delta_y = m_traits->approximate_2_object()(top->point(), 1) -
m_traits->approximate_2_object()(bottom->point(), 1);
if (CGAL::sign(delta_x) == CGAL::ZERO)
delta_x = delta_y;
if (CGAL::sign(delta_y) == CGAL::ZERO)
delta_y = delta_x;
ANT delta_x = m_traits->approximate_2_object()(right->point(), 0) -
m_traits->approximate_2_object()(left->point(), 0);
ANT delta_y = m_traits->approximate_2_object()(top->point(), 1) -
m_traits->approximate_2_object()(bottom->point(), 1);
if (CGAL::sign(delta_x) == CGAL::ZERO) delta_x = delta_y;
if (CGAL::sign(delta_y) == CGAL::ZERO) delta_y = delta_x;
CGAL_assertion((CGAL::sign(delta_x) == CGAL::POSITIVE) &&
(CGAL::sign(delta_y) == CGAL::POSITIVE));
step_x = delta_x / (sqrt_n - 1);
step_y = delta_y / (sqrt_n - 1);

View File

@ -17,8 +17,9 @@
//
// Author(s) : Idit Haran <haranidi@post.tau.ac.il>
// Ron Wein <haranidi@post.tau.ac.il>
#ifndef CGAL_ARR_LM_HALTON_GENERATOR_H
#define CGAL_ARR_LM_HALTON_GENERATOR_H
#ifndef CGAL_ARR_LANDMARKS_HALTON_GENERATOR_H
#define CGAL_ARR_LANDMARKS_HALTON_GENERATOR_H
/*! \file
* Definition of the Arr_halton_landmarks_generator<Arrangement> template.
@ -55,7 +56,7 @@ public:
protected:
// Data members:
unsigned int num_landmarks;
unsigned int num_landmarks;
private:
/*! Copy constructor - not supported. */
@ -64,10 +65,12 @@ private:
/*! Assignment operator - not supported. */
Self& operator=(const Self&);
public:
/*! Constructor. */
public:
/*! Constructor from an arrangement.
* \param arr (in) The arrangement.
*/
Arr_halton_landmarks_generator(const Arrangement_2& arr,
unsigned int n_landmarks = 0) :
unsigned int n_landmarks = 0) :
Base(arr),
num_landmarks(n_landmarks)
{ this->build_landmark_set(); }
@ -79,18 +82,18 @@ protected:
* The Halton points are constructed in the bounding rectangle of the
* arrangement vertices.
*/
virtual void _create_points_set (Points_set& points)
virtual void _create_points_set(Points_set& points)
{
points.clear();
// Go over the arrangement vertices and construct their boundig box.
const Arrangement_2* arr = this->arrangement();
Vertex_const_iterator vit;
Vertex_const_iterator vit;
double x_min = 0, x_max = 1, y_min = 0, y_max = 1;
double x, y;
bool first = true;
for (vit=arr->vertices_begin(); vit != arr->vertices_end(); ++vit) {
for (vit = arr->vertices_begin(); vit != arr->vertices_end(); ++vit) {
x = CGAL::to_double(vit->point().x());
y = CGAL::to_double(vit->point().y());
@ -100,15 +103,11 @@ protected:
first = false;
}
else {
if (x < x_min)
x_min = x;
else if (x > x_max)
x_max = x;
if (x < x_min) x_min = x;
else if (x > x_max) x_max = x;
if (y < y_min)
y_min = y;
else if (y > y_max)
y_max = y;
if (y < y_min) y_min = y;
else if (y > y_max) y_max = y;
}
}
@ -117,11 +116,10 @@ protected:
if (num_landmarks == 0)
num_landmarks = static_cast<unsigned int>(arr->number_of_vertices());
if (num_landmarks == 0)
return;
if (num_landmarks == 0) return;
if (num_landmarks == 1) {
points.push_back (Point_2 (x_max, y_max));
points.push_back (Point_2 (x_max, y_max));
return;
}

View File

@ -17,8 +17,9 @@
//
//
// Author(s) : Idit Haran <haranidi@post.tau.ac.il>
#ifndef CGAL_ARR_LM_MIDDLE_EDGES_GENERATOR_H
#define CGAL_ARR_LM_MIDDLE_EDGES_GENERATOR_H
#ifndef CGAL_ARR_LANDMARKS_MIDDLE_EDGES_GENERATOR_H
#define CGAL_ARR_LANDMARKS_MIDDLE_EDGES_GENERATOR_H
/*! \file
* Definition of the Arr_middle_edges_landmarks_generator<Arrangement> template.
@ -81,7 +82,10 @@ private:
Self& operator=(const Self&);
public:
/*! Constructor. */
/*! Constructor from an arrangement.
* \param arr(in) The arrangement.
* \param lm_num(in)
*/
Arr_middle_edges_landmarks_generator(const Arrangement_2& arr,
int /* lm_num */ = -1) :
Base(arr)
@ -93,20 +97,19 @@ public:
// Observer functions that should be empty, because they
// got nothing to do with middle edges
//-------------------------------------------------
virtual void after_create_vertex (Vertex_handle /* v */) {}
virtual void after_split_face (Face_handle /* f */,
Face_handle /* new_f */, bool /* is_hole */)
virtual void after_create_vertex(Vertex_handle /* v */) {}
virtual void after_split_face(Face_handle /* f */,
Face_handle /* new_f */, bool /* is_hole */)
{}
virtual void after_add_hole (Ccb_halfedge_circulator /* h */) {}
virtual void after_add_hole(Ccb_halfedge_circulator /* h */) {}
virtual void after_merge_face (Face_handle /* f */) {}
virtual void after_move_hole (Ccb_halfedge_circulator /* h */) {}
virtual void after_remove_vertex () {}
virtual void after_remove_hole (Face_handle /* f */) {}
virtual void after_merge_face(Face_handle /* f */) {}
virtual void after_move_hole(Ccb_halfedge_circulator /* h */) {}
virtual void after_remove_vertex() {}
virtual void after_remove_hole(Face_handle /* f */) {}
protected:
/*!
* create a set of middle_edges points
/*! Create a set of middle_edges points
* the number of points is equal to the number of edges in the arrangement.
*/
virtual void _create_nn_points_set(NN_Points_set& nn_points)
@ -116,12 +119,11 @@ protected:
Halfedge_const_handle hh;
Arrangement_2* arr = this->arrangement();
if (arr->number_of_vertices() == 1)
{
if (arr->number_of_vertices() == 1) {
//special treatment for arrangement with one isolated verrtex
Vertex_const_iterator vit = arr->vertices_begin();
PL_result_type obj = this->pl_make_result(vit);
Point_2 p (vit->point());
Point_2 p(vit->point());
NN_Point_2 np(p, obj);
nn_points.push_back(np);
@ -132,7 +134,7 @@ protected:
hh = eit;
const Point_2& p1 = hh->source()->point();
const Point_2& p2 = hh->target()->point();
Point_2 p ((p1.x()+p2.x())/2, (p1.y()+p2.y())/2);
Point_2 p((p1.x()+p2.x())/2, (p1.y()+p2.y())/2);
//CGAL_PRINT_DEBUG("mid point is= " << p);
@ -142,9 +144,9 @@ protected:
}
}
virtual void _create_points_set (Points_set & /* points */)
virtual void _create_points_set(Points_set& /* points */)
{
std::cerr << "should not reach here!"<< std::endl;
std::cerr << "should not reach here!" << std::endl;
CGAL_error();
}
};

View File

@ -14,11 +14,12 @@
//
// $URL$
// $Id$
//
//
// Author(s) : Idit Haran <haranidi@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
#ifndef CGAL_ARR_LM_RANDOM_GENERATOR_H
#define CGAL_ARR_LM_RANDOM_GENERATOR_H
#ifndef CGAL_ARR_LANDMARKS_RANDOM_GENERATOR_H
#define CGAL_ARR_LANDMARKS_RANDOM_GENERATOR_H
/*! \file
* Definition of the Arr_random_landmarks_generator<Arrangement> template.
@ -57,40 +58,41 @@ public:
protected:
// Data members:
unsigned int num_landmarks;
unsigned int num_landmarks;
private:
/*! Copy constructor - not supported. */
Arr_random_landmarks_generator (const Self& );
Arr_random_landmarks_generator(const Self&);
/*! Assignment operator - not supported. */
Self& operator= (const Self& );
Self& operator=(const Self&);
public:
/*! Constructor. */
Arr_random_landmarks_generator (const Arrangement_2& arr,
unsigned int n_landmarks = 0) :
Base (arr),
num_landmarks (n_landmarks)
public:
/*! Constructor from an arrangement.
* \param arr (in) The arrangement.
*/
Arr_random_landmarks_generator(const Arrangement_2& arr,
unsigned int n_landmarks = 0) :
Base(arr),
num_landmarks(n_landmarks)
{ this->build_landmark_set(); }
protected:
/*!
* Create a set of random points (the number of points is given as a
/*! Create a set of random points (the number of points is given as a
* parameter to the constructor, or is taken from the arrangement size).
* The coordinates of the landmarks are selected randomly in the
* bounding rectangle of the Arrangement's vertices
* bounding rectangle of the Arrangement's vertices
*/
virtual void _create_points_set (Points_set& points)
virtual void _create_points_set(Points_set& points)
{
points.clear();
// Go over the arrangement vertices and construct their boundig box.
const Arrangement_2 *arr = this->arrangement();
Vertex_const_iterator vit;
double x_min = 0, x_max = 1, y_min = 0, y_max = 1;
double x, y;
bool first = true;
const Arrangement_2* arr = this->arrangement();
Vertex_const_iterator vit;
double x_min = 0, x_max = 1, y_min = 0, y_max = 1;
double x, y;
bool first = true;
for (vit=arr->vertices_begin(); vit != arr->vertices_end(); ++vit) {
x = CGAL::to_double(vit->point().x());
@ -102,15 +104,11 @@ protected:
first = false;
}
else {
if (x < x_min)
x_min = x;
else if (x > x_max)
x_max = x;
if (x < x_min) x_min = x;
else if (x > x_max) x_max = x;
if (y < y_min)
y_min = y;
else if (y > y_max)
y_max = y;
if (y < y_min) y_min = y;
else if (y > y_max) y_max = y;
}
}
@ -123,10 +121,9 @@ protected:
for (unsigned int i = 0; i < num_landmarks; ++i) {
double px = (x_min == x_max) ? x_min : random.get_double(x_min, x_max);
double py = (y_min == y_max) ? y_min : random.get_double(y_min, y_max);
points.push_back(Point_2 (px, py));
points.push_back(Point_2(px, py));
}
}
};
} //namespace CGAL

View File

@ -14,11 +14,11 @@
//
// $URL$
// $Id$
//
//
// Author(s) : Shlomo Golubev <golubevs@post.tau.ac.il>
#ifndef CGAL_ARR_SPECIFIED_POINTS_GENERATOR_H
#define CGAL_ARR_SPECIFIED_POINTS_GENERATOR_H
#ifndef CGAL_ARR_LANDMARKS_SPECIFIED_POINTS_GENERATOR_H
#define CGAL_ARR_LANDMARKS_SPECIFIED_POINTS_GENERATOR_H
/*! \file
* Definition of the Arr_lm_specified_points_generator<Arrangement> template.
@ -65,7 +65,7 @@ public:
typedef typename Nearest_neighbor::NN_Point_2 NN_Point_2;
typedef std::list<NN_Point_2> NN_Point_list;
protected:
typedef Arr_traits_basic_adaptor_2<Geometry_traits_2> Traits_adaptor_2;
typedef typename Base::PL_result_type PL_result_type;
@ -85,26 +85,28 @@ private:
/*! Assignment operator - not supported. */
Self& operator=(const Self&);
public:
/*! Constructor. */
public:
/*! Constructor.
* Create landmarks in the points that are given to it.
*/
Arr_landmarks_specified_points_generator(const Arrangement_2& arr,
const Points_set points) :
Base(arr),
m_traits(static_cast<const Traits_adaptor_2*>(arr.geometry_traits())),
m_points(points),
num_landmarks(points.size())
{
//this constructor creates landmarks in the points that are given to it
m_traits = static_cast<const Traits_adaptor_2*>(arr.geometry_traits());
m_points = points;
build_landmark_set();
}
{ build_landmark_set(); }
/*! Constructor. from an arrangement.
* \param arr (in) The arrangement.
*/
Arr_landmarks_specified_points_generator(const Arrangement_2& arr) :
Base(arr)
Base(arr),
m_traits(static_cast<const Traits_adaptor_2*> (arr.geometry_traits())),
num_landmarks(1)
{
//this constructor creates a single landmark in the origin
m_points.push_back(Point_2(0,0));
num_landmarks = 1;
m_traits = static_cast<const Traits_adaptor_2*> (arr.geometry_traits());
build_landmark_set();
}
@ -114,28 +116,24 @@ public:
CGAL_error();
}
/*!
* Creates the landmark set, using all arrangement vertices.
/*! Create the landmark set, using all arrangement vertices.
*/
void build_landmark_set()
{
lm_pairs.clear();
locate (*(this->arrangement()), m_points.begin(), m_points.end(),
std::back_inserter(lm_pairs));
locate(*(this->arrangement()), m_points.begin(), m_points.end(),
std::back_inserter(lm_pairs));
// Go over the container of the specified points and insert them as
// landmarks.
NN_Point_list nnp_list;
NN_Point_list nnp_list;
typename Points_set::iterator pt_it;
typename Pairs_set::iterator pairs_it;
for (pt_it = m_points.begin(); pt_it != m_points.end(); ++pt_it)
{
for (pt_it = m_points.begin(); pt_it != m_points.end(); ++pt_it) {
for (pairs_it = lm_pairs.begin();
pairs_it != lm_pairs.end() && (*pairs_it).first != (*pt_it);
++pairs_it) {};
if ((*pairs_it).first == (*pt_it))
{
if ((*pairs_it).first == (*pt_it)) {
nnp_list.push_back (NN_Point_2 ((*pt_it),(*pairs_it).second));
}
}

View File

@ -14,7 +14,7 @@
//
// $URL$
// $Id$
//
//
// Author(s) : Idit Haran <haranidi@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
#ifndef CGAL_ARR_LANDMARKS_VERTICES_GENERATOR_H
@ -57,7 +57,7 @@ public:
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
typedef typename Arrangement_2::Face_handle Face_handle;
typedef typename Arrangement_2::Vertex_const_iterator Vertex_const_iterator;
typedef typename Arrangement_2::Point_2 Point_2;
typedef typename Arrangement_2::X_monotone_curve_2 X_monotone_curve_2;
@ -81,28 +81,29 @@ private:
Self& operator=(const Self&);
public:
/*! Constructor. */
/*! Constructor from an arrangement.
* \param arr (in) The arrangement.
*/
Arr_landmarks_vertices_generator(const Arrangement_2& arr) :
Base (arr),
Base(arr),
num_landmarks(0)
{
m_traits = static_cast<const Traits_adaptor_2*> (arr.geometry_traits());
m_traits = static_cast<const Traits_adaptor_2*>(arr.geometry_traits());
build_landmark_set();//this->
}
virtual void _create_points_set(Points_set & /* points */)
{
std::cerr << "should not reach here!"<< std::endl;
std::cerr << "should not reach here!" << std::endl;
CGAL_error();
}
/*!
* Creates the landmark set, using all arrangement vertices.
/*! Create the landmark set, using all arrangement vertices.
*/
virtual void build_landmark_set()
{
// Go over the arrangement, and insert all its vertices as landmarks.
NN_Point_list nnp_list;
NN_Point_list nnp_list;
const Arrangement_2* arr = this->arrangement();
Vertex_const_iterator vit;
num_landmarks = 0;
@ -120,10 +121,9 @@ public:
this->updated = true;
}
/*!
* Clear the landmark set.
/*! Clear the landmark set.
*/
virtual void clear_landmark_set ()
virtual void clear_landmark_set()
{
this->nn.clear();
num_landmarks = 0;
@ -132,13 +132,14 @@ public:
}
protected:
/*! Handle a local change. */
/*! Handle a local change.
*/
void _handle_local_change_notification()
{
// Rebuild the landmark set only if the number of small
// changes is greater than sqrt(num_landmarks).
double nl = static_cast<double>(num_landmarks);
const int sqrt_num_landmarks = static_cast<int> (std::sqrt (nl) + 0.5);
double nl = static_cast<double>(num_landmarks);
const int sqrt_num_landmarks = static_cast<int>(std::sqrt(nl) + 0.5);
this->num_small_not_updated_changes++;
if ((num_landmarks < 10) ||

View File

@ -14,7 +14,7 @@
//
// $URL$
// $Id$
//
//
//
// Author(s) : Idit Haran <haranidi@post.tau.ac.il>
@ -22,106 +22,105 @@
#define CGAL_ARR_TRIANGULATION_POINT_LOCATION_FUNCTIONS_H
/*! \file
* Member-function definitions for the Arr_triangulation_point_location<Arrangement>
* class.
* Member-function definitions for the
* Arr_triangulation_point_location<Arrangement> class.
*/
//#define CGAL_TRG_DEBUG
// #define CGAL_TRG_DEBUG
#ifdef CGAL_TRG_DEBUG
#define CGAL_TRG_PRINT_DEBUG(expr) std::cout << expr << std::endl
#define CGAL_TRG_PRINT_DEBUG(expr) std::cout << expr << std::endl
#else
#define CGAL_TRG_PRINT_DEBUG(expr)
#define CGAL_TRG_PRINT_DEBUG(expr)
#endif
namespace CGAL {
template <typename Arrangement_2_>
typename Arr_triangulation_point_location<Arrangement_2_>::result_type
Arr_triangulation_point_location<Arrangement_2_>::
locate_in_unbounded(const Point_2& p) const
{
CGAL_TRG_PRINT_DEBUG("unbounded face");
//! \todo Here we assume that there is only one unbounded face.
Face_const_handle face_found = this->arrangement()->unbounded_faces_begin();
// Check whether the query point coincides with any of the isolated
// vertices contained inside this face.
typename Traits_adaptor_2::Equal_2 equal = m_traits->equal_2_object();
Isolated_vertex_const_iterator iso_verts_it;
for (iso_verts_it = face_found->isolated_vertices_begin();
iso_verts_it != face_found->isolated_vertices_end(); ++iso_verts_it)
{
if (equal (p, iso_verts_it->point())) {
Vertex_const_handle vh = iso_verts_it;
return make_result(vh);
}
}
return make_result(face_found);
}
//-----------------------------------------------------------------------------
// Locate the arrangement feature containing the given point.
//
template <class Arrangement_2>
typename Arr_triangulation_point_location<Arrangement_2>::result_type
Arr_triangulation_point_location<Arrangement_2>::locate(const Point_2& p) const
template <typename Arrangement_2_>
typename Arr_triangulation_point_location<Arrangement_2_>::result_type
Arr_triangulation_point_location<Arrangement_2_>::locate(const Point_2& p)
const
{
CGAL_TRG_PRINT_DEBUG("------ locate point "<< p);
//init output
Face_const_handle face_found = this->arrangement()->unbounded_face();
CGAL_TRG_PRINT_DEBUG("------ locate point " << p);
//locate in the CDT
CDT_Point p1 = static_cast <CDT_Point> (p);
CDT_Point p1 = static_cast <CDT_Point>(p);
//locate point
int li;
CDT_Locate_type cdt_lt;
CDT_Face_handle fh = cdt.locate(p1,cdt_lt,li);
CDT_Face_handle fh = m_cdt.locate(p1, cdt_lt, li);
switch (cdt_lt) {
case CDT::OUTSIDE_AFFINE_HULL:
case CDT::OUTSIDE_CONVEX_HULL:
{
CGAL_TRG_PRINT_DEBUG("unbounded face" );
// we still have to check whether the query point coincides with
// any of the isolated vertices contained inside this face.
Isolated_vertex_const_iterator iso_verts_it;
typename Traits_adaptor_2::Equal_2 equal = traits->equal_2_object();
for (iso_verts_it = face_found->isolated_vertices_begin();
iso_verts_it != face_found->isolated_vertices_end(); ++iso_verts_it)
{
if (equal (p, iso_verts_it->point())) {
Vertex_const_handle vh = iso_verts_it;
return make_result(vh);
}
}
return make_result(face_found);
}
return locate_in_unbounded(p);
case CDT::VERTEX:
{
//get the vertex from li, which is the index of the vertex
Vertex_const_handle vertex_found = fh->vertex(li)->info();
CGAL_TRG_PRINT_DEBUG("vertex: "<< vertex_found->point());
return make_result(vertex_found);
}
//get the vertex from li, which is the index of the vertex
CGAL_TRG_PRINT_DEBUG("vertex: "<< fh->vertex(li)->info()->point());
return make_result(fh->vertex(li)->info());
case CDT::EDGE:
{
CGAL_TRG_PRINT_DEBUG("locate type = edge"<<li );
//li is the index of the vertex OPOSITE to the edge
if ( cdt.is_constrained(CDT_Edge(fh,li)) )
{ //the edge found is an edge in the plannar map
CGAL_TRG_PRINT_DEBUG("the edge is a constrained");
//get the 2 vertices incident to the edge in the plannar map
int v1_index = (li+1)%3, v2_index = (li+2)%3;
CGAL_TRG_PRINT_DEBUG("v1 = "<<v1_index<<", v2 = "<<v2_index );
Vertex_const_handle v1_of_edge = fh->vertex(v1_index)->info();
Vertex_const_handle v2_of_edge = fh->vertex(v2_index)->info();
//go over all halfedges incident to v1, and check if v2 is their source
Halfedge_around_vertex_const_circulator circ1 =
v1_of_edge->incident_halfedges();
Halfedge_around_vertex_const_circulator circ1_done (circ1);
Halfedge_const_handle edeg_found;
CGAL_TRG_PRINT_DEBUG("locate type = edge" << li);
//li is the index of the vertex OPOSITE to the edge
if (m_cdt.is_constrained(CDT_Edge(fh,li))) {
//the edge found is an edge in the plannar map
CGAL_TRG_PRINT_DEBUG("the edge is a constrained");
//get the 2 vertices incident to the edge in the plannar map
int v1_index = (li+1)%3, v2_index = (li+2)%3;
CGAL_TRG_PRINT_DEBUG("v1 = " << v1_index << ", v2 = " << v2_index);
Vertex_const_handle v1_of_edge = fh->vertex(v1_index)->info();
Vertex_const_handle v2_of_edge = fh->vertex(v2_index)->info();
//go over all halfedges incident to v1, and check if v2 is their source
Halfedge_around_vertex_const_circulator circ1 =
v1_of_edge->incident_halfedges();
Halfedge_around_vertex_const_circulator circ1_done (circ1);
do {
if (v2_of_edge == (*circ1).source())
{
edeg_found = circ1;
CGAL_TRG_PRINT_DEBUG("edeg_found = "<< edeg_found->source()->point()
<<" towards "<< edeg_found->target()->point());
}
} while (++circ1 != circ1_done);
return make_result(edeg_found);
}
//if the edge is not a constrained - its not an edge of the
//plannar map, which means we're inside of a pm face -
//lets look at the face as if it was a face case.
// no break - continue to the face caes
Halfedge_const_handle edge_found;
do {
if (v2_of_edge == (*circ1).source()) {
edge_found = circ1;
CGAL_TRG_PRINT_DEBUG("edge_found = "
<< edge_found->source()->point()
<< " towards "
<< edge_found->target()->point());
}
} while (++circ1 != circ1_done);
return make_result(edge_found);
}
// if the edge is not a constrained - its not an edge of the
// plannar map, which means we're inside of a pm face -
// lets look at the face as if it was a face case.
// no break - continue to the face caes
case CDT::FACE:
break;
@ -131,78 +130,56 @@ Arr_triangulation_point_location<Arrangement_2>::locate(const Point_2& p) const
CGAL_TRG_PRINT_DEBUG("FACE ");
//get 3 pm vertices of face
Vertex_const_handle v0 = fh->vertex(0)->info();
Vertex_const_handle v0 = fh->vertex(0)->info();
Vertex_const_handle v1 = fh->vertex(1)->info();
Vertex_const_handle v2 = fh->vertex(2)->info();
//the vertices should not be isolated, since we do not insert the
//isolated vertices as points in the triangulation, only edges
// (and thus vertices inceident to this edge).
//in the future it is possible to add isolated vertices to the
//isolated vertices as points in the triangulation, only edges
// (and thus vertices inceident to this edge).
//in the future it is possible to add isolated vertices to the
// triangulation, and then, when found, take its incident_face
CGAL_assertion(!v0->is_isolated());
CGAL_assertion(!v1->is_isolated());
CGAL_assertion(!v2->is_isolated());
if (v0->is_isolated()) return make_result(v0->face());
if (v1->is_isolated()) return make_result(v1->face());
if (v2->is_isolated()) return make_result(v2->face());
// if (v0->is_isolated()) return make_result(v0->face());
// if (v1->is_isolated()) return make_result(v1->face());
// if (v2->is_isolated()) return make_result(v2->face());
//find the face in the pm correspond to the 3 vertices
Halfedge_around_vertex_const_circulator havc0 = v0->incident_halfedges();
Halfedge_around_vertex_const_circulator havc0_done (havc0);
Halfedge_around_vertex_const_circulator havc1 = v1->incident_halfedges();
Halfedge_around_vertex_const_circulator havc1_done (havc1);
Halfedge_around_vertex_const_circulator havc2 = v2->incident_halfedges();
Halfedge_around_vertex_const_circulator havc2_done (havc2);
//loop to find face
bool found = false;
bool found_unbounded = false;
// Find the face in the arrangement that contains the triangle <v0,v1,v2>
// Loop over the incident vertices of v0, and try to find a ccb that first
// contains v1 and then v2 in that order. If such a face does not exists,
// the unbounded face contains the triangle.
Halfedge_around_vertex_const_circulator havc0 = v0->incident_halfedges();
Halfedge_around_vertex_const_circulator havc0_done(havc0);
bool found_v2 = false;
Halfedge_const_handle he;
do {
//get face from halfedge
Face_const_handle f0 = (*havc0).face();
bool found_v1 = false;
found_v2 = false;
he = havc0->twin();
Halfedge_const_handle he_done(he);
do {
Face_const_handle f1 = (*havc1).face();
if ( f0 == f1 )
{
CGAL_TRG_PRINT_DEBUG("f0 == f1");
do {
Face_const_handle f2 = (*havc2).face();
if ( f1 == f2 )
{
CGAL_TRG_PRINT_DEBUG("f1 == f2");
if (face_found != f0) {
face_found = f0;
found = true;
}
else
found_unbounded = true;
}
} while ((++havc2 != havc2_done) && !found );
if (!found_v1) {
if (he->target() == v1) found_v1 = true;
}
} while ((++havc1 != havc1_done)&& !found );
} while ((++havc0 != havc0_done)&& !found );
else if (!found_v2) {
if (he->target() == v2) {
found_v2 = true;
break;
}
}
he = he->next();
} while (he != he_done);
} while ((++havc0 != havc0_done) && !found_v2);
if (face_found == this->arrangement()->unbounded_face())
{
if (! found_unbounded)
{
std::cerr<< "NOT GOOD - face not found" << std::endl;
//debug - print some more info
std::cout << "p = "<< p <<std::endl;
std::cout << "v0 = "<< v0->point()
<<", v1 = "<< v1->point()
<<", v2 = "<<v2->point() <<std::endl;
}
}
Face_const_handle face_found = (found_v2) ?
he->face() : this->arrangement()->unbounded_faces_begin();
// we still have to check whether the query point coincides with
// any of the isolated vertices contained inside this face.
Isolated_vertex_const_iterator iso_verts_it;
typename Traits_adaptor_2::Equal_2 equal = traits->equal_2_object();
typename Traits_adaptor_2::Equal_2 equal = m_traits->equal_2_object();
Isolated_vertex_const_iterator iso_verts_it;
for (iso_verts_it = face_found->isolated_vertices_begin();
iso_verts_it != face_found->isolated_vertices_end(); ++iso_verts_it)
{
@ -210,7 +187,7 @@ Arr_triangulation_point_location<Arrangement_2>::locate(const Point_2& p) const
Vertex_const_handle vh = iso_verts_it;
return make_result(vh);
}
}
}
return make_result(face_found);
}
@ -218,33 +195,24 @@ Arr_triangulation_point_location<Arrangement_2>::locate(const Point_2& p) const
//----------------------------------------------------
/*! triangulate the arrangement into a cdt (Constaint Delauney Triangulation):
go over all halfedges, and insert each halfedge as a constraint to the cdt.
go over all halfedges, and insert each halfedge as a constraint to the cdt.
*/
template <class Arrangement_2>
void Arr_triangulation_point_location<Arrangement_2>
::clear_triangulation ()
{
cdt.clear();
}
template <typename Arrangement_2_>
void Arr_triangulation_point_location<Arrangement_2_>::clear_triangulation()
{ m_cdt.clear(); }
//----------------------------------------------------
/*! triangulate the arrangement into a cdt (Constaint Delauney Triangulation):
go over all halfedges, and insert each halfedge as a constraint to the cdt.
go over all halfedges, and insert each halfedge as a constraint to the cdt.
*/
template <class Arrangement_2>
void Arr_triangulation_point_location<Arrangement_2>
::build_triangulation ()
{
template <typename Arrangement_2_>
void Arr_triangulation_point_location<Arrangement_2_>::build_triangulation()
{
CGAL_TRG_PRINT_DEBUG("build_triangulation");
//Go over the arrangement, and create a triangulation of it
Edge_const_iterator eit;
eit = this->arrangement()->edges_begin();
for (eit = this->arrangement()->edges_begin();
eit != this->arrangement()->edges_end(); eit++)
{
Edge_const_iterator eit = this->arrangement()->edges_begin();
for (; eit != this->arrangement()->edges_end(); ++eit) {
//get vertices from edge
Vertex_const_handle pm_vh1 = (*eit).source();
Vertex_const_handle pm_vh2 = (*eit).target();
@ -261,35 +229,31 @@ void Arr_triangulation_point_location<Arrangement_2>
CDT_Point cdt_p2 = static_cast <CDT_Point> (pm_p2);
//check if source point is equal to destination point
if (traits->equal_2_object()(pm_p1, pm_p2))
{
std::cerr << "WARNING: source point is equal to destination point!!! "
<< pm_p1 << std::endl ;
CDT_Vertex_handle cdt_vh1 = cdt.insert(cdt_p1);
if (m_traits->equal_2_object()(pm_p1, pm_p2)) {
std::cerr << "WARNING: source point is equal to destination point!!! "
<< pm_p1 << std::endl ;
CDT_Vertex_handle cdt_vh1 = m_cdt.insert(cdt_p1);
cdt_vh1->info() = pm_vh1;
continue;
}
//insert vertices to the CDT
CDT_Vertex_handle cdt_vh1 = cdt.insert(cdt_p1);
CDT_Vertex_handle cdt_vh2 = cdt.insert(cdt_p2);
CDT_Vertex_handle cdt_vh1 = m_cdt.insert(cdt_p1);
CDT_Vertex_handle cdt_vh2 = m_cdt.insert(cdt_p2);
//connect new CDT vertex with Pm vertex
cdt_vh1->info() = pm_vh1;
cdt_vh2->info() = pm_vh2;
//add constraint from the two points
cdt.insert_constraint(cdt_vh1, cdt_vh2);
m_cdt.insert_constraint(cdt_vh1, cdt_vh2);
//print
CGAL_TRG_PRINT_DEBUG("source = " << pm_p1 << " , target = " << pm_p2 );
CGAL_TRG_PRINT_DEBUG("source = " << pm_p1 << " , target = " << pm_p2);
}
//the triangulation is now updated
updated_cdt = true;
CGAL_assertion(cdt.is_valid());
CGAL_TRG_PRINT_DEBUG("finished updating the CDT " );
CGAL_assertion(m_cdt.is_valid());
CGAL_TRG_PRINT_DEBUG("finished updating the CDT ");
}
} //namespace CGAL

View File

@ -14,7 +14,7 @@
//
// $URL: $
// $Id: $
//
//
//
// Author(s) : Efi Fogel <efif@post.tau.ac.il>
@ -33,6 +33,7 @@
#include <CGAL/Object.h>
#include <boost/optional.hpp>
#include <boost/variant.hpp>
#ifdef CGAL_CFG_BOOST_VARIANT_SWAP_BUG
@ -96,19 +97,19 @@ struct Arr_point_location_result {
static
inline Type make_result(T t) { return Type(t); }
inline
inline
static
boost::optional<Type> empty_optional_result() { return boost::optional<Type>(); }
template<typename T>
const T* assign(const Type& obj) const { return boost::get<T>(&obj); }
#endif // CGAL_ARR_POINT_LOCATION_VERSION < 2
//this one is only to remove warnings in functions
//this one is only to remove warnings in functions
static
inline Type default_result(){
inline Type default_result(){
CGAL_error_msg("This functions should never have been called!");
return Type();
return Type();
}
};

View File

@ -2683,6 +2683,50 @@ namespace CGAL {
Compare_y_near_boundary_2 compare_y_near_boundary_2_object() const
{ return Compare_y_near_boundary_2(*this); }
/*! A functor that indicates whether a geometric object lies on the
* vertical identification arc.
*/
class Is_on_y_identification_2 {
protected:
typedef Arr_polyline_traits_2<Segment_traits_2> Polyline_traits_2;
/*! The polyline traits (in case it has state) */
const Polyline_traits_2& m_poly_traits;
public:
/*! Constructor. */
Is_on_y_identification_2(const Polyline_traits_2& traits) :
m_poly_traits(traits)
{}
/*! Determine whether a point lies in the vertical boundary.
* \param p the point.
* \return a Boolean indicating whether p lies in the vertical boundary.
*/
bool operator()(const Point_2& p) const
{
const Segment_traits_2* seg_traits = m_poly_traits.segment_traits_2();
return seg_traits->is_on_y_identification_2_object()(p);
}
/*! Determine whether an x-monotone curve lies in the vertical boundary.
* \param xcv the x-monotone curve.
* \return a Boolean indicating whether xcv lies in the vertical boundary.
*/
bool operator()(const X_monotone_curve_2& xcv) const
{
const Segment_traits_2* seg_traits = m_poly_traits.segment_traits_2();
typename X_monotone_curve_2::Segment_const_iterator it;
for (it = xcv.begin_segments(); it != xcv.end_segments(); ++it)
if (! seg_traits->is_on_y_identification_2_object()(*it))
return false;
return true;
}
};
/*! Obtain a Is_on_y_identification_2 function object */
Is_on_y_identification_2 is_on_y_identification_2_object() const
{ return Is_on_y_identification_2(*this); }
private:
/*
* Roadmap: locate() should return an iterator to the located segment

View File

@ -57,26 +57,26 @@
namespace CGAL {
// Forward declaration:
template <class GeomTraits, class TopTraits>
template <typename GeomTraits, typename TopTraits>
class Arrangement_on_surface_2;
/*! This class handles the topology for arrangements of great spherical
* arcs on the sphere embedded on 2D parametric surdace.
*/
template <class GeomTraits, class T_Dcel = Arr_default_dcel<GeomTraits> >
template <typename GeomTraits_, typename Dcel_ = Arr_default_dcel<GeomTraits_> >
class Arr_spherical_topology_traits_2 {
public:
///! \name The geometry-traits types.
//@{
typedef GeomTraits Geometry_traits_2;
typedef GeomTraits_ Geometry_traits_2;
typedef typename Geometry_traits_2::Point_2 Point_2;
typedef typename Geometry_traits_2::X_monotone_curve_2 X_monotone_curve_2;
//@}
///! \name The DCEL types.
//@{
typedef T_Dcel Dcel;
typedef Dcel_ Dcel;
typedef typename Dcel::Size Size;
typedef typename Dcel::Vertex Vertex;
typedef typename Dcel::Halfedge Halfedge;
@ -129,32 +129,34 @@ public:
* An auxiliary structure for rebinding the topology traits with a new
* geometry-traits class and a new DCEL class.
*/
template<typename T, typename D>
struct rebind
{
typedef Arr_spherical_topology_traits_2<T,D> other;
template <typename T, typename D>
struct rebind {
typedef Arr_spherical_topology_traits_2<T, D> other;
};
private:
//! A container of boundary vertices.
struct Vertex_key_comparer {
/*! Construct default */
Vertex_key_comparer() : m_traits(NULL) {}
Vertex_key_comparer() : m_geom_traits(NULL) {}
/*! Construct */
Vertex_key_comparer(const Traits_adaptor_2* traits) : m_traits(traits) {}
const Traits_adaptor_2* m_traits;
Vertex_key_comparer(const Traits_adaptor_2* geom_traits) :
m_geom_traits(geom_traits)
{}
const Traits_adaptor_2* m_geom_traits;
bool operator()(const Point_2& p1, const Point_2& p2) const
{
return (m_traits->compare_y_on_boundary_2_object()(p1, p2) ==
return (m_geom_traits->compare_y_on_boundary_2_object()(p1, p2) ==
SMALLER);
}
};
//! \todo define the key to be 'const Point_2*'.
typedef std::map<Point_2,Vertex*,Vertex_key_comparer> Vertex_map;
typedef std::pair<Point_2,Vertex*> Vertex_value;
typedef std::map<Point_2, Vertex*, Vertex_key_comparer> Vertex_map;
typedef std::pair<Point_2, Vertex*> Vertex_value;
protected:
// Data members:
@ -174,14 +176,14 @@ protected:
Vertex_map m_boundary_vertices;
//! The geometry-traits adaptor.
const Traits_adaptor_2* m_traits;
const Traits_adaptor_2* m_geom_traits;
// Inidicates whether the traits object should evetually be freed.
bool m_own_traits;
//! Inidicates whether the traits object should evetually be freed.
bool m_own_geom_traits;
// Copy constructor and assignment operator - not supported.
Arr_spherical_topology_traits_2(const Self &);
Self& operator=(const Self &);
Arr_spherical_topology_traits_2(const Self&);
Self& operator=(const Self&);
public:
///! \name Construction methods.
@ -190,11 +192,14 @@ public:
/*! Default constructor. */
Arr_spherical_topology_traits_2();
/*! Constructor with a geometry-traits class.
/*! Constructor from a geometry-traits object.
* \param traits the traits.
*/
Arr_spherical_topology_traits_2(const Geometry_traits_2* traits);
/*! Destructor */
~Arr_spherical_topology_traits_2();
/*! Assign the contents of another topology-traits class.
* \param other the other spherical topology-traits.
*/
@ -288,18 +293,16 @@ public:
const Vertex* north_pole() const { return m_north_pole; }
/*! Obtain the north pole (non-const version). */
Vertex* north_pole()
{ return m_north_pole; }
Vertex* north_pole() { return m_north_pole; }
/*! Obtain a vertex on the line of discontinuity that corresponds to
* the given curve-end (or return NULL if no such vertex exists).
*/
Vertex* discontinuity_vertex(const X_monotone_curve_2 xc, Arr_curve_end ind)
{
Point_2 key;
key = (ind == ARR_MIN_END) ?
m_traits->construct_min_vertex_2_object()(xc) :
m_traits->construct_max_vertex_2_object()(xc);
Point_2 key = (ind == ARR_MIN_END) ?
m_geom_traits->construct_min_vertex_2_object()(xc) :
m_geom_traits->construct_max_vertex_2_object()(xc);
typename Vertex_map::iterator it = m_boundary_vertices.find(key);
return (it != m_boundary_vertices.end()) ? it->second : NULL;
}
@ -308,27 +311,27 @@ public:
private:
/// \name Auxiliary type definitions.
//@{
typedef Arrangement_on_surface_2<Geometry_traits_2, Self> Arr;
typedef Arrangement_on_surface_2<Geometry_traits_2, Self> Arr;
// Type definition for the constuction sweep-line visitor.
typedef Arr_construction_subcurve<Geometry_traits_2> CSubcurve;
typedef Arr_construction_event<Geometry_traits_2,CSubcurve,Arr>
typedef Arr_construction_event<Geometry_traits_2, CSubcurve, Arr>
CEvent;
typedef Arr_spherical_construction_helper<Geometry_traits_2,Arr,
typedef Arr_spherical_construction_helper<Geometry_traits_2, Arr,
CEvent,CSubcurve> CHelper;
// Type definition for the basic insertion sweep-line visitor.
typedef Arr_basic_insertion_traits_2<Geometry_traits_2, Arr> BInsTraits;
typedef Arr_construction_subcurve<BInsTraits> BISubcurve;
typedef Arr_construction_event<BInsTraits,BISubcurve,Arr> BIEvent;
typedef Arr_spherical_insertion_helper<BInsTraits,Arr,BIEvent,BISubcurve>
typedef Arr_construction_event<BInsTraits, BISubcurve, Arr> BIEvent;
typedef Arr_spherical_insertion_helper<BInsTraits, Arr, BIEvent, BISubcurve>
BIHelper;
// Type definition for the insertion sweep-line visitor.
typedef Arr_insertion_traits_2<Geometry_traits_2, Arr> InsTraits;
typedef Arr_construction_subcurve<InsTraits> ISubcurve;
typedef Arr_construction_event<InsTraits,ISubcurve,Arr> IEvent;
typedef Arr_spherical_insertion_helper<InsTraits,Arr,IEvent,ISubcurve>
typedef Arr_spherical_insertion_helper<InsTraits, Arr, IEvent, ISubcurve>
IHelper;
// Type definition for the batched point-location sweep-line visitor.
@ -340,17 +343,27 @@ private:
typedef Arr_spherical_vert_decomp_helper<VdTraits, Arr> VdHelper;
// Type definition for the overlay sweep-line visitor.
template <class ExGeomTraits_, class ArrangementA_, class ArrangementB_>
template <typename ExGeomTraits_, typename ArrangementA_,
typename ArrangementB_>
struct _Overlay_helper :
public Arr_spherical_overlay_helper<ExGeomTraits_, ArrangementA_,
ArrangementB_, Arr, Arr_construction_event<ExGeomTraits_,
Arr_overlay_subcurve<ExGeomTraits_>, Arr>,
Arr_overlay_subcurve<ExGeomTraits_> >
public Arr_spherical_overlay_helper
<ExGeomTraits_, ArrangementA_, ArrangementB_, Arr,
Arr_construction_event<ExGeomTraits_,
Arr_overlay_subcurve<ExGeomTraits_>, Arr>,
Arr_overlay_subcurve<ExGeomTraits_> >
{
typedef Arr_spherical_overlay_helper<ExGeomTraits_, ArrangementA_,
ArrangementB_, Arr, Arr_construction_event<ExGeomTraits_,
Arr_overlay_subcurve<ExGeomTraits_>, Arr>,
Arr_overlay_subcurve<ExGeomTraits_> > Base;
typedef ExGeomTraits_ Ex_geomt_raits;
typedef ArrangementA_ Arrangement_a;
typedef ArrangementB_ Arrangement_b;
typedef Arr_overlay_subcurve<Ex_geomt_raits> Overlay_subcurve;
typedef Arr_construction_event<Ex_geomt_raits, Overlay_subcurve, Arr>
Construction_event;
typedef Arr_spherical_overlay_helper<Ex_geomt_raits,
Arrangement_a, Arrangement_b, Arr,
Construction_event, Overlay_subcurve>
Base;
typedef typename Base::Traits_2 Traits_2;
typedef typename Base::Arrangement_red_2 Arrangement_red_2;
@ -360,8 +373,9 @@ private:
typedef typename Base::Subcurve Subcurve;
typedef typename Base::Construction_helper Construction_helper;
_Overlay_helper(const ArrangementA_* arrA, const ArrangementB_* arrB) :
Base(arrA, arrB) {}
_Overlay_helper(const Arrangement_a* arr_a, const Arrangement_b* arr_b) :
Base(arr_a, arr_b)
{}
};
//@}
@ -381,16 +395,16 @@ public:
typedef Arr_basic_insertion_sl_visitor<BIHelper>
Sweep_line_non_intersecting_insertion_visitor;
template <class OutputIterator_>
template <typename OutputIterator_>
struct Sweep_line_batched_point_location_visitor :
public Arr_batched_pl_sl_visitor<BplHelper, OutputIterator_>
{
typedef OutputIterator_ Output_iterator;
typedef OutputIterator_ Output_iterator;
typedef Arr_batched_pl_sl_visitor<BplHelper, Output_iterator> Base;
typedef typename Base::Traits_2 Traits_2;
typedef typename Base::Event Event;
typedef typename Base::Subcurve Subcurve;
typedef Arr_batched_pl_sl_visitor<BplHelper, Output_iterator> Base;
typedef typename Base::Traits_2 Traits_2;
typedef typename Base::Event Event;
typedef typename Base::Subcurve Subcurve;
Sweep_line_batched_point_location_visitor(const Arr* arr,
Output_iterator& oi) :
@ -398,16 +412,16 @@ public:
{}
};
template <class OutputIterator_>
template <typename OutputIterator_>
struct Sweep_line_vertical_decomposition_visitor :
public Arr_vert_decomp_sl_visitor<VdHelper, OutputIterator_>
{
typedef OutputIterator_ Output_iterator;
typedef OutputIterator_ Output_iterator;
typedef Arr_vert_decomp_sl_visitor<VdHelper,Output_iterator> Base;
typedef typename Base::Traits_2 Traits_2;
typedef typename Base::Event Event;
typedef typename Base::Subcurve Subcurve;
typedef typename Base::Traits_2 Traits_2;
typedef typename Base::Event Event;
typedef typename Base::Subcurve Subcurve;
Sweep_line_vertical_decomposition_visitor(const Arr* arr,
Output_iterator* oi) :
@ -415,41 +429,44 @@ public:
{}
};
template <class ArrangementA_, class ArrangementB_, class OverlayTraits_>
template <typename ArrangementA_, typename ArrangementB_,
typename OverlayTraits_>
struct Sweep_line_overlay_visitor :
public Arr_overlay_sl_visitor
<_Overlay_helper<Arr_overlay_traits_2<Geometry_traits_2,ArrangementA_,
ArrangementB_>,
ArrangementA_, ArrangementB_>, OverlayTraits_>
<_Overlay_helper<Arr_overlay_traits_2<Geometry_traits_2,ArrangementA_,
ArrangementB_>,
ArrangementA_, ArrangementB_>, OverlayTraits_>
{
typedef ArrangementA_ ArrangementA_2;
typedef ArrangementB_ ArrangementB_2;
typedef ArrangementA_ Arrangement_a;
typedef ArrangementB_ Arrangement_b;
typedef Arr Arrangement_result_2;
typedef OverlayTraits_ Overlay_traits;
typedef Arr_overlay_traits_2<Geometry_traits_2,ArrangementA_2,
ArrangementB_2> Geom_ovl_traits_2;
typedef Arr_overlay_traits_2<Geometry_traits_2,
Arrangement_a,
Arrangement_b> Geom_ovl_traits_2;
typedef _Overlay_helper<Geom_ovl_traits_2,ArrangementA_2,ArrangementB_2>
Ovl_helper;
typedef _Overlay_helper<Geom_ovl_traits_2, Arrangement_a, Arrangement_b>
Ovl_helper;
typedef Arr_overlay_sl_visitor<Ovl_helper,Overlay_traits> Base;
typedef Arr_overlay_sl_visitor<Ovl_helper, Overlay_traits> Base;
typedef typename Base::Traits_2 Traits_2;
typedef typename Base::Event Event;
typedef typename Base::Subcurve Subcurve;
typedef typename Base::Traits_2 Traits_2;
typedef typename Base::Event Event;
typedef typename Base::Subcurve Subcurve;
Sweep_line_overlay_visitor(const ArrangementA_2* arrA,
const ArrangementB_2* arrB,
Sweep_line_overlay_visitor(const Arrangement_a* arr_a,
const Arrangement_b* arr_b,
Arrangement_result_2* arr_res,
Overlay_traits* overlay_tr) :
Base(arrA, arrB, arr_res, overlay_tr)
Base(arr_a, arr_b, arr_res, overlay_tr)
{}
};
typedef Arr_inc_insertion_zone_visitor<Arr> Zone_insertion_visitor;
typedef Arr_naive_point_location<Arr> Default_point_location_strategy;
typedef Arr_naive_point_location<Arr> Default_point_location_strategy;
typedef Arr_naive_point_location<Arr> Default_vertical_ray_shooting_strategy;
//@}
///! \name Topology-traits methods.
@ -494,8 +511,11 @@ public:
* will form a hole in the original face.
*/
std::pair<bool, bool>
face_split_after_edge_insertion(std::pair< CGAL::Sign, CGAL::Sign > /* signs1 */,
std::pair< CGAL::Sign, CGAL::Sign > /* signs2 */) const {
face_split_after_edge_insertion(std::pair< CGAL::Sign,
CGAL::Sign > /* signs1 */,
std::pair< CGAL::Sign,
CGAL::Sign > /* signs2 */) const
{
// In case of a spherical topology, connecting two vertices on the same
// inner CCB closes a new face that becomes a hole in the original face:
return (std::make_pair(true, true));
@ -632,7 +652,6 @@ public:
//@}
protected:
/// \name Auxiliary functions.
//@{
@ -643,17 +662,15 @@ protected:
* \pre v is a valid boundary.
* \return The curve that induces v.
*/
const X_monotone_curve_2& _curve(const Vertex* v,
Arr_curve_end& ind) const;
const X_monotone_curve_2& _curve(const Vertex* v, Arr_curve_end& ind) const;
/*! Return the halfedge, the target vertex of which is given, that is
* the predecessor of a halfedge, the curve of which is given, that is about
* to be inserted into the dcel.
*/
Halfedge *
_locate_around_vertex_on_discontinuity(Vertex* v,
const X_monotone_curve_2& xc,
Arr_curve_end ind) const;
Halfedge* _locate_around_vertex_on_discontinuity(Vertex* v,
const X_monotone_curve_2& xc,
Arr_curve_end ind) const;
/*! Return the halfedge, the target vertex of which is a given pole,
* that is the predecessor of a halfedge, the curve of which is given, that

View File

@ -14,9 +14,10 @@
//
// $URL$
// $Id$
//
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ARR_BOUNDED_PLANAR_TOPOLOGY_TRAITS_2_IMPL_H
#define CGAL_ARR_BOUNDED_PLANAR_TOPOLOGY_TRAITS_2_IMPL_H
@ -31,24 +32,22 @@ namespace CGAL {
//-----------------------------------------------------------------------------
// Assign the contents of another topology-traits class.
//
template <class GeomTraits, class Dcel_>
void Arr_bounded_planar_topology_traits_2<GeomTraits, Dcel_>::assign
(const Self& other)
template <typename GeomTraits_, typename Dcel_>
void Arr_bounded_planar_topology_traits_2<GeomTraits_, Dcel_>::
assign(const Self& other)
{
// Assign the base class.
Base::assign (other);
Base::assign(other);
// Update the topology-traits properties after the DCEL have been updated.
dcel_updated();
return;
}
//-----------------------------------------------------------------------------
// Initialize an empty DCEL structure.
//
template <class GeomTraits, class Dcel_>
void Arr_bounded_planar_topology_traits_2<GeomTraits, Dcel_>::init_dcel ()
template <typename GeomTraits_, typename Dcel_>
void Arr_bounded_planar_topology_traits_2<GeomTraits_, Dcel_>::init_dcel()
{
// Clear the current DCEL.
this->m_dcel.delete_all();
@ -56,34 +55,26 @@ void Arr_bounded_planar_topology_traits_2<GeomTraits, Dcel_>::init_dcel ()
// Create the unbounded face.
unb_face = this->m_dcel.new_face();
unb_face->set_unbounded (true);
unb_face->set_fictitious (false);
return;
unb_face->set_unbounded(true);
unb_face->set_fictitious(false);
}
//-----------------------------------------------------------------------------
// Make the necessary updates after the DCEL structure have been updated.
//
template <class GeomTraits, class Dcel_>
void Arr_bounded_planar_topology_traits_2<GeomTraits, Dcel_>::dcel_updated ()
template <typename GeomTraits_, typename Dcel_>
void Arr_bounded_planar_topology_traits_2<GeomTraits_, Dcel_>::dcel_updated()
{
// Go over the DCEL faces and locate the unbounded face.
typename Dcel::Face_iterator fit;
unb_face = NULL;
for (fit = this->m_dcel.faces_begin();
fit != this->m_dcel.faces_end(); ++fit)
{
if (fit->is_unbounded())
{
typename Dcel::Face_iterator fit = this->m_dcel.faces_begin();
for (; fit != this->m_dcel.faces_end(); ++fit) {
if (fit->is_unbounded()) {
unb_face = &(*fit);
break;
}
}
CGAL_assertion (unb_face != NULL);
return;
CGAL_assertion(unb_face != NULL);
}
} //namespace CGAL

View File

@ -50,12 +50,11 @@ namespace CGAL {
* A base topology-traits class that encapsulates the embedding of 2D
* arrangements of bounded or unbounded curves on the plane.
*/
template <class GeomTraits_,
class Dcel_ = Arr_default_dcel<GeomTraits_> >
template <typename GeomTraits_,
typename Dcel_ = Arr_default_dcel<GeomTraits_> >
class Arr_planar_topology_traits_base_2
{
public:
///! \name The geometry-traits types.
//@{
typedef GeomTraits_ Geometry_traits_2;
@ -75,54 +74,50 @@ public:
typedef typename Dcel::Isolated_vertex Isolated_vertex;
//@}
typedef Arr_planar_topology_traits_base_2<Geometry_traits_2,
Dcel> Self;
typedef Arr_planar_topology_traits_base_2<Geometry_traits_2, Dcel>
Self;
protected:
typedef Arr_traits_basic_adaptor_2<Geometry_traits_2> Traits_adaptor_2;
typedef Arr_traits_basic_adaptor_2<Geometry_traits_2> Traits_adaptor_2;
// Data members:
Dcel m_dcel; // The DCEL.
Dcel m_dcel; // The DCEL.
const Traits_adaptor_2* traits; // The geometry-traits adaptor.
bool own_traits; // Inidicate whether we should evetually
// free the traits object.
const Traits_adaptor_2* m_geom_traits; // The geometry-traits adaptor.
bool m_own_geom_traits; // Inidicate whether we should
// evetually free the traits object.
// Copy constructor and assignment operator - not supported.
Arr_planar_topology_traits_base_2 (const Self& );
Self& operator= (const Self& );
Arr_planar_topology_traits_base_2(const Self&);
Self& operator=(const Self&);
public:
///! \name Construction methods.
//@{
/*! Default constructor. */
Arr_planar_topology_traits_base_2 () :
own_traits (true)
{
traits = new Traits_adaptor_2;
}
Arr_planar_topology_traits_base_2() :
m_own_geom_traits(true)
{ m_geom_traits = new Traits_adaptor_2; }
/*! Constructor with a geometry-traits class. */
Arr_planar_topology_traits_base_2 (const Geometry_traits_2 * geom_traits) :
own_traits (false)
{
traits = static_cast<const Traits_adaptor_2*>(geom_traits);
}
Arr_planar_topology_traits_base_2 (const Geometry_traits_2* geom_traits) :
m_own_geom_traits(false)
{ m_geom_traits = static_cast<const Traits_adaptor_2*>(geom_traits); }
/*! Assign the contents of another topology-traits class. */
void assign (const Self& other);
void assign(const Self& other);
/*! Destructor. */
virtual ~Arr_planar_topology_traits_base_2 ()
virtual ~Arr_planar_topology_traits_base_2()
{
// Clear the DCEL.
m_dcel.delete_all();
if (own_traits)
delete traits;
if (m_own_geom_traits && (m_geom_traits != NULL)) {
delete m_geom_traits;
m_geom_traits = NULL;
}
}
//@}
@ -130,16 +125,10 @@ public:
//@{
/*! Get the DCEL (const version). */
const Dcel& dcel () const
{
return (m_dcel);
}
const Dcel& dcel() const { return m_dcel; }
/*! Get the DCEL (non-const version). */
Dcel& dcel ()
{
return (m_dcel);
}
Dcel& dcel() { return (m_dcel); }
/*!
* Receive a notification on the creation of a new boundary vertex that
@ -150,11 +139,11 @@ public:
* \param ps_x The boundary condition of the curve end in x.
* \param ps_y The boundary condition of the curve end in y.
*/
void notify_on_boundary_vertex_creation (Vertex *,
const X_monotone_curve_2& ,
Arr_curve_end,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
void notify_on_boundary_vertex_creation(Vertex*,
const X_monotone_curve_2& ,
Arr_curve_end,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
{
// In the planar-topology traits this function should never be invoked:
return;
@ -170,9 +159,11 @@ public:
* \param swap_predecessors Output swap predeccesors or not;
* set correctly only if true is returned
*/
bool let_me_decide_the_outer_ccb(std::pair< CGAL::Sign, CGAL::Sign> /* signs1 */,
std::pair< CGAL::Sign, CGAL::Sign> /* signs2 */,
bool& swap_predecessors) const {
bool
let_me_decide_the_outer_ccb(std::pair<CGAL::Sign, CGAL::Sign> /* signs1 */,
std::pair<CGAL::Sign, CGAL::Sign> /* signs2 */,
bool& swap_predecessors) const
{
swap_predecessors = false;
return false;
}
@ -188,11 +179,14 @@ public:
* will form a hole in the original face.
*/
std::pair<bool, bool>
face_split_after_edge_insertion(std::pair< CGAL::Sign, CGAL::Sign > /* signs1 */,
std::pair< CGAL::Sign, CGAL::Sign > /* signs2 */) const {
face_split_after_edge_insertion(std::pair<CGAL::Sign,
CGAL::Sign > /* signs1 */,
std::pair<CGAL::Sign,
CGAL::Sign > /* signs2 */) const
{
// In case of a planar topology, connecting two vertices on the same
// inner CCB closes a new face that becomes a hole in the original face:
return (std::make_pair (true, true));
return (std::make_pair(true, true));
}
/*!
@ -203,7 +197,7 @@ public:
* \param f must not be fictitious, and v must not lie at infinity.
* \return Whether p is contained in f's interior.
*/
bool is_in_face (const Face *f, const Point_2& p, const Vertex *v) const;
bool is_in_face(const Face* f, const Point_2& p, const Vertex* v) const;
//@}
/// \name Additional accessors, specialized for this topology-traits class.
@ -222,8 +216,8 @@ public:
* \param v The vertex.
* \return The result of the comparison of the x-coordinates of p and v.
*/
virtual Comparison_result compare_x (const Point_2& p,
const Vertex* v) const = 0;
virtual Comparison_result compare_x(const Point_2& p,
const Vertex* v) const = 0;
/*!
* Compare the given vertex (which may lie at infinity) and the given point.
@ -242,8 +236,8 @@ public:
* \pre p should lie in the x-range of the given edge.
* \return The relative y-position of the point p and the edge.
*/
virtual Comparison_result compare_y_at_x (const Point_2& p,
const Halfedge* he) const = 0;
virtual Comparison_result compare_y_at_x(const Point_2& p,
const Halfedge* he) const = 0;
//@}
};
@ -254,43 +248,41 @@ public:
//-----------------------------------------------------------------------------
// Assign the contents of another topology-traits class.
//
template <class GeomTraits, class Dcel_>
void Arr_planar_topology_traits_base_2<GeomTraits, Dcel_>::assign
(const Self& other)
template <typename GeomTraits, typename Dcel_>
void
Arr_planar_topology_traits_base_2<GeomTraits, Dcel_>::assign(const Self& other)
{
// Clear the current DCEL and duplicate the other DCEL.
m_dcel.delete_all();
m_dcel.assign (other.m_dcel);
m_dcel.assign(other.m_dcel);
// Take care of the traits object.
if (own_traits && traits != NULL)
delete traits;
if (m_own_geom_traits && (m_geom_traits != NULL)) {
delete m_geom_traits;
m_geom_traits = NULL;
}
if (other.own_traits)
traits = new Traits_adaptor_2;
else
traits = other.traits;
own_traits = other.own_traits;
if (other.m_own_geom_traits) m_geom_traits = new Traits_adaptor_2;
else m_geom_traits = other.m_geom_traits;
return;
m_own_geom_traits = other.m_own_geom_traits;
}
//-----------------------------------------------------------------------------
// Determine whether the given vertex lies in the interior of the given face.
//
template <class GeomTraits, class Dcel_>
template <typename GeomTraits, typename Dcel_>
bool Arr_planar_topology_traits_base_2<GeomTraits, Dcel_>::
is_in_face(const Face *f, const Point_2& p, const Vertex *v) const
is_in_face(const Face* f, const Point_2& p, const Vertex* v) const
{
CGAL_precondition (v == NULL || ! v->has_null_point());
CGAL_precondition (v == NULL ||
traits->equal_2_object()(p, v->point()));
CGAL_precondition((v == NULL) || ! v->has_null_point());
CGAL_precondition((v == NULL) ||
m_geom_traits->equal_2_object()(p, v->point()));
// In case the face is unbounded and has no outer ccbs, this is the single
// unbounded face of an arrangement of bounded curves. This face obviously
// contains any point in its interior.
if (f->is_unbounded() && f->number_of_outer_ccbs() == 0)
return (true);
if (f->is_unbounded() && (f->number_of_outer_ccbs() == 0)) return true;
// Keep a counter of the number of x-monotone curves that intersect an upward
// vertical emanating from p (except for some degenerate cases that are
@ -302,7 +294,7 @@ is_in_face(const Face *f, const Point_2& p, const Vertex *v) const
// We begin by comparing p to the source vertex of the first halfedge.
// Note that if p coincides with this vertex, p is obviously not in the
// interior of the component.
const Halfedge *first = *(f->outer_ccbs_begin());
const Halfedge* first = *(f->outer_ccbs_begin());
// Some left ends of curves may not yet have the curve assigned,
@ -317,34 +309,31 @@ is_in_face(const Face *f, const Point_2& p, const Vertex *v) const
}
const Halfedge *curr = first;
Comparison_result res_source;
Comparison_result res_target;
Comparison_result res_y_at_x;
const Halfedge* curr = first;
Comparison_result res_source;
Comparison_result res_target;
Comparison_result res_y_at_x;
if (curr->opposite()->vertex() == v)
return (false);
if (curr->opposite()->vertex() == v) return false;
res_source = compare_xy (p, curr->opposite()->vertex());
res_source = compare_xy(p, curr->opposite()->vertex());
do
{
do {
// Compare p to the target vertex of the current halfedge.
// If the vertex v associated with p (if v is given and is not NULL)
// on the boundary of the component, p is obviously not in the interior
// the component.
if (curr->vertex() == v)
return (false);
if (curr->vertex() == v) return false;
// We jump over vertices at TOP/BOTTOM that do not yet have a curve
if( curr->vertex()->parameter_space_in_x()==ARR_INTERIOR
&& curr->has_null_curve()
&& curr->next()->has_null_curve()){
if ((curr->vertex()->parameter_space_in_x() == ARR_INTERIOR) &&
curr->has_null_curve() && curr->next()->has_null_curve())
{
curr = curr->next();
continue;
}
res_target = compare_xy (p, curr->vertex());
res_target = compare_xy(p, curr->vertex());
// In case the current halfedge belongs to an "antenna", namely its
// incident face is the same as its twin's, we can simply skip it
@ -361,19 +350,16 @@ is_in_face(const Face *f, const Point_2& p, const Vertex *v) const
// (by "tilted" we mean the angle it forms with the x-axis is
// PI/2 + epsilon, where epsilon is arbitrarily small), then we hit
// the x-monotone curve associated with curr once.
if (res_source != res_target)
{
res_y_at_x = compare_y_at_x (p, curr);
if (res_source != res_target) {
res_y_at_x = compare_y_at_x(p, curr);
if (res_y_at_x == SMALLER)
{
n_ray_intersections++;
if (res_y_at_x == SMALLER) {
++n_ray_intersections;
}
else if (res_y_at_x == EQUAL)
{
else if (res_y_at_x == EQUAL) {
// In this case p lies on the current edge, so it is obviously not
// contained in the interior of the component.
return (false);
return false;
}
}

View File

@ -1,4 +1,4 @@
// Copyright (c) 2007,2009,2010,2011 Tel-Aviv University (Israel).
// Copyright (c) 2007,2009,2010,2011,2013 Tel-Aviv University (Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
@ -14,7 +14,7 @@
//
// $URL$
// $Id$
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
@ -49,6 +49,7 @@ public:
typedef Sweep_line_empty_visitor<Traits_2> Base_visitor;
typedef typename Base_visitor::Event Event;
typedef typename Base_visitor::Subcurve Subcurve;
typedef typename Event::Subcurve_iterator Subcurve_iterator;
protected:
@ -56,16 +57,16 @@ protected:
// Data members:
//! The topology-traits class.
const Topology_traits * m_top_traits;
const Topology_traits* m_top_traits;
//! The unbounded arrangement face.
Face_const_handle m_unb_face;
Face_const_handle m_spherical_face;
public:
/*! Constructor.
* \param arr The arrangement.
*/
Arr_spherical_batched_pl_helper(const Arrangement_2 *arr) :
Arr_spherical_batched_pl_helper(const Arrangement_2* arr) :
m_top_traits(arr->topology_traits())
{}
@ -74,22 +75,64 @@ public:
/*! A notification issued before the sweep process starts. */
void before_sweep()
{
// Get the unbounded face.
m_unb_face = Face_const_handle(m_top_traits->unbounded_face());
}
{ m_spherical_face = Face_const_handle(m_top_traits->spherical_face()); }
/*! A notification invoked after the sweep-line finishes handling the given
* event.
*/
void after_handle_event(Event * ) { return; }
void after_handle_event(Event* event) {
if (event->parameter_space_in_y() == ARR_TOP_BOUNDARY) {
Arr_curve_end ind = ((event->number_of_left_curves() == 0) &&
(event->number_of_right_curves() != 0)) ?
ARR_MIN_END : ARR_MAX_END;
Subcurve_iterator it, nit, it_end;
if (ind == ARR_MIN_END) {
it = nit = event->right_curves_begin();
it_end = event->right_curves_end();
} else {
it = nit = event->left_curves_begin();
it_end = event->left_curves_end();
}
++nit;
if (it != it_end) {
while (nit != it_end) {
++it;
++nit;
}
}
const Subcurve* sc = *it;
// pick the one facing the top right corner now
m_spherical_face = sc->last_curve().halfedge_handle()->face();
}
// EBEB 2013-12-012 do similar stuff for right boundary
if (event->parameter_space_in_y() == ARR_RIGHT_BOUNDARY) {
Subcurve_iterator it, nit, it_end;
it = nit = event->left_curves_begin();
it_end = event->left_curves_end();
++nit;
if (it != it_end) {
while (nit != it_end) {
++it;
++nit;
}
}
const Subcurve* sc = *it;
// pick the one facing the top right corner now
CGAL_assertion(sc->last_curve().halfedge_handle()->direction() == ARR_LEFT_TO_RIGHT);
m_spherical_face = sc->last_curve().halfedge_handle()->face();
}
return;
}
//@}
/*! Get the current top face. */
Face_const_handle top_face() const
{
return m_unb_face;
}
/*! Obtain the current top face. */
Face_const_handle top_face() const { return m_spherical_face; }
};
} //namespace CGAL

View File

@ -14,7 +14,7 @@
//
// $URL$
// $Id$
//
//
// Author(s) : Efi Fogel <efif@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
@ -29,33 +29,47 @@
namespace CGAL {
/*! \brief constructs default */
template <class GeomTraits, class Dcel>
template <typename GeomTraits, typename Dcel>
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
Arr_spherical_topology_traits_2() :
m_spherical_face(NULL),
m_north_pole(NULL),
m_south_pole(NULL),
m_own_traits(true)
m_own_geom_traits(true)
{
m_traits = new Traits_adaptor_2;
m_boundary_vertices = Vertex_map(Vertex_key_comparer(m_traits));
m_geom_traits = new Traits_adaptor_2;
m_boundary_vertices = Vertex_map(Vertex_key_comparer(m_geom_traits));
}
/*! \brief constructs with a geometry-traits class */
template <class GeomTraits, class Dcel>
/*! \brief constructs from a geometry-traits object. */
template <typename GeomTraits, typename Dcel>
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
Arr_spherical_topology_traits_2(const Geometry_traits_2* traits) :
m_spherical_face(NULL),
m_north_pole(NULL),
m_south_pole(NULL),
m_own_traits(false)
m_own_geom_traits(false)
{
m_traits = static_cast<const Traits_adaptor_2*>(traits);
m_boundary_vertices = Vertex_map(Vertex_key_comparer(m_traits));
m_geom_traits = static_cast<const Traits_adaptor_2*>(traits);
m_boundary_vertices = Vertex_map(Vertex_key_comparer(m_geom_traits));
}
/*! \brief destructs */
template <typename GeomTraits, typename Dcel>
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
~Arr_spherical_topology_traits_2()
{
// Clear the DCEL.
m_dcel.delete_all();
if (m_own_geom_traits && (m_geom_traits != NULL)) {
delete m_geom_traits;
m_geom_traits = NULL;
}
}
/*! \brief assigns the contents of another topology-traits class */
template <class GeomTraits, class Dcel>
template <typename GeomTraits, typename Dcel>
void Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
assign(const Self& other)
{
@ -64,44 +78,41 @@ assign(const Self& other)
m_dcel.assign(other.m_dcel);
// Take care of the traits object.
if (m_own_traits && m_traits != NULL)
delete m_traits;
if (other.m_own_traits)
{
m_traits = new Traits_adaptor_2;
m_own_traits = true;
if (m_own_geom_traits && m_geom_traits != NULL) {
delete m_geom_traits;
m_geom_traits == NULL;
}
else
{
m_traits = other.m_traits;
m_own_traits = false;
if (other.m_own_geom_traits) {
m_geom_traits = new Traits_adaptor_2;
m_own_geom_traits = true;
}
else {
m_geom_traits = other.m_geom_traits;
m_own_geom_traits = false;
}
// Update the rest of the properties.
dcel_updated();
return;
}
/*! \brief initializes an empty DCEL structure. */
template <class GeomTraits, class Dcel>
void Arr_spherical_topology_traits_2<GeomTraits, Dcel>::dcel_updated()
template <typename GeomTraits_, typename Dcel_>
void Arr_spherical_topology_traits_2<GeomTraits_, Dcel_>::dcel_updated()
{
typedef Dcel_ Dcel;
// Go over the DCEL vertices and locate the south and north pole (if any)
// and any other vertex on the line of discontinuity.
typename Dcel::Vertex_iterator vit;
Arr_parameter_space bx, by;
m_north_pole = NULL;
m_south_pole = NULL;
m_boundary_vertices.clear();
for (vit = this->m_dcel.vertices_begin();
vit != this->m_dcel.vertices_end(); ++vit)
{
bx = vit->parameter_space_in_x();
by = vit->parameter_space_in_y();
typename Dcel::Vertex_iterator vit = this->m_dcel.vertices_begin();
for (; vit != this->m_dcel.vertices_end(); ++vit) {
Arr_parameter_space bx = vit->parameter_space_in_x();
Arr_parameter_space by = vit->parameter_space_in_y();
if (by == ARR_BOTTOM_BOUNDARY) m_south_pole = &(*vit);
else if (by == ARR_TOP_BOUNDARY) m_north_pole = &(*vit);
@ -113,13 +124,11 @@ void Arr_spherical_topology_traits_2<GeomTraits, Dcel>::dcel_updated()
// Go over the DCEL faces and locate the spherical face, which is the only
// face with no outer CCB.
typename Dcel::Face_iterator fit;
m_spherical_face = NULL;
for (fit = this->m_dcel.faces_begin(); fit != this->m_dcel.faces_end(); ++fit)
{
if (fit->number_of_outer_ccbs() == 0)
{
typename Dcel::Face_iterator fit = this->m_dcel.faces_begin();
for (; fit != this->m_dcel.faces_end(); ++fit) {
if (fit->number_of_outer_ccbs() == 0) {
CGAL_assertion(m_spherical_face == NULL);
m_spherical_face = &(*fit);
@ -127,12 +136,10 @@ void Arr_spherical_topology_traits_2<GeomTraits, Dcel>::dcel_updated()
}
}
CGAL_assertion(m_spherical_face != NULL);
return;
}
/*! \brief initializes an empty DCEL structure. */
template <class GeomTraits, class Dcel>
template <typename GeomTraits, typename Dcel>
void Arr_spherical_topology_traits_2<GeomTraits, Dcel>::init_dcel()
{
// std::cout << "init_dcel()" << std::endl;
@ -150,20 +157,21 @@ void Arr_spherical_topology_traits_2<GeomTraits, Dcel>::init_dcel()
}
/*! \brief determines whether a point lies in the interior of a given face. */
template <class GeomTraits, class Dcel>
template <typename GeomTraits, typename Dcel>
bool Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
is_in_face(const Face* f, const Point_2& p, const Vertex* v) const
{
// std::cout << "is_in_face()" << std::endl;
CGAL_precondition(v == NULL || !v->has_null_point());
CGAL_precondition(v == NULL || m_traits->equal_2_object()(p, v->point()));
CGAL_precondition((v == NULL) || !v->has_null_point());
CGAL_precondition((v == NULL) ||
m_geom_traits->equal_2_object()(p, v->point()));
/* There is always one face that contains everything else. It has no
* outer CCB's. When a new face is constructed, we make sure that the
* face that contains everything also contains the north pole. (In the
* degenerate case, where a vertex coincides with the north pole, the face
* that contains everything is incident to the north pole.)
* If the face has no iuter ccb's, it contains everything:
* If the face has no outer ccb's, it contains everything:
*/
#if 0
std::cout << "p: " << p
@ -172,26 +180,29 @@ is_in_face(const Face* f, const Point_2& p, const Vertex* v) const
#endif
if (f->number_of_outer_ccbs() == 0) return true;
if (((v != NULL) && (v->parameter_space_in_y() == ARR_TOP_BOUNDARY)) ||
(m_traits->parameter_space_in_y_2_object()(p) == ARR_TOP_BOUNDARY))
(m_geom_traits->parameter_space_in_y_2_object()(p) == ARR_TOP_BOUNDARY))
return false;
/*! \todo a temporary test
* if (((v != NULL) && (v->parameter_space_in_y() == ARR_BOTTOM_BOUNDARY)) ||
* (p.is_min_boundary()))
* return false;
* return false;
*/
typename Traits_adaptor_2::Parameter_space_in_x_2 ps_x_op =
m_traits->parameter_space_in_x_2_object();
m_geom_traits->parameter_space_in_x_2_object();
typename Traits_adaptor_2::Parameter_space_in_y_2 ps_y_op =
m_traits->parameter_space_in_y_2_object();
m_geom_traits->parameter_space_in_y_2_object();
typename Traits_adaptor_2::Compare_x_2 cmp_x_op =
m_traits->compare_x_2_object();
m_geom_traits->compare_x_2_object();
typename Traits_adaptor_2::Compare_y_at_x_2 cmp_y_at_x_op =
m_traits->compare_y_at_x_2_object();
m_geom_traits->compare_y_at_x_2_object();
typename Traits_adaptor_2::Compare_x_point_curve_end_2 cmp_x_pt_ce =
m_traits->compare_x_point_curve_end_2_object();
m_geom_traits->compare_x_point_curve_end_2_object();
// Process the input point.
bool p_is_interior_x = !(m_geom_traits->is_on_y_identification_2_object()(p));
/* Maintain a counter of the number of x-monotone curves that intersect an
* upward vertical ray emanating from p. Handle degenerate cases as
* explained below).
@ -211,7 +222,6 @@ is_in_face(const Face* f, const Point_2& p, const Vertex* v) const
*/
if (curr->opposite()->vertex() == v) return false;
/*! We identify 2 main cases:
* 1. The vertical ray intersects the boundary at a halfedge. In this
* case the x-possition of p is strictly larger than the x-possition of
@ -226,7 +236,7 @@ is_in_face(const Face* f, const Point_2& p, const Vertex* v) const
* than the x-possition of the next-curve target, or vise verase (that is,
* the "smaller" and "larger" interchanged).
*/
/* Indicates that a change between the x-position of p and the x-position
* of the current-curve source, and the x-position of p and the x-position
* of the current-curve target is pending. Used to handle case (2) above.
@ -245,9 +255,6 @@ is_in_face(const Face* f, const Point_2& p, const Vertex* v) const
ps_x_source, ps_x_target = ARR_INTERIOR,
ps_y_source, ps_y_target;
Arr_parameter_space ps_x_p = ARR_INTERIOR;
if (v != NULL) ps_x_p = v->parameter_space_in_x();
do {
/* Compare p to the target vertex of the current halfedge. If the
* vertex v is on the boundary of the component, p is not in the interior
@ -256,27 +263,29 @@ is_in_face(const Face* f, const Point_2& p, const Vertex* v) const
if (curr->vertex() == v) return false;
// Ignore vertical curves:
bool is_vertical = m_traits->is_vertical_2_object()(curr->curve());
if (is_vertical)
{
/* If this outer ccb chain contains the north pole, and our point
bool is_vertical = m_geom_traits->is_vertical_2_object()(curr->curve());
if (is_vertical) {
/* If this outer ccb chain contains the north pole, and our point
* lies horizontaly between the two vertical curves that meet at
* the north pole, increase the intersection counter
*/
Arr_parameter_space ps_y_1 = ps_y_op(curr->curve(), ARR_MAX_END);
Arr_parameter_space ps_y_2 = ps_y_op(curr->next()->curve(), ARR_MAX_END);
if ((ps_y_1 == ARR_TOP_BOUNDARY) && (ps_y_2 == ARR_TOP_BOUNDARY)) {
// Compare the x-coordinates:
Comparison_result rc1 =
cmp_x_pt_ce(p, curr->curve(), ARR_MAX_END);
Comparison_result rc2 =
cmp_x_pt_ce(p, curr->next()->curve(), ARR_MAX_END);
if (rc1 == opposite(rc2)) ++num_intersections;
if (curr->direction() == ARR_LEFT_TO_RIGHT) {
Arr_parameter_space ps_y_1 = ps_y_op(curr->curve(), ARR_MAX_END);
Arr_parameter_space ps_y_2 = ps_y_op(curr->next()->curve(),
ARR_MAX_END);
if ((ps_y_1 == ARR_TOP_BOUNDARY) && (ps_y_2 == ARR_TOP_BOUNDARY)) {
// Compare the x-coordinates:
Comparison_result rc1 =
cmp_x_pt_ce(p, curr->curve(), ARR_MAX_END);
Comparison_result rc2 =
cmp_x_pt_ce(p, curr->next()->curve(), ARR_MAX_END);
if (rc1 == opposite(rc2)) ++num_intersections;
}
}
curr = curr->next();
continue;
}
/* If the current halfedge belongs to an "antenna". Namely, its
* incident face is the same as its twin's, skip it to avoid counting
* it twice.
@ -286,7 +295,7 @@ is_in_face(const Face* f, const Point_2& p, const Vertex* v) const
const Halfedge* opp_he = curr->opposite();
const Face* opp_curr_face = (opp_he->is_on_inner_ccb()) ?
opp_he->inner_ccb()->face() : opp_he->outer_ccb()->face();
if (curr_face == opp_curr_face) {
curr = curr->next();
continue;
@ -296,7 +305,8 @@ is_in_face(const Face* f, const Point_2& p, const Vertex* v) const
if (curr->direction() == ARR_LEFT_TO_RIGHT) {
ind_source = ARR_MIN_END;
ind_target = ARR_MAX_END;
} else {
}
else {
ind_source = ARR_MAX_END;
ind_target = ARR_MIN_END;
}
@ -306,13 +316,13 @@ is_in_face(const Face* f, const Point_2& p, const Vertex* v) const
ps_y_source = ps_y_op(curr->curve(), ind_source);
ps_y_target = ps_y_op(curr->curve(), ind_target);
if (ps_x_p != ARR_INTERIOR) {
if (!p_is_interior_x) {
if (ps_x_source == ps_x_target) {
curr = curr->next();
continue;
}
if (ps_x_target != ARR_INTERIOR) {
change_pending = true;
ps_x_pending = (ps_x_target == ARR_LEFT_BOUNDARY) ?
@ -340,14 +350,14 @@ is_in_face(const Face* f, const Point_2& p, const Vertex* v) const
res_source = (ps_x_source == ARR_LEFT_BOUNDARY) ? LARGER :
(ps_x_source == ARR_RIGHT_BOUNDARY) ? SMALLER :
(ps_y_source == ARR_INTERIOR) ?
cmp_x_op(p, curr->opposite()->vertex()->point()) :
cmp_x_pt_ce(p, curr->curve(), ind_source);
cmp_x_op(p, curr->opposite()->vertex()->point()) :
cmp_x_pt_ce(p, curr->curve(), ind_source);
res_target = (ps_x_target == ARR_LEFT_BOUNDARY) ? LARGER :
(ps_x_target == ARR_RIGHT_BOUNDARY) ? SMALLER :
(ps_y_target == ARR_INTERIOR) ?
cmp_x_op(p, curr->vertex()->point()) :
cmp_x_pt_ce(p, curr->curve(), ind_target);
cmp_x_op(p, curr->vertex()->point()) :
cmp_x_pt_ce(p, curr->curve(), ind_target);
/* If a vertical ray is shot from p upward, the x-monotone curve
* associated with curr is hit once.
@ -383,7 +393,7 @@ is_in_face(const Face* f, const Point_2& p, const Vertex* v) const
} while (curr != first);
if (last_pending) {
if (ps_x_p != ARR_INTERIOR) {
if (!p_is_interior_x) {
if (ps_x_last == ps_x_target) {
Comparison_result res_y_at_x = cmp_y_at_x_op(p, curr->curve());
if (res_y_at_x == EQUAL) return false;
@ -409,17 +419,17 @@ is_in_face(const Face* f, const Point_2& p, const Vertex* v) const
}
/*! \brief compares the relative y-position of a point and a halfedge */
template <class GeomTraits, class Dcel>
template <typename GeomTraits, typename Dcel>
Comparison_result
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
compare_y_at_x(const Point_2& p, const Halfedge* he) const
{
// std::cout << "compare_y_at_x(Point_2&,Halfedge*)" << std::endl;
return m_traits->compare_y_at_x_2_object()(p, he->curve());
return m_geom_traits->compare_y_at_x_2_object()(p, he->curve());
}
/*! \brief determine whether a vertex is associated with a curve end */
template <class GeomTraits, class Dcel>
template <typename GeomTraits, typename Dcel>
bool Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
are_equal(const Vertex* v,
const X_monotone_curve_2& xc, Arr_curve_end ind,
@ -439,9 +449,9 @@ are_equal(const Vertex* v,
if (ps_y != v->parameter_space_in_y()) return false;
if (ps_y != ARR_INTERIOR) return (ps_y == v->parameter_space_in_y());
if (((ps_x == ARR_INTERIOR) && (v->parameter_space_in_x() != ARR_INTERIOR)) ||
((ps_x != ARR_INTERIOR) && (v->parameter_space_in_x() == ARR_INTERIOR)))
((ps_x != ARR_INTERIOR) && (v->parameter_space_in_x() == ARR_INTERIOR)))
return false;
CGAL_assertion(ps_x != ARR_INTERIOR);
@ -450,13 +460,13 @@ are_equal(const Vertex* v,
*/
const Point_2& p1 = v->point();
const Point_2& p2 = (ind == ARR_MIN_END) ?
m_traits->construct_min_vertex_2_object()(xc) :
m_traits->construct_max_vertex_2_object()(xc);
return (m_traits->compare_y_on_boundary_2_object()(p1, p2) == EQUAL);
m_geom_traits->construct_min_vertex_2_object()(xc) :
m_geom_traits->construct_max_vertex_2_object()(xc);
return (m_geom_traits->compare_y_on_boundary_2_object()(p1, p2) == EQUAL);
}
/*! \brief receives a notification on the creation of a new boundary vertex */
template <class GeomTraits, class Dcel>
template <typename GeomTraits, typename Dcel>
void
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
notify_on_boundary_vertex_creation(Vertex* v,
@ -477,37 +487,38 @@ notify_on_boundary_vertex_creation(Vertex* v,
}
CGAL_assertion(ps_x != ARR_INTERIOR);
const Point_2& key = (ind == ARR_MIN_END) ?
m_traits->construct_min_vertex_2_object()(xc) :
m_traits->construct_max_vertex_2_object()(xc);
m_geom_traits->construct_min_vertex_2_object()(xc) :
m_geom_traits->construct_max_vertex_2_object()(xc);
m_boundary_vertices.insert(Vertex_value(key, v));
}
template <class GeomTraits, class Dcel>
bool
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
template <typename GeomTraits, typename Dcel>
bool Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
let_me_decide_the_outer_ccb(std::pair< CGAL::Sign, CGAL::Sign> signs1,
std::pair< CGAL::Sign, CGAL::Sign> signs2,
bool& swap_predecessors) const {
CGAL_precondition(signs1.second == CGAL::ZERO); // no perimetric in top-bottom for first loop
CGAL_precondition(signs2.second == CGAL::ZERO); // no perimetric in top-bottom for second loop
bool& swap_predecessors) const
{
// no perimetric in top-bottom for first loop
CGAL_precondition(signs1.second == CGAL::ZERO);
// choose prev1 to define outer ccb of new face if it is a non-perimetric loop,
// otherwise choose prev2
// TODO what if both are non-zero? does it occur?
// TODO EBEB check this!!!!
swap_predecessors = (signs2.first != CGAL::POSITIVE);
// no perimetric in top-bottom for second loop
CGAL_precondition(signs2.second == CGAL::ZERO);
// but only if the at least one of the loops is perimetric, otherwise return false
// to let leftmost-vertex decide which becomes part of the new outer ccb
return signs1.first != CGAL::ZERO || signs2.first != CGAL::ZERO;
}
// choose prev1 to define outer ccb of new face if it is a non-perimetric loop,
// otherwise choose prev2
// TODO what if both are non-zero? does it occur?
// TODO EBEB check this!!!!
swap_predecessors = (signs2.first != CGAL::POSITIVE);
// but only if the at least one of the loops is perimetric, otherwise return
// false to let leftmost-vertex decide which becomes part of the new outer ccb
return (signs1.first != CGAL::ZERO) || (signs2.first != CGAL::ZERO);
}
/*! \brief given a curve end with boundary conditions and a face that contains
* the interior of the curve, find a place for a boundary vertex that will
* represent the curve end along the face boundary */
template <class GeomTraits, class Dcel>
template <typename GeomTraits, typename Dcel>
CGAL::Object
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
place_boundary_vertex(Face* /* f */,
@ -528,8 +539,8 @@ place_boundary_vertex(Face* /* f */,
CGAL_assertion((ps_x == ARR_LEFT_BOUNDARY) || (ps_x == ARR_RIGHT_BOUNDARY));
const Point_2& key = (ind == ARR_MIN_END) ?
m_traits->construct_min_vertex_2_object()(xc) :
m_traits->construct_max_vertex_2_object()(xc);
m_geom_traits->construct_min_vertex_2_object()(xc) :
m_geom_traits->construct_max_vertex_2_object()(xc);
typename Vertex_map::iterator it = m_boundary_vertices.find(key);
if (it != m_boundary_vertices.end()) {
@ -539,12 +550,12 @@ place_boundary_vertex(Face* /* f */,
// The vertex hasn't been created yet, return a null object:
return Object();
}
}
/*! \brief locate the predecessor halfedge for the given curve around a given
* vertex with boundary conditions. */
template <class GeomTraits, class Dcel>
typename Arr_spherical_topology_traits_2<GeomTraits, Dcel>::Halfedge*
template <typename GeomTraits, typename Dcel>
typename Arr_spherical_topology_traits_2<GeomTraits, Dcel>::Halfedge*
Arr_spherical_topology_traits_2<GeomTraits,Dcel>::
locate_around_boundary_vertex(Vertex* v,
const X_monotone_curve_2& xc,
@ -569,7 +580,7 @@ locate_around_boundary_vertex(Vertex* v,
}
/*! \brief locates a DCEL feature that contains a given curve end. */
template <class GeomTraits, class Dcel>
template <typename GeomTraits, typename Dcel>
CGAL::Object Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ind,
Arr_parameter_space ps_x, Arr_parameter_space ps_y)
@ -584,7 +595,7 @@ locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ind,
}
typename Vertex_map::iterator it;
Vertex* v = NULL;
Vertex* v = NULL;
if (ps_y == ARR_BOTTOM_BOUNDARY) {
// In case the curve end coincides with the south pole, return the vertex
@ -600,8 +611,8 @@ locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ind,
// discontinuity. If so, return this vertex. Otherwise, locate the first
// vertex above it.
const Point_2& key = (ind == ARR_MIN_END) ?
m_traits->construct_min_vertex_2_object()(xc) :
m_traits->construct_max_vertex_2_object()(xc);
m_geom_traits->construct_min_vertex_2_object()(xc) :
m_geom_traits->construct_max_vertex_2_object()(xc);
it = m_boundary_vertices.find(key);
if (it != m_boundary_vertices.end()) {
v = it->second;
@ -617,19 +628,19 @@ locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ind,
// we return the face that lies below the vertex v.
if (it == m_boundary_vertices.end())
return CGAL::make_object(m_spherical_face);
v = it->second;
return CGAL::make_object(_face_below_vertex_on_discontinuity(v));
}
/*! \brief determines whether a given boundary vertex is redundant */
template <class GeomTraits, class Dcel>
template <typename GeomTraits, typename Dcel>
bool Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
is_redundant(const Vertex* v) const
{ return (v->halfedge() == NULL); }
/* \brief erases a given redundant vertex */
template <class GeomTraits, class Dcel>
template <typename GeomTraits, typename Dcel>
typename Arr_spherical_topology_traits_2<GeomTraits, Dcel>::Halfedge*
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
erase_redundant_vertex(Vertex* v)
@ -650,9 +661,9 @@ erase_redundant_vertex(Vertex* v)
}
/*! \brief obtains the curve associated with a boundary vertex */
template <class GeomTraits, class Dcel>
template <typename GeomTraits, typename Dcel>
const typename
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::X_monotone_curve_2&
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::X_monotone_curve_2&
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
_curve(const Vertex* v, Arr_curve_end& ind) const
{
@ -666,7 +677,7 @@ _curve(const Vertex* v, Arr_curve_end& ind) const
* the predecessor of a halfedge, the curve of which is given, that is about
* to be inserted into the dcel.
*/
template <class GeomTraits, class Dcel>
template <typename GeomTraits, typename Dcel>
typename Arr_spherical_topology_traits_2<GeomTraits, Dcel>::Halfedge*
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
_locate_around_vertex_on_discontinuity(Vertex* v,
@ -689,11 +700,11 @@ _locate_around_vertex_on_discontinuity(Vertex* v,
// Otherwise, we traverse the halfedges around v until we find the pair
// of adjacent halfedges between which we should insert xc.
typename Traits_adaptor_2::Is_between_cw_2 is_between_cw =
m_traits->is_between_cw_2_object();
m_geom_traits->is_between_cw_2_object();
bool eq_curr, eq_next;
while (!is_between_cw(xc, (ind == ARR_MIN_END), curr->curve(),
(curr->direction() == ARR_RIGHT_TO_LEFT), next->curve(),
while (!is_between_cw(xc, (ind == ARR_MIN_END), curr->curve(),
(curr->direction() == ARR_RIGHT_TO_LEFT), next->curve(),
(next->direction() == ARR_RIGHT_TO_LEFT), v->point(),
eq_curr, eq_next))
{
@ -717,18 +728,17 @@ _locate_around_vertex_on_discontinuity(Vertex* v,
* that is the predecessor of a halfedge, the curve of which is given, that
* is about to be inserted into the dcel.
*/
template <class GeomTraits, class Dcel>
template <typename GeomTraits, typename Dcel>
typename Arr_spherical_topology_traits_2<GeomTraits, Dcel>::Halfedge*
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
_locate_around_pole(Vertex* v,
const X_monotone_curve_2& xc, Arr_curve_end ind) const
{
CGAL_assertion(v == m_south_pole || v == m_north_pole);
CGAL_assertion((v == m_south_pole) || (v == m_north_pole));
// std::cout << "locate_around_pole() " << ind << std::endl;
// If the vertex is isolated, return a null halfedge:
if (v->is_isolated())
return NULL;
if (v->is_isolated()) return NULL;
// Get the first incident halfedge around v and the next halfedge:
Halfedge* first = v->halfedge();
@ -743,15 +753,15 @@ _locate_around_pole(Vertex* v,
// pole, the result LARGER (resp. SMALLER) indicates that the line of
// discontinuity is located in between the two curves.
const Comparison_result cross_res = (v == m_south_pole) ? LARGER : SMALLER;
// Traverse all other halfedges, and compare their x-positions next to the
// pole with the query curve xc.
typename Traits_adaptor_2::Compare_x_curve_ends_2 cmp_x_curve_ends =
m_traits->compare_x_curve_ends_2_object();
m_geom_traits->compare_x_curve_ends_2_object();
Arr_curve_end curr_end, next_end;
Comparison_result curr_res, next_res;
Comparison_result curr_next_res;
curr_end =
(curr->direction() == ARR_RIGHT_TO_LEFT) ? ARR_MIN_END : ARR_MAX_END;
curr_res = cmp_x_curve_ends(xc, ind, curr->curve(), curr_end);
@ -787,14 +797,13 @@ _locate_around_pole(Vertex* v,
/*! \brief Return the face that lies below the given vertex, which lies
* on the line of discontinuity.
*/
template <class GeomTraits, class Dcel>
template <typename GeomTraits, typename Dcel>
typename Arr_spherical_topology_traits_2<GeomTraits, Dcel>::Face*
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
_face_below_vertex_on_discontinuity(Vertex* v) const
{
// If the vertex is isolated, just return the face that contains it.
if (v->is_isolated())
return (v->isolated_vertex()->face());
if (v->is_isolated()) return (v->isolated_vertex()->face());
// Get the first incident halfedge around v and the next halfedge.
Halfedge* first = v->halfedge();
@ -811,9 +820,9 @@ _face_below_vertex_on_discontinuity(Vertex* v) const
// halfedge we encounter if we go from "6 o'clock" clockwise.
// First locate the lower left and the top right halfedges around v.
typename Traits_adaptor_2::Compare_y_at_x_right_2 cmp_y_at_x_op_right =
m_traits->compare_y_at_x_right_2_object();
m_geom_traits->compare_y_at_x_right_2_object();
typename Traits_adaptor_2::Compare_y_at_x_left_2 cmp_y_at_x_op_left =
m_traits->compare_y_at_x_left_2_object();
m_geom_traits->compare_y_at_x_left_2_object();
Halfedge* lowest_left = NULL;
Halfedge* top_right = NULL;
@ -847,7 +856,7 @@ _face_below_vertex_on_discontinuity(Vertex* v) const
} while (curr != first);
// The first halfedge we encounter is the lowest to the left, but if there
// is no edge to the left, we first encounter the topmost halfedge to the
// is no edge to the left, we first encounter the topmost halfedge to the
// right. Note that as the halfedge we located has v as its target, we now
// have to return its twin.
first =
@ -864,7 +873,6 @@ _face_below_vertex_on_discontinuity(Vertex* v) const
first->inner_ccb()->face() : first->outer_ccb()->face());
}
} //namespace CGAL
#endif

View File

@ -14,7 +14,7 @@
//
// $URL$
// $Id$
//
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
@ -91,7 +91,7 @@ public:
};
//-----------------------------------------------------------------------------
// Memeber-function definitions:
// Member-function definitions:
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
@ -103,15 +103,15 @@ void Arr_unb_planar_batched_pl_helper<Tr, Arr>::before_sweep ()
// Initialize the fictitious halfedge lying on the top edge of the
// fictitious face. We start from the leftmost halfedge, which is
// incident to the top-left vertex and directed from right to left.
Vertex_const_handle v_tl =
Vertex_const_handle v_tl =
Vertex_const_handle (m_top_traits->top_left_vertex());
m_top_fict = v_tl->incident_halfedges();
if (m_top_fict->direction() == ARR_LEFT_TO_RIGHT)
m_top_fict = m_top_fict->next()->twin();
CGAL_assertion_code (
Vertex_const_handle v_tr =
Vertex_const_handle v_tr =
Vertex_const_handle (m_top_traits->top_right_vertex());
);
CGAL_assertion
@ -138,10 +138,10 @@ after_handle_event (Event* event)
if (event->parameter_space_in_x() != ARR_INTERIOR)
return;
if (event->parameter_space_in_y() == ARR_TOP_BOUNDARY)
m_top_fict = m_top_fict->twin()->next()->twin();
return;
}

View File

@ -14,7 +14,7 @@
//
// $URL$
// $Id$
//
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
@ -123,7 +123,7 @@ void Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::dcel_updated ()
// Go over the DCEL faces and locate the fictitious face.
typename Dcel::Face_iterator fit;
fict_face = NULL;
for (fit = this->m_dcel.faces_begin();
fit != this->m_dcel.faces_end(); ++fit)
@ -175,12 +175,12 @@ void Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::init_dcel ()
//
// he2
// v_tl (.) ----------------> (.) v_tr
// ^ <------------------
// ^ <------------------
// || ^|
// fict_face he1 || in_f ||
// || || he3
// |V ||
// ------------------> V
// ------------------> V
// v_bl (.) <---------------- (.) v_br
// he4
//
@ -257,13 +257,12 @@ are_equal(const Vertex *v,
// In case the given boundary conditions do not match those of the given
// vertex, v cannot represent the curve end.
if (ps_x != v->parameter_space_in_x() || ps_y != v->parameter_space_in_y())
return (false);
return false;
// Compare the curve end with the vertex.
Comparison_result res;
if (ps_x != ARR_INTERIOR)
{
if (ps_x != ARR_INTERIOR) {
// The curve end lies at x = +/- oo and so does v. Check if the curve
// overlaps with the curve that currently induces v.
Arr_curve_end v_ind;
@ -272,11 +271,11 @@ are_equal(const Vertex *v,
if (v_cv == NULL)
return (v->parameter_space_in_x() == ps_x &&
v->parameter_space_in_y() == ps_y);
res = this->traits->compare_y_curve_ends_2_object() (cv, *v_cv, v_ind);
res = this->m_geom_traits->compare_y_curve_ends_2_object()(cv,
*v_cv, v_ind);
}
else
{
else {
CGAL_assertion (ps_y != ARR_INTERIOR);
// The curve end lies at y = +/- oo and so does v. Check if the curve
@ -289,7 +288,8 @@ are_equal(const Vertex *v,
v->parameter_space_in_y() == ps_y);
res =
this->traits->compare_x_curve_ends_2_object() (cv, ind, *v_cv, v_ind);
this->m_geom_traits->compare_x_curve_ends_2_object() (cv, ind,
*v_cv, v_ind);
}
return (res == EQUAL);
@ -416,10 +416,10 @@ split_fictitious_edge (Halfedge *e, Vertex *v)
// face.
Halfedge *he1 = e;
Halfedge *he2 = he1->opposite();
CGAL_assertion (! he1->is_on_inner_ccb());
Outer_ccb *oc1 = he1->outer_ccb();
CGAL_assertion (oc1->face()->is_unbounded());
CGAL_assertion (he2->is_on_inner_ccb());
@ -489,9 +489,9 @@ is_unbounded(const Face *f) const
if (curr->has_null_curve())
// Found a fictitious halfedge along the boundary: f is unbounded.
return (true);
curr = curr->next();
} while (curr != first);
// If we reached here, all halfedges along the face boundary are valid,
@ -512,7 +512,7 @@ is_redundant(const Vertex *v) const
// is no valid edge incident to it).
const Halfedge *first_he = v->halfedge();
const Halfedge *next_he = first_he->next()->opposite();
if (next_he->next()->opposite() == first_he)
{
CGAL_assertion (first_he->has_null_curve() && next_he->has_null_curve());
@ -604,7 +604,7 @@ compare_x (const Point_2& p, const Vertex* v) const
{
// First check if the vertex v lies at x = -oo (then it is obviously smaller
// than p), or at x = +oo (then it is obviously larger).
const Arr_parameter_space ps_x = v->parameter_space_in_x();
const Arr_parameter_space ps_x = v->parameter_space_in_x();
if (ps_x == ARR_LEFT_BOUNDARY)
return (LARGER);
@ -612,21 +612,23 @@ compare_x (const Point_2& p, const Vertex* v) const
return (SMALLER);
// Check if the vertex lies at y = +/- oo.
const Arr_parameter_space ps_y = v->parameter_space_in_y();
const Arr_parameter_space ps_y = v->parameter_space_in_y();
if (ps_y != ARR_INTERIOR)
{
// Compare the x-position of the vertical asymptote of the curve incident
// to v with the x-coodinate of p.
Arr_curve_end v_ind = ARR_MIN_END;
const X_monotone_curve_2 *v_cv = _curve (v, v_ind);
CGAL_assertion (v_cv != NULL);
return (this->traits->compare_x_point_curve_end_2_object() (p, *v_cv, v_ind));
Arr_curve_end v_ind = ARR_MIN_END;
const X_monotone_curve_2* v_cv = _curve (v, v_ind);
CGAL_assertion(v_cv != NULL);
return
(this->m_geom_traits->compare_x_point_curve_end_2_object()(p, *v_cv,
v_ind));
}
// In this case v represents a normal point, and we compare it with p.
return (this->traits->compare_x_2_object() (p, v->point()));
return (this->m_geom_traits->compare_x_2_object() (p, v->point()));
}
//-----------------------------------------------------------------------------
@ -639,37 +641,34 @@ compare_xy (const Point_2& p, const Vertex* v) const
{
// First check if the vertex v lies at x = -oo (then it is obviously smaller
// than p), or at x = +oo (then it is obviously larger).
const Arr_parameter_space ps_x = v->parameter_space_in_x();
const Arr_parameter_space ps_x = v->parameter_space_in_x();
if (ps_x == ARR_LEFT_BOUNDARY)
return (LARGER);
else if (ps_x == ARR_RIGHT_BOUNDARY)
return (SMALLER);
if (ps_x == ARR_LEFT_BOUNDARY) return (LARGER);
else if (ps_x == ARR_RIGHT_BOUNDARY) return (SMALLER);
// Check if the vertex lies at y = +/- oo.
const Arr_parameter_space ps_y = v->parameter_space_in_y();
const Arr_parameter_space ps_y = v->parameter_space_in_y();
if (ps_y != ARR_INTERIOR)
{
if (ps_y != ARR_INTERIOR) {
// Compare the x-position of the vertical asymptote of the curve incident
// to v with the x-coodinate of p.
Arr_curve_end v_ind = ARR_MIN_END;
const X_monotone_curve_2 *v_cv = _curve (v, v_ind);
Arr_curve_end v_ind = ARR_MIN_END;
const X_monotone_curve_2* v_cv = _curve (v, v_ind);
CGAL_assertion (v_cv != NULL);
Comparison_result res =
this->traits->compare_x_point_curve_end_2_object() (p, *v_cv, v_ind);
Comparison_result res =
this->m_geom_traits->compare_x_point_curve_end_2_object() (p, *v_cv,
v_ind);
if (res != EQUAL)
return (res);
if (res != EQUAL) return (res);
// In case of equality, consider whether v lies at y = -oo or at y = +oo.
return (ps_y == ARR_BOTTOM_BOUNDARY) ? LARGER : SMALLER;
}
// In this case v represents a normal point, and we compare it with p.
return (this->traits->compare_xy_2_object() (p, v->point()));
return (this->m_geom_traits->compare_xy_2_object()(p, v->point()));
}
//-----------------------------------------------------------------------------
@ -683,54 +682,52 @@ compare_y_at_x (const Point_2& p, const Halfedge* he) const
{
// In case of a valid edge, just compare p to its associated curve.
if (! he->has_null_curve())
return (this->traits->compare_y_at_x_2_object() (p, he->curve()));
return (this->m_geom_traits->compare_y_at_x_2_object()(p, he->curve()));
// Otherwise, determine on which edge of the bounding rectangle does he lie.
// Note this can be either the top edge or the bottom edge (and not the
// left or the right edge), as p must lie in its x-range.
CGAL_assertion ((he->vertex()->parameter_space_in_x() == ARR_INTERIOR) ||
(he->vertex()->parameter_space_in_x() !=
he->opposite()->vertex()->parameter_space_in_x()));
CGAL_assertion ((he->vertex()->parameter_space_in_y() != ARR_INTERIOR) &&
(he->vertex()->parameter_space_in_y() ==
he->opposite()->vertex()->parameter_space_in_y()));
CGAL_assertion((he->vertex()->parameter_space_in_x() == ARR_INTERIOR) ||
(he->vertex()->parameter_space_in_x() !=
he->opposite()->vertex()->parameter_space_in_x()));
CGAL_assertion((he->vertex()->parameter_space_in_y() != ARR_INTERIOR) &&
(he->vertex()->parameter_space_in_y() ==
he->opposite()->vertex()->parameter_space_in_y()));
// he lies on the bottom edge, so p is obviously above it.
if (he->vertex()->parameter_space_in_y() == ARR_BOTTOM_BOUNDARY)
// he lies on the bottom edge, so p is obviously above it.
return (LARGER);
return LARGER;
// he lies on the top edge, so p is obviously below it.
else
// he lies on the top edge, so p is obviously below it.
return (SMALLER);
return SMALLER;
}
//-----------------------------------------------------------------------------
// Get the curve associated with a boundary vertex.
//
template <class GeomTraits, class Dcel_>
template <typename GeomTraits, typename Dcel_>
const typename
Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::X_monotone_curve_2*
Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::X_monotone_curve_2*
Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::
_curve (const Vertex *v, Arr_curve_end& ind) const
_curve (const Vertex* v, Arr_curve_end& ind) const
{
// Go over the incident halfedges of v until encountering the halfedge
// associated with a valid curve (v should have three incident halfedges,
// two of the are fictitious and one associated with a curve).
const Halfedge *he = v->halfedge();
const Halfedge* he = v->halfedge();
while (he->has_null_curve())
{
while (he->has_null_curve()) {
he = he->next()->opposite();
if (he == v->halfedge())
// No incident curve were found:
return (NULL);
// No incident curve were found:
if (he == v->halfedge()) return (NULL);
}
// The halfedge he is directed toward v, so if it is directed from left to
// right, v represents the maximal end of cv, otherwise it represents its
// minimal end.
ind = (he->direction() == ARR_LEFT_TO_RIGHT) ? ARR_MAX_END : ARR_MIN_END;
// Return the x-monotone curve.
return &(he->curve());
}
@ -739,116 +736,101 @@ _curve (const Vertex *v, Arr_curve_end& ind) const
// Check whether the given infinite curve end lies on the given fictitious
// halfedge.
//
template <class GeomTraits, class Dcel_>
bool
template <typename GeomTraits, typename Dcel_>
bool
Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::
_is_on_fictitious_edge (const X_monotone_curve_2& cv, Arr_curve_end ind,
Arr_parameter_space ps_x, Arr_parameter_space ps_y,
const Halfedge *he,
bool& eq_source, bool& eq_target)
_is_on_fictitious_edge(const X_monotone_curve_2& cv, Arr_curve_end ind,
Arr_parameter_space ps_x, Arr_parameter_space ps_y,
const Halfedge* he,
bool& eq_source, bool& eq_target)
{
eq_source = false;
eq_target = false;
// Get the end-vertices of the edge.
const Vertex *v1 = he->opposite()->vertex();
const Vertex *v2 = he->vertex();
Comparison_result res1, res2;
Arr_curve_end v_ind = ARR_MIN_END;
const Vertex* v1 = he->opposite()->vertex();
const Vertex* v2 = he->vertex();
Comparison_result res1, res2;
Arr_curve_end v_ind = ARR_MIN_END;
// Check if this is a "vertical" ficitious edge.
Arr_parameter_space he_ps_x = v1->parameter_space_in_x();
if (he_ps_x != ARR_INTERIOR && he_ps_x == v2->parameter_space_in_x())
{
if ((he_ps_x != ARR_INTERIOR) && (he_ps_x == v2->parameter_space_in_x())) {
// If the edge lies on x = +/- oo, the curve endpoint must also lie there.
CGAL_assertion ((he_ps_x == ARR_LEFT_BOUNDARY) ||
(he_ps_x == ARR_RIGHT_BOUNDARY));
CGAL_assertion((he_ps_x == ARR_LEFT_BOUNDARY) ||
(he_ps_x == ARR_RIGHT_BOUNDARY));
if (he_ps_x != ps_x)
return (false);
if (he_ps_x != ps_x) return false;
// Compare the y-position of the curve end to the source vertex.
if (v1 == v_bl || v1 == v_br)
{
if ((v1 == v_bl) || (v1 == v_br)) {
// These vertices are below any curve.
res1 = LARGER;
}
else if (v1 == v_tl || v1 == v_tr)
{
else if ((v1 == v_tl) || (v1 == v_tr)) {
// These vertices are above any curve.
res1 = SMALLER;
}
else
{
const Arr_curve_end ind =
else {
const Arr_curve_end ind =
(ps_x == ARR_LEFT_BOUNDARY) ? ARR_MIN_END : ARR_MAX_END;
res1 =
this->traits->compare_y_curve_ends_2_object() (cv,
*_curve (v1, v_ind),
ind);
if (res1 == EQUAL)
{
this->m_geom_traits->compare_y_curve_ends_2_object()(cv,
*_curve (v1, v_ind),
ind);
if (res1 == EQUAL) {
eq_source = true;
return (true);
return true;
}
}
// Compare the y-position of the curve end to the target vertex.
if (v2 == v_bl || v2 == v_br)
{
if ((v2 == v_bl) || (v2 == v_br)) {
// These vertices are below any curve.
res2 = LARGER;
}
else if (v2 == v_tl || v2 == v_tr)
{
else if ((v2 == v_tl) || (v2 == v_tr)) {
// These vertices are above any curve.
res2 = SMALLER;
}
else
{
else {
const Arr_curve_end ind =
(ps_x == ARR_LEFT_BOUNDARY) ? ARR_MIN_END : ARR_MAX_END;
res2 =
this->traits->compare_y_curve_ends_2_object() (cv,
*_curve (v2, v_ind),
ind);
if (res2 == EQUAL)
{
this->m_geom_traits->compare_y_curve_ends_2_object()(cv,
*_curve (v2, v_ind),
ind);
if (res2 == EQUAL) {
eq_target = true;
return (true);
return true;
}
}
}
else
{
else {
// If we reched here, we have a "horizontal" fictitious halfedge.
Arr_parameter_space he_ps_y = v1->parameter_space_in_y();
CGAL_assertion ((he_ps_y == ARR_BOTTOM_BOUNDARY ||
he_ps_y == ARR_TOP_BOUNDARY) &&
he_ps_y == v2->parameter_space_in_y());
CGAL_assertion((he_ps_y == ARR_BOTTOM_BOUNDARY ||
he_ps_y == ARR_TOP_BOUNDARY) &&
he_ps_y == v2->parameter_space_in_y());
// If the edge lies on y = +/- oo, the curve endpoint must also lie there
// (and must not lies at x = +/- oo.
if (ps_x != ARR_INTERIOR || he_ps_y != ps_y)
return (false);
if ((ps_x != ARR_INTERIOR) || (he_ps_y != ps_y)) return false;
// Compare the x-position of the curve end to the source vertex.
if (v1 == v_bl || v1 == v_tl)
{
if ((v1 == v_bl) || (v1 == v_tl)) {
// These vertices are to the left of any curve.
res1 = LARGER;
}
else if (v1 == v_br || v1 == v_tr)
{
else if ((v1 == v_br) || (v1 == v_tr)) {
// These vertices are to the right of any curve.
res1 = SMALLER;
}
else
{
else {
const X_monotone_curve_2 *v_cv1 = _curve (v1, v_ind);
// Note that v1 is a non-fictitious vertex, therefore we expect it to
@ -858,37 +840,32 @@ _is_on_fictitious_edge (const X_monotone_curve_2& cv, Arr_curve_end ind,
// arrangement, but it hasn't been associated with a valid halfedge
// yet, as the insertion process is still ongoing.
// The comparison result in this case is trivial.
if (v_cv1 != NULL)
{
res1 = this->traits->compare_x_curve_ends_2_object() (cv, ind,
*v_cv1, v_ind);
if (res1 == EQUAL)
{
if (v_cv1 != NULL) {
res1 =
this->m_geom_traits->compare_x_curve_ends_2_object()(cv, ind,
*v_cv1, v_ind);
if (res1 == EQUAL) {
eq_source = true;
return (true);
return true;
}
}
else
{
else {
res1 = (ind == ARR_MIN_END) ? SMALLER : LARGER;
}
}
// Compare the x-position of the curve end to the target vertex.
if (v2 == v_bl || v2 == v_tl)
{
if ((v2 == v_bl) || (v2 == v_tl)) {
// These vertices are to the left of any curve.
res2 = LARGER;
}
else if (v2 == v_br || v2 == v_tr)
{
else if ((v2 == v_br) || (v2 == v_tr)) {
// These vertices are to the right of any curve.
res2 = SMALLER;
}
else
{
const X_monotone_curve_2 *v_cv2 = _curve (v2, v_ind);
else {
const X_monotone_curve_2* v_cv2 = _curve(v2, v_ind);
// Note that v2 is a non-fictitious vertex, therefore we expect it to
// be associated with a valid curve end. If this is not the case, we
@ -897,21 +874,19 @@ _is_on_fictitious_edge (const X_monotone_curve_2& cv, Arr_curve_end ind,
// arrangement, but it hasn't been associated with a valid halfedge
// yet, as the insertion process is still ongoing.
// The comparison result in this case is trivial.
if (v_cv2 != NULL)
{
res2 = this->traits->compare_x_curve_ends_2_object() (cv, ind,
*v_cv2, v_ind);
if (res2 == EQUAL)
{
if (v_cv2 != NULL) {
res2 =
this->m_geom_traits->compare_x_curve_ends_2_object()(cv, ind,
*v_cv2, v_ind);
if (res2 == EQUAL) {
eq_target = true;
return (true);
}
return true;
}
}
else
{
else {
res2 = (ind == ARR_MIN_END) ? SMALLER : LARGER;
}
}
}
}

View File

@ -14,16 +14,12 @@
//
// $URL$
// $Id$
//
//
// Author(s) : Idit Haran <haranidi@post.tau.ac.il>
#ifndef CGAL_ARR_TRIANGULATION_POINT_LOCATION_H
#define CGAL_ARR_TRIANGULATION_POINT_LOCATION_H
#include <CGAL/config.h>
#ifdef CGAL_DONT_SUBMIT
/*! \file
* Definition of the Arr_triangulation_point_location<Arrangement> template.
*/
@ -42,18 +38,17 @@
namespace CGAL {
/*! \class
* A class that answers point-location and queries
* on a planar arrangement using the triangulation algorithm.
* The Arrangement parameter corresponds to an arrangement instantiation.
* A class that answers point-location queries on an arrangement using the
* triangulation algorithm.
*/
template <class Arrangement_>
template <typename Arrangement_>
class Arr_triangulation_point_location : public Arr_observer<Arrangement_>
{
public:
typedef Arrangement_ Arrangement_2;
typedef typename Arrangement_2::Traits_2 Traits_2;
typedef typename Traits_2::Kernel Kernel;
typedef typename Arrangement_2::Geometry_traits_2 Geometry_traits_2;
typedef typename Geometry_traits_2::Kernel Kernel;
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
@ -64,29 +59,29 @@ public:
typedef typename Arrangement_2::Vertex_const_iterator Vertex_const_iterator;
typedef typename Arrangement_2::Edge_const_iterator Edge_const_iterator;
typedef typename Arrangement_2::Hole_const_iterator Hole_const_iterator;
typedef typename Arrangement_2::Halfedge_const_iterator
typedef typename Arrangement_2::Face_const_iterator Face_const_iterator;
typedef typename Arrangement_2::Halfedge_const_iterator
Halfedge_const_iterator;
typedef typename Arrangement_2::Halfedge_around_vertex_const_circulator
typedef typename Arrangement_2::Halfedge_around_vertex_const_circulator
Halfedge_around_vertex_const_circulator;
typedef typename Arrangement_2::Ccb_halfedge_const_circulator
typedef typename Arrangement_2::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;
typedef typename Arrangement_2::Isolated_vertex_const_iterator
Isolated_vertex_const_iterator;
typedef typename Traits_2::Point_2 Point_2;
typedef typename Traits_2::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Geometry_traits_2::Point_2 Point_2;
typedef typename Geometry_traits_2::X_monotone_curve_2 X_monotone_curve_2;
typedef std::list<Halfedge_const_handle> Edge_list;
typedef typename Edge_list::iterator Std_edge_iterator;
typedef std::list<Halfedge_const_handle> Edge_list;
typedef typename Edge_list::iterator Std_edge_iterator;
//----------------------------------------------------------
// Triangulation Types
//----------------------------------------------------------
typedef Triangulation_vertex_base_with_info_2<Vertex_const_handle, Kernel>
Vbb;
typedef Triangulation_vertex_base_with_info_2<Vertex_const_handle, Kernel>
Vbb;
typedef Triangulation_hierarchy_vertex_base_2<Vbb> Vb;
//typedef Triangulation_face_base_with_info_2<CGAL::Color,Kernel> Fbt;
typedef Constrained_triangulation_face_base_2<Kernel> Fb;
@ -113,13 +108,13 @@ public:
typedef Result_type result_type;
protected:
typedef Arr_traits_basic_adaptor_2<Traits_2> Traits_adaptor_2;
typedef Arr_traits_basic_adaptor_2<Geometry_traits_2> Traits_adaptor_2;
// Data members:
const Traits_adaptor_2* m_traits; // Its associated traits object.
bool ignore_notifications;
CDT cdt;
bool updated_cdt;
bool m_ignore_notifications;
bool m_ignore_remove_edge;
CDT m_cdt;
template<typename T>
Result_type make_result(T t) const { return Result::make_result(t); }
@ -127,211 +122,263 @@ protected:
public:
/*! Default constructor. */
Arr_triangulation_point_location() : m_traits(NULL) {}
Arr_triangulation_point_location() :
m_traits(NULL),
m_ignore_notifications(false),
m_ignore_remove_edge(false)
{}
/*! Constructor given an arrangement. */
/*! Constructor from an arrangement.
* \param arr (in) The arrangement.
*/
Arr_triangulation_point_location(const Arrangement_2& arr) :
Arr_observer<Arrangement_2>(const_cast<Arrangement_2 &>(arr))
Arr_observer<Arrangement_2>(const_cast<Arrangement_2&>(arr)),
m_traits(static_cast<const Traits_adaptor_2*>(arr.geometry_traits())),
m_ignore_notifications(false),
m_ignore_remove_edge(false)
{ build_triangulation(); }
/*!
* Locate the arrangement feature containing the given point.
* \param p The query point.
/*! Locate the arrangement feature containing the given point.
* \param p (in) The query point.
* \return An object representing the arrangement feature containing the
* query point. This object is either a Face_const_handle or a
* Halfedge_const_handle or a Vertex_const_handle.
*/
result_type locate(const Point_2& p) const;
//Observer functions that are relevant to overload
//-------------------------------------------------
//Observer functions that are relevant to overload
//-------------------------------------------------
/*! Attach an arrangement object. */
virtual void before_attach(const Arrangement_2& arr)
{ m_traits = static_cast<const Traits_adaptor_2*>(arr.traits()); }
/*! Attach an arrangement.
* \param arr (in) The arrangement.
*/
virtual void before_attach(const Arrangement_2& arr)
{ m_traits = static_cast<const Traits_adaptor_2*>(arr.geometry_traits()); }
virtual void after_attach()
{ build_triangulation(); }
virtual void after_attach() { build_triangulation(); }
virtual void before_detach()
{ clear_triangulation(); }
virtual void before_detach() { clear_triangulation(); }
/*!
* Notification after the arrangement has been assigned with another
* arrangement.
* \param u A handle to the unbounded face.
*/
virtual void after_assign()
{
/// \name Overloaded observer functions on global changes.
//@{
/*! Notification after the arrangement has been assigned with another
* arrangement.
*/
virtual void after_assign()
{
clear_triangulation();
build_triangulation();
}
/*! Notification after the arrangement is cleared.
*/
virtual void after_clear()
{
clear_triangulation();
build_triangulation();
}
/*! Notification before a global operation modifies the arrangement.
*/
virtual void before_global_change()
{
clear_triangulation();
m_ignore_notifications = true;
}
/*! Notification after a global operation is completed.
*/
virtual void after_global_change()
{
build_triangulation();
m_ignore_notifications = false;
}
//@}
/// \name Overloaded observer functions on local changes.
//@{
/*! Notification before the removal of an edge.
* \param e (in) A handle to one of the twin halfedges to be removed.
*/
virtual void before_remove_edge(Halfedge_handle /* e */)
{ m_ignore_remove_edge = true; }
/*! Notification after the creation of a new vertex.
* \param v (in) A handle to the created vertex.
*/
virtual void after_create_vertex(Vertex_handle /* v */)
{
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
}
}
/*!
* Notification after the arrangement is cleared.
* \param u A handle to the unbounded face.
*/
virtual void after_clear()
{
/*! Notification after the creation of a new edge.
* \param e (in) A handle to one of the twin halfedges that were created.
*/
virtual void after_create_edge(Halfedge_handle /* e */)
{
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
}
}
/*! Notification before a global operation modifies the arrangement. */
virtual void before_global_change()
{
/*! Notification after an edge was split.
* \param e1 (in) A handle to one of the twin halfedges forming the first edge.
* \param e2 (in) A handle to one of the twin halfedges forming the second edge.
*/
virtual void after_split_edge(Halfedge_handle /* e1 */,
Halfedge_handle /* e2 */)
{
if (! m_ignore_notifications) {
clear_triangulation();
ignore_notifications = true;
}
/*! Notification after a global operation is completed. */
virtual void after_global_change()
{
build_triangulation();
ignore_notifications = false;
}
}
/*!
* Notification after the creation of a new vertex.
* \param v A handle to the created vertex.
*/
virtual void after_create_vertex(Vertex_handle /* v */)
{
if (! ignore_notifications) {
clear_triangulation();
build_triangulation();
}
/*! Notification after a face was split.
* \param f (in) A handle to the face we have just split.
* \param new_f (in) A handle to the new face that has been created.
* \param is_hole (in) Whether the new face forms a hole inside f.
*/
virtual void after_split_face(Face_handle /* f */,
Face_handle /* new_f */,
bool /* is_hole */)
{
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
}
}
/*!
* Notification after the creation of a new edge.
* \param e A handle to one of the twin halfedges that were created.
*/
virtual void after_create_edge(Halfedge_handle /* e */)
{
if (! ignore_notifications) {
clear_triangulation();
build_triangulation();
}
/*! Notification after an outer CCB was created inside a face.
* \param h (in) A circulator representing the boundary of the new outer CCB.
*/
virtual void after_add_outer_ccb(Ccb_halfedge_circulator /* h */)
{
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
}
}
/*!
* Notification after an edge was split.
* \param e1 A handle to one of the twin halfedges forming the first edge.
* \param e2 A handle to one of the twin halfedges forming the second edge.
*/
virtual void after_split_edge(Halfedge_handle /* e1 */,
Halfedge_handle /* e2 */)
{
if (! ignore_notifications) {
clear_triangulation();
build_triangulation();
}
/*! Notification after an edge was merged.
* \param e (in) A handle to one of the twin halfedges forming the merged edge.
*/
virtual void after_merge_edge(Halfedge_handle /* e */)
{
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
}
}
/*!
* Notification after a face was split.
* \param f A handle to the face we have just split.
* \param new_f A handle to the new face that has been created.
* \param is_hole Whether the new face forms a hole inside f.
*/
virtual void after_split_face(Face_handle /* f */,
Face_handle /* new_f */,
bool /* is_hole */)
{
if (! ignore_notifications) {
clear_triangulation();
build_triangulation();
}
/*! Notification after a face was merged.
* \param f (in) A handle to the merged face.
*/
virtual void after_merge_face(Face_handle /* f */)
{
if (! m_ignore_notifications && ! m_ignore_remove_edge) {
clear_triangulation();
build_triangulation();
}
}
/*!
* Notification after a hole was created inside a face.
* \param h A circulator representing the boundary of the new hole.
*/
virtual void after_add_hole(Ccb_halfedge_circulator /* h */)
{
if (! ignore_notifications) {
clear_triangulation();
build_triangulation();
}
/*! Notification after an outer CCB is moved from one face to another.
* \param h (in) A circulator representing the boundary of the component.
*/
virtual void after_move_outer_ccb(Ccb_halfedge_circulator /* h */)
{
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
}
}
/*!
* Notification after an edge was merged.
* \param e A handle to one of the twin halfedges forming the merged edge.
*/
virtual void after_merge_edge(Halfedge_handle /* e */)
{
if (! ignore_notifications) {
clear_triangulation();
build_triangulation();
}
/*! Notificaion before the removal of a vertex.
* \param v (in) A handle to the vertex to be deleted.
*/
virtual void after_remove_vertex()
{
if (! m_ignore_notifications && ! m_ignore_remove_edge) {
clear_triangulation();
build_triangulation();
}
}
/*!
* Notification after a face was merged.
* \param f A handle to the merged face.
*/
virtual void after_merge_face(Face_handle /* f */)
{
if (! ignore_notifications) {
clear_triangulation();
build_triangulation();
}
/*! Notification before the removal of an edge.
* \param e (in) A handle to one of the twin halfedges to be deleted.
*/
virtual void after_remove_edge()
{
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
}
m_ignore_remove_edge = false;
}
/*!
* Notification after a hole is moved from one face to another.
* \param h A circulator representing the boundary of the hole.
*/
virtual void after_move_hole(Ccb_halfedge_circulator /* h */)
{
if (! ignore_notifications) {
clear_triangulation();
build_triangulation();
}
/*! Notification before the removal of an outer CCB.
* \param f (in) The face that used to own the outer CCB.
*/
virtual void after_remove_outer_ccb(Face_handle /* f */)
{
if (! m_ignore_notifications && ! m_ignore_remove_edge) {
clear_triangulation();
build_triangulation();
}
}
/*!
* Notificaion before the removal of a vertex.
* \param v A handle to the vertex to be deleted.
*/
virtual void after_remove_vertex()
{
if (! ignore_notifications) {
clear_triangulation();
build_triangulation();
}
/*! Notification after an inner CCB was created inside a face.
* \param h (in) A circulator representing the boundary of the new inner CCB.
*/
virtual void after_add_inner_ccb(Ccb_halfedge_circulator /* h */)
{
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
}
}
/*!
* Notification before the removal of an edge.
* \param e A handle to one of the twin halfedges to be deleted.
*/
virtual void after_remove_edge()
{
if (! ignore_notifications) {
clear_triangulation();
build_triangulation();
}
/*! Notification after an inner CCB is moved from one face to another.
* \param h (in) A circulator representing the boundary of the component.
*/
virtual void after_move_inner_ccb(Ccb_halfedge_circulator /* h */)
{
if (! m_ignore_notifications) {
clear_triangulation();
build_triangulation();
}
}
/*!
* Notification before the removal of a hole.
* \param h A circulator representing the boundary of the hole.
*/
virtual void after_remove_hole()
{
if (! ignore_notifications) {
clear_triangulation();
build_triangulation();
}
/*! Notificaion after the removal of an inner CCB.
* \param f (in) The face that used to contain the inner CCB.
*/
virtual void after_remove_inner_ccb(Face_handle /* f */)
{
if (! m_ignore_notifications && ! m_ignore_remove_edge) {
clear_triangulation();
build_triangulation();
}
}
protected:
/*! Locate the arrangement feature containing the given point in the
* unbounded face(s).
* \param p (in) The query point.
* \return An object representing the arrangement feature containing the
* query point. This object is either a Face_const_handle
* representing an unbounded face or a Vertex_const_handle
* representing an isolated vertex.
*/
result_type locate_in_unbounded(const Point_2& p) const;
void clear_triangulation();
void build_triangulation();
void build_triangulation();
};
} //namespace CGAL
@ -339,6 +386,4 @@ protected:
// The member-function definitions can be found under:
#include <CGAL/Arr_point_location/Arr_triangulation_pl_functions.h>
#endif // CGAL_DONT_SUBMIT
#endif

View File

@ -38,25 +38,23 @@
namespace CGAL {
// Forward declaration:
template <class GeomTraits_, class TopTraits_>
template <typename GeomTraits_, typename TopTraits_>
class Arrangement_on_surface_2;
/*! \class Arr_unb_planar_topology_traits_2
* A topology-traits class that encapsulates the embedding of 2D arrangements
* of unbounded curves on the plane.
*/
template <class GeomTraits_,
class Dcel_ = Arr_default_dcel<GeomTraits_> >
template <typename GeomTraits_,
typename Dcel_ = Arr_default_dcel<GeomTraits_> >
class Arr_unb_planar_topology_traits_2 :
public Arr_planar_topology_traits_base_2<GeomTraits_, Dcel_>
{
private:
typedef Arr_planar_topology_traits_base_2<GeomTraits_,
Dcel_> Base;
typedef Arr_planar_topology_traits_base_2<GeomTraits_, Dcel_>
Base;
public:
///! \name The geometry-traits types.
//@{
typedef GeomTraits_ Geometry_traits_2;
@ -76,7 +74,6 @@ public:
typedef typename Base::Isolated_vertex Isolated_vertex;
//@}
//! \name Arrangement types
//!@{
typedef Arr_unb_planar_topology_traits_2<Geometry_traits_2, Dcel> Self;
@ -120,46 +117,43 @@ public:
* An auxiliary structure for rebinding the topology traits with a new
* geometry-traits class and a new DCEL class.
*/
template<typename T, typename D>
struct rebind
{
typedef Arr_unb_planar_topology_traits_2<T,D> other;
template <typename T, typename D>
struct rebind {
typedef Arr_unb_planar_topology_traits_2<T, D> other;
};
protected:
// Data members:
Vertex *v_bl; // A fictitious vertex at (-oo,-oo).
Vertex *v_tl; // A fictitious vertex at (-oo,+oo).
Vertex *v_br; // A fictitious vertex at (-oo,+oo).
Vertex *v_tr; // A fictitious vertex at (+oo,+oo).
Size n_inf_verts; // Number of vertices at infinity.
Face *fict_face; // The fictitious DCEL face.
Vertex* v_bl; // A fictitious vertex at (-oo,-oo).
Vertex* v_tl; // A fictitious vertex at (-oo,+oo).
Vertex* v_br; // A fictitious vertex at (-oo,+oo).
Vertex* v_tr; // A fictitious vertex at (+oo,+oo).
Size n_inf_verts; // Number of vertices at infinity.
Face* fict_face; // The fictitious DCEL face.
// Copy constructor and assignment operator - not supported.
Arr_unb_planar_topology_traits_2 (const Self& );
Self& operator= (const Self& );
Arr_unb_planar_topology_traits_2(const Self&);
Self& operator=(const Self&);
public:
///! \name Construction methods.
//@{
/*! Default constructor. */
Arr_unb_planar_topology_traits_2 ();
Arr_unb_planar_topology_traits_2();
/*! Constructor with a geometry-traits class. */
Arr_unb_planar_topology_traits_2 (const Geometry_traits_2 *tr);
Arr_unb_planar_topology_traits_2(const Geometry_traits_2* tr);
/*! Assign the contents of another topology-traits class. */
void assign (const Self& other);
void assign(const Self& other);
//@}
///! \name Accessing the DCEL and constructing iterators.
//@{
/*! Determine whether the DCEL reprsenets an empty structure. */
bool is_empty_dcel () const
bool is_empty_dcel() const
{
// An empty arrangement contains just two four vertices at infinity
// and eight fictitious halfedges connecting them.
@ -168,40 +162,40 @@ public:
}
/*! Check if the given vertex is concrete (associated with a point). */
bool is_concrete_vertex (const Vertex *v) const
bool is_concrete_vertex(const Vertex* v) const
{
return (! v->has_null_point());
}
/*! Get the number of concrete vertices. */
Size number_of_concrete_vertices () const
Size number_of_concrete_vertices() const
{
// All vertices not lying at infinity are concrete.
return (this->m_dcel.size_of_vertices() - n_inf_verts);
}
/*! Check if the given vertex is valid (not a fictitious one). */
bool is_valid_vertex (const Vertex *v) const
bool is_valid_vertex(const Vertex* v) const
{
return (! v->has_null_point() ||
(v != v_bl && v != v_tl && v != v_br && v != v_tr));
}
/*! Get the number of valid vertices. */
Size number_of_valid_vertices () const
Size number_of_valid_vertices() const
{
// All vertices, except the four fictitious one, are valid.
return (this->m_dcel.size_of_vertices() - 4);
}
/*! Check if the given halfedge is valid (not a fictitious one). */
bool is_valid_halfedge (const Halfedge *he) const
bool is_valid_halfedge(const Halfedge* he) const
{
return (! he->has_null_curve());
}
/*! Get the number of valid halfedges. */
Size number_of_valid_halfedges () const
Size number_of_valid_halfedges() const
{
// Note that we do not count fictitious halfedges (each vertex at infinity
// induces two fictitious halfedges).
@ -209,13 +203,13 @@ public:
}
/*! Check if the given face is valid (not a fictitious one). */
bool is_valid_face (const Face *f) const
bool is_valid_face (const Face* f) const
{
return (! f->is_fictitious());
}
/*! Get the number of valid faces. */
Size number_of_valid_faces () const
Size number_of_valid_faces() const
{
// We do not count the ficitious DCEL face.
return (this->m_dcel.size_of_faces() - 1);
@ -223,16 +217,14 @@ public:
//@}
private:
/// \name Auxiliary type definitions.
//@{
typedef Arrangement_on_surface_2<Geometry_traits_2, Self> Arr;
typedef Arrangement_on_surface_2<Geometry_traits_2, Self> Arr;
// Type definition for the constuction sweep-line visitor.
typedef Arr_construction_subcurve<Geometry_traits_2> CSubcurve;
typedef Arr_construction_event<Geometry_traits_2,
CSubcurve,
Arr> CEvent;
typedef Arr_construction_event<Geometry_traits_2, CSubcurve, Arr>
CEvent;
typedef Arr_unb_planar_construction_helper<Geometry_traits_2,
Arr,
CEvent,
@ -241,24 +233,18 @@ private:
// Type definition for the basic insertion sweep-line visitor.
typedef Arr_basic_insertion_traits_2<Geometry_traits_2, Arr> BInsTraits;
typedef Arr_construction_subcurve<BInsTraits> BISubcurve;
typedef Arr_construction_event<BInsTraits,
BISubcurve,
Arr> BIEvent;
typedef Arr_unb_planar_insertion_helper<BInsTraits,
Arr,
BIEvent,
BISubcurve> BIHelper;
typedef Arr_construction_event<BInsTraits, BISubcurve, Arr>
BIEvent;
typedef Arr_unb_planar_insertion_helper<BInsTraits, Arr, BIEvent, BISubcurve>
BIHelper;
// Type definition for the insertion sweep-line visitor.
typedef Arr_insertion_traits_2<Geometry_traits_2, Arr> InsTraits;
typedef Arr_construction_subcurve<InsTraits> ISubcurve;
typedef Arr_construction_event<InsTraits,
ISubcurve,
Arr> IEvent;
typedef Arr_unb_planar_insertion_helper<InsTraits,
Arr,
IEvent,
ISubcurve> IHelper;
typedef Arr_construction_event<InsTraits, ISubcurve, Arr>
IEvent;
typedef Arr_unb_planar_insertion_helper<InsTraits, Arr, IEvent, ISubcurve>
IHelper;
// Type definition for the batched point-location sweep-line visitor.
typedef Arr_batched_point_location_traits_2<Arr> BplTraits;
@ -292,15 +278,12 @@ private:
typedef typename Base::Subcurve Subcurve;
typedef typename Base::Construction_helper Construction_helper;
_Overlay_helper (const ArrangementA_ *arrA,
const ArrangementB_ *arrB) :
Base (arrA, arrB)
{}
_Overlay_helper(const ArrangementA_* arrA, const ArrangementB_* arrB) :
Base(arrA, arrB) {}
};
//@}
public:
///! \name Visitor types.
//@{
@ -338,17 +321,16 @@ public:
public Arr_vert_decomp_sl_visitor<VdHelper, OutputIterator_>
{
typedef OutputIterator_ Output_iterator;
typedef Arr_vert_decomp_sl_visitor<VdHelper,
Output_iterator> Base;
typedef Arr_vert_decomp_sl_visitor<VdHelper, Output_iterator>
Base;
typedef typename Base::Traits_2 Traits_2;
typedef typename Base::Event Event;
typedef typename Base::Subcurve Subcurve;
Sweep_line_vertical_decomposition_visitor (const Arr *arr,
Output_iterator *oi) :
Base (arr, oi)
{}
Sweep_line_vertical_decomposition_visitor(const Arr* arr,
Output_iterator* oi) :
Base(arr, oi) {}
};
template <class ArrangementA_, class ArrangementB_, class OverlayTraits_>
@ -381,19 +363,22 @@ public:
typedef typename Base::Event Event;
typedef typename Base::Subcurve Subcurve;
Sweep_line_overlay_visitor (const ArrangementA_2 *arrA,
const ArrangementB_2 *arrB,
Arrangement_result_2 *arr_res,
Overlay_traits *overlay_tr) :
Base (arrA, arrB, arr_res, overlay_tr)
Sweep_line_overlay_visitor(const ArrangementA_2* arrA,
const ArrangementB_2* arrB,
Arrangement_result_2* arr_res,
Overlay_traits* overlay_tr) :
Base(arrA, arrB, arr_res, overlay_tr)
{}
};
typedef Arr_inc_insertion_zone_visitor<Arr>
Zone_insertion_visitor;
Zone_insertion_visitor;
typedef Arr_walk_along_line_point_location<Arr>
Default_point_location_strategy;
Default_point_location_strategy;
typedef Arr_walk_along_line_point_location<Arr>
Default_vertical_ray_shooting_strategy;
//@}
///! \name Topology-traits methods.
@ -402,12 +387,12 @@ public:
/*!
* Initialize an empty DCEL structure.
*/
void init_dcel ();
void init_dcel();
/*!
* Make the necessary updates after the DCEL structure have been updated.
*/
void dcel_updated ();
void dcel_updated();
/*!
* Check if the given vertex is associated with the given curve end.
@ -419,9 +404,9 @@ public:
* \pre The curve has a boundary condition in either x or y.
* \return Whether v represents the given curve end.
*/
bool are_equal (const Vertex *v,
const X_monotone_curve_2& cv, Arr_curve_end ind,
Arr_parameter_space ps_x, Arr_parameter_space ps_y) const;
bool are_equal(const Vertex* v,
const X_monotone_curve_2& cv, Arr_curve_end ind,
Arr_parameter_space ps_x, Arr_parameter_space ps_y) const;
/*!
* Given a curve end with boundary conditions and a face that contains the
@ -436,11 +421,11 @@ public:
* \return An object that contains the curve end.
* In our case this object always wraps a fictitious edge.
*/
CGAL::Object place_boundary_vertex (Face *f,
const X_monotone_curve_2& cv,
Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
CGAL::Object place_boundary_vertex(Face* f,
const X_monotone_curve_2& cv,
Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
/*!
* Locate the predecessor halfedge for the given curve around a given
@ -455,11 +440,11 @@ public:
* \return An object that contains the curve end.
*/
Halfedge*
locate_around_boundary_vertex (Vertex* /* v */,
const X_monotone_curve_2& /* cv */,
Arr_curve_end /* ind */,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */) const
locate_around_boundary_vertex(Vertex* /* v */,
const X_monotone_curve_2& /* cv */,
Arr_curve_end /* ind */,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */) const
{
CGAL_error();
return (NULL);
@ -476,10 +461,10 @@ public:
* In our case this object may either wrap an unbounded face,
* or an edge with an end-vertex at infinity (in case of an overlap).
*/
CGAL::Object locate_curve_end (const X_monotone_curve_2& cv,
Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
CGAL::Object locate_curve_end(const X_monotone_curve_2& cv,
Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
/*!
* Split a fictitious edge using the given vertex.
@ -489,21 +474,21 @@ public:
* \return A halfedge whose direction is the same as e's and whose target is
* the split vertex v.
*/
Halfedge* split_fictitious_edge (Halfedge *e, Vertex *v);
Halfedge* split_fictitious_edge(Halfedge* e, Vertex* v);
/*!
* Determine whether the given face is unbounded.
* \param f The face.
* \return Whether f is unbounded.
*/
bool is_unbounded (const Face *f) const;
bool is_unbounded(const Face* f) const;
/*!
* Determine whether the given boundary vertex is redundant.
* \param v The vertex.
* \return Whether v is redundant, and should be erased.
*/
bool is_redundant (const Vertex *v) const;
bool is_redundant(const Vertex* v) const;
/*!
* Erase the given redundant vertex by merging a fictitious edge.
@ -512,7 +497,7 @@ public:
* \pre v is a redundant vertex.
* \return One of the pair of halfedges that form the merged edge.
*/
Halfedge* erase_redundant_vertex (Vertex *v);
Halfedge* erase_redundant_vertex(Vertex* v);
//! reference_face (const version).
/*! The function returns a reference face of the arrangement.
@ -544,70 +529,37 @@ public:
//@{
/*! This function is used by the "walk" point-location strategy. */
const Face* initial_face () const
{
return (fict_face);
}
const Face* initial_face() const { return fict_face; }
/*! Get the fictitious face (const version). */
const Face* fictitious_face () const
{
return (fict_face);
}
const Face* fictitious_face() const { return fict_face; }
/*! Get the fictitious face (non-const version). */
Face* fictitious_face ()
{
return (fict_face);
}
Face* fictitious_face() { return fict_face; }
/*! Get the bottom-left fictitious vertex (const version). */
const Vertex* bottom_left_vertex () const
{
return (v_bl);
}
const Vertex* bottom_left_vertex() const { return (v_bl); }
/*! Get the bottom-left fictitious vertex (non-const version). */
Vertex* bottom_left_vertex ()
{
return (v_bl);
}
Vertex* bottom_left_vertex() { return (v_bl); }
/*! Get the top-left fictitious vertex (const version). */
const Vertex* top_left_vertex () const
{
return (v_tl);
}
const Vertex* top_left_vertex() const { return (v_tl); }
/*! Get the top-left fictitious vertex (non-const version). */
Vertex* top_left_vertex ()
{
return (v_tl);
}
Vertex* top_left_vertex() { return (v_tl); }
/*! Get the bottom-right fictitious vertex (const version). */
const Vertex* bottom_right_vertex () const
{
return (v_br);
}
const Vertex* bottom_right_vertex() const { return (v_br); }
/*! Get the bottom-right fictitious vertex (non-const version). */
Vertex* bottom_right_vertex ()
{
return (v_br);
}
Vertex* bottom_right_vertex() { return (v_br); }
/*! Get the top-right fictitious vertex (const version). */
const Vertex* top_right_vertex () const
{
return (v_tr);
}
const Vertex* top_right_vertex() const { return (v_tr); }
/*! Get the top-right fictitious vertex (non-const version). */
Vertex* top_right_vertex ()
{
return (v_tr);
}
Vertex* top_right_vertex() { return (v_tr); }
//@}
/// \name Additional predicates, specialized for this topology-traits class.
@ -619,8 +571,8 @@ public:
* \param v The vertex.
* \return The result of the comparison of the x-coordinates of p and v.
*/
virtual Comparison_result compare_x (const Point_2& p,
const Vertex* v) const;
virtual Comparison_result compare_x(const Point_2& p,
const Vertex* v) const;
/*!
* Compare the given vertex (which may lie at infinity) and the given point.
@ -628,8 +580,8 @@ public:
* \param v The vertex.
* \return The result of the xy-lexicographic comparison of p and v.
*/
virtual Comparison_result compare_xy (const Point_2& p,
const Vertex* v) const;
virtual Comparison_result compare_xy(const Point_2& p,
const Vertex* v) const;
/*!
* Compare the relative y-position of the given point and the given edge
@ -639,8 +591,8 @@ public:
* \pre p should lie in the x-range of the given edge.
* \return The relative y-position of the point p and the edge.
*/
virtual Comparison_result compare_y_at_x (const Point_2& p,
const Halfedge* he) const;
virtual Comparison_result compare_y_at_x(const Point_2& p,
const Halfedge* he) const;
//@}
protected:
@ -656,7 +608,7 @@ protected:
* \pre v is a valid (not fictitious) boundary.
* \return The curve that induces v, or NULL if v has no incident curves yet.
*/
const X_monotone_curve_2* _curve (const Vertex *v, Arr_curve_end& ind) const;
const X_monotone_curve_2* _curve(const Vertex* v, Arr_curve_end& ind) const;
/*!
* Check whether the given infinite curve end lies on the given fictitious
@ -670,10 +622,10 @@ protected:
* \param eq_target Output: Whether the curve coincides with he's target.
* \return Whether the curve end lies on the fictitious halfedge.
*/
bool _is_on_fictitious_edge (const X_monotone_curve_2& cv, Arr_curve_end ind,
bool _is_on_fictitious_edge(const X_monotone_curve_2& cv, Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y,
const Halfedge *he,
const Halfedge* he,
bool& eq_source, bool& eq_target);
//@}
};

View File

@ -189,16 +189,13 @@ void Arrangement_on_surface_2<GeomTraits, TopTraits>::assign(const Self& arr)
}
// Go over the edge and create duplicates of the stored curves.
X_monotone_curve_2* dup_cv;
DHalfedge* p_e;
typename Dcel::Edge_iterator eit;
for (eit = _dcel().edges_begin(); eit != _dcel().edges_end(); ++eit) {
p_e = &(*eit);
DHalfedge* p_e = &(*eit);
if (! p_e->has_null_curve()) {
// Create the duplicate curve and store it in the curves container.
dup_cv = _new_curve(p_e->curve());
X_monotone_curve_2* dup_cv = _new_curve(p_e->curve());
// Associate the halfedge (and its twin) with the duplicated curve.
p_e->set_curve(dup_cv);
@ -206,8 +203,10 @@ void Arrangement_on_surface_2<GeomTraits, TopTraits>::assign(const Self& arr)
}
// Take care of the traits object.
if (m_own_traits && m_geom_traits != NULL)
if (m_own_traits && (m_geom_traits != NULL)) {
delete m_geom_traits;
m_geom_traits = NULL;
}
m_geom_traits = (arr.m_own_traits) ? new Traits_adaptor_2 : arr.m_geom_traits;
m_own_traits = arr.m_own_traits;
@ -234,12 +233,11 @@ Arrangement_on_surface_2<GeomTraits, TopTraits>::~Arrangement_on_surface_2()
if (! eit->has_null_curve())
_delete_curve(eit->curve());
// Clear the DCEL.
_dcel().delete_all();
// Free the traits object, if necessary.
if (m_own_traits)
if (m_own_traits && (m_geom_traits != NULL)) {
delete m_geom_traits;
m_geom_traits = NULL;
}
// Detach all observers still attached to the arrangement.
Observers_iterator iter = m_observers.begin();

View File

@ -0,0 +1,469 @@
#ifndef CGAL_BATCHED_POINT_LOCATION_TEST_H
#define CGAL_BATCHED_POINT_LOCATION_TEST_H
#include <vector>
#include <list>
#include <utility>
#include <CGAL/basic.h>
#include <CGAL/Arr_batched_point_location.h>
#include <CGAL/Arr_point_location_result.h>
#include "IO_test.h"
/*! Point location test */
template <typename GeomTraits_T, typename TopolTraits_T>
class Batched_point_location_test : public IO_test<GeomTraits_T> {
public:
typedef GeomTraits_T Geom_traits;
typedef TopolTraits_T Topol_traits;
private:
typedef IO_test<Geom_traits> Base;
public:
typedef typename Base::Point_2 Point_2;
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Base::Curve_2 Curve_2;
typedef typename Base::Points_vector Points_vector;
typedef typename Base::Xcurves_vector Xcurves_vector;
typedef typename Base::Curves_vector Curves_vector;
typedef CGAL::Arrangement_on_surface_2<Geom_traits, Topol_traits>
Arrangement;
typedef typename Arrangement::Vertex_handle Vertex_handle;
typedef typename Arrangement::Halfedge_handle Halfedge_handle;
typedef typename Arrangement::Face_handle Face_handle;
typedef typename Arrangement::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement::Face_const_handle Face_const_handle;
typedef typename Arrangement::Edge_const_iterator Edge_const_iterator;
typedef typename Arrangement::Vertex_const_iterator Vertex_const_iterator;
typedef typename Points_vector::iterator Point_iterator;
typedef typename boost::variant<Vertex_const_handle,
Halfedge_const_handle,
Face_const_handle> Cell_handle;
typedef CGAL::Arr_point_location_result<Arrangement> Point_location_result;
typedef typename Point_location_result::Type Result_type;
typedef std::pair<Point_2, Result_type> Query_result;
protected:
/*! The geometry traits. */
const Geom_traits& m_geom_traits;
/*! The arrangement. */
Arrangement m_arr;
/*! The input data file of the query points. */
std::string m_filename_queries;
/*! The query points. */
Points_vector m_query_points;
/*! Verbosity */
size_t m_verbose_level;
/*! Verify the results.
*/
template <typename InputIterator>
bool verify(InputIterator begin, InputIterator end);
/*! print the results.
*/
void print(const std::pair<Point_2, Cell_handle>& res);
/*! print the results.
*/
void print(const std::pair<Point_2, CGAL::Object>& res);
/*! Compare the results.
*/
bool compare(const Cell_handle& expected, const Cell_handle& actual);
/*! Compare the results.
*/
bool compare(const CGAL::Object& expected, const CGAL::Object& actual);
public:
/*! Constructor from a geometry traits object.
*/
Batched_point_location_test(const Geom_traits& geom_traits);
/*! Destructor */
virtual ~Batched_point_location_test() { clear(); }
/*! Perform the test.
* \return true upon success and false otherwise.
*/
virtual bool perform();
/*! Clear the data structure. */
virtual void clear();
/*! Initialize the data structure.
* \return true upon success and false otherwise.
*/
virtual bool init();
/*! Set the file names.
*/
void set_filenames(const char* points_filename, const char* xcurves_filename,
const char* curves_filename, const char* queries_filename);
/*! Set the verbosity level.
*/
void set_verbose_level(size_t verbose_level);
};
/*!
* Constructor from a geometry traits object.
*/
template <typename GeomTraits_T, typename TopolTraits_T>
Batched_point_location_test<GeomTraits_T, TopolTraits_T>::
Batched_point_location_test(const Geom_traits& geom_traits) :
Base(geom_traits),
m_geom_traits(geom_traits),
m_verbose_level(0)
{}
//! \brief sets the file names.
template <typename GeomTraits_T, typename TopolTraits_T>
void Batched_point_location_test<GeomTraits_T, TopolTraits_T>::
set_filenames(const char* points_filename,
const char* xcurves_filename,
const char* curves_filename,
const char* queries_filename)
{
Base::set_filenames(points_filename, xcurves_filename, curves_filename);
m_filename_queries.assign(queries_filename);
}
//! \brief sets the verbosity level.
template <typename GeomTraits_T, typename TopolTraits_T>
void Batched_point_location_test<GeomTraits_T, TopolTraits_T>::
set_verbose_level(size_t verbose_level)
{ m_verbose_level = verbose_level; }
/*! Clear the data structures */
template <typename GeomTraits_T, typename TopolTraits_T>
void Batched_point_location_test<GeomTraits_T, TopolTraits_T>::clear()
{
m_arr.clear();
Base::clear();
m_query_points.clear();
m_filename_queries.clear();
}
template <typename GeomTraits_T, typename TopolTraits_T>
bool Batched_point_location_test<GeomTraits_T, TopolTraits_T>::init()
{
// Initialize the input.
if (!Base::init()) return false;
// Read the query points
if (!this->read_points(m_filename_queries.c_str(), m_query_points))
return false;
// Insert all into the arrangement
CGAL::insert(m_arr, this->m_xcurves.begin(), this->m_xcurves.end());
// insert(*m_arr, m_points.begin(), m_points.end());
CGAL::insert(m_arr, this->m_curves.begin(), this->m_curves.end());
// Print the size of the arrangement.
if (m_verbose_level > 1)
std::cout << "V = " << m_arr.number_of_vertices()
<< ", E = " << m_arr.number_of_edges()
<< ", F = " << m_arr.number_of_faces() << std::endl;
return true;
}
//! \brief performs the test.
template <typename GeomTraits_T, typename TopolTraits_T>
bool Batched_point_location_test<GeomTraits_T, TopolTraits_T>::perform()
{
// Apply batched point location.
std::list<Query_result> results;
locate(m_arr, m_query_points.begin(), m_query_points.end(),
std::back_inserter(results));
// Verify the results.
return verify(results.begin(), results.end());
}
//! \brief verifies the results.
template <typename GeomTraits_T, typename TopolTraits_T>
template <typename InputIterator>
bool Batched_point_location_test<GeomTraits_T, TopolTraits_T>::
verify(InputIterator begin, InputIterator end)
{
typedef TopolTraits_T TopolTraits;
typename TopolTraits::Default_point_location_strategy pl(m_arr);
for (InputIterator it = begin; it != end; ++it) {
if (m_verbose_level > 1)
print(*it);
// Perform (single) point location.
Result_type obj = pl.locate(it->first);
// Compare the results.
if (!compare(obj, it->second)) return false;
}
return true;
}
//! \brief compares the results.
template <typename GeomTraits_T, typename TopolTraits_T>
bool Batched_point_location_test<GeomTraits_T, TopolTraits_T>::
compare(const Cell_handle& expected, const Cell_handle& actual)
{
// Assign object to a face
const Face_const_handle* fh_expected =
boost::get<Face_const_handle>(&(expected));
if (fh_expected) {
const Face_const_handle* fh_actual =
boost::get<Face_const_handle>(&(actual));
if (fh_actual) {
if ((*fh_actual) == (*fh_expected)) return true;
std::cout << "Error: batched point location!" << std::endl;
std::cout << "Expected: a face." << std::endl;
std::cout << "Actual: a different face." << std::endl;
return false;
}
std::cout << "Error: batched point location!" << std::endl;
std::cout << "Expected a face." << std::endl;
const Halfedge_const_handle* hh_actual =
boost::get<Halfedge_const_handle>(&(actual));
if (hh_actual) {
std::cout << "Actual: a halfedge." << std::endl;
return false;
}
const Vertex_const_handle* vh_actual =
boost::get<Vertex_const_handle>(&(actual));
if (vh_actual) {
std::cout << "Actual: a vertex." << std::endl;
return false;
}
std::cout << "Actual: an unknowen object." << std::endl;
return false;
}
// Assign object to a halfedge
const Halfedge_const_handle* hh_expected =
boost::get<Halfedge_const_handle>(&(expected));
if (hh_expected) {
const Halfedge_const_handle* hh_actual =
boost::get<Halfedge_const_handle>(&(actual));
if (hh_actual) {
if (((*hh_actual) == (*hh_expected)) ||
((*hh_actual)->twin() == (*hh_expected)))
return true;
std::cout << "Error: batched point location!" << std::endl;
std::cout << "Expected: a halfedge, " << (*hh_expected)->curve()
<< std::endl;
std::cout << "Actual: a different halfedge, " << (*hh_actual)->curve()
<< std::endl;
return false;
}
std::cout << "Error: batched point location!" << std::endl;
std::cout << "Expected: a halfedge, " << (*hh_expected)->curve()
<< std::endl;
const Face_const_handle* fh_actual =
boost::get<Face_const_handle>(&(actual));
if (fh_actual) {
std::cout << "Actual: a face." << std::endl;
return false;
}
const Vertex_const_handle* vh_actual =
boost::get<Vertex_const_handle>(&(actual));
if (vh_actual) {
std::cout << "Actual: a vertex." << std::endl;
return false;
}
std::cout << "Actual: an unknowen object." << std::endl;
return false;
}
// Assign object to a vertex
const Vertex_const_handle* vh_expected =
boost::get<Vertex_const_handle>(&(expected));
if (vh_expected) {
const Vertex_const_handle* vh_actual =
boost::get<Vertex_const_handle>(&(actual));
if (vh_actual) {
if ((*vh_actual) == (*vh_expected)) return true;
std::cout << "Error: batched point location!" << std::endl;
std::cout << "Expected: a vertex, "<< (*vh_expected)->point()
<< std::endl;
std::cout << "Actual: a different vertex, " << (*vh_actual)->point()
<< std::endl;
return false;
}
std::cout << "Error: batched point location!";
std::cout << "Expected: a vertex, "<< (*vh_expected)->point() << std::endl;
const Face_const_handle* fh_actual =
boost::get<Face_const_handle>(&(actual));
if (fh_actual) {
std::cout << "Actual: a face" << std::endl;
return false;
}
const Halfedge_const_handle* hh_actual =
boost::get<Halfedge_const_handle>(&(actual));
if (hh_actual) {
std::cout << "Actual: a halfedge." << std::endl;
return false;
}
std::cout << "Actual: an unknown object." << std::endl;
return false;
}
std::cout << "Error: Unknown!" << std::endl;
return false;
}
//! \brief compares the results.
template <typename GeomTraits_T, typename TopolTraits_T>
bool Batched_point_location_test<GeomTraits_T, TopolTraits_T>::
compare(const CGAL::Object& expected, const CGAL::Object& actual)
{
Face_const_handle fh_expected;
if (CGAL::assign(fh_expected, expected)) {
Face_const_handle fh_actual;
if (CGAL::assign(fh_actual, actual)) {
if (fh_actual == fh_expected) return true;
std::cout << "Error: batched point location!" << std::endl;
std::cout << "Expected: a face" << std::endl;
std::cout << "Actual: a different face." << std::endl;
return false;
}
std::cout << "Error: batched point location!" << std::endl;
std::cout << "Expected: a face" << std::endl;
Halfedge_const_handle hh_actual;
if (CGAL::assign(hh_actual, actual)) {
std::cout << "Actual: a halfedge." << std::endl;
return false;
}
Vertex_const_handle vh_actual;
if (CGAL::assign(vh_actual, actual)) {
std::cout << "Actual: a vertex." << std::endl;
return false;
}
std::cout << "Actual: an unknowen object." << std::endl;
return false;
}
// Assign object to a halfedge
Halfedge_const_handle hh_expected;
if (CGAL::assign(hh_expected, expected)) {
Halfedge_const_handle hh_actual;
if (CGAL::assign(hh_actual, actual)) {
if ((hh_actual == hh_expected) || (hh_actual->twin() == hh_expected))
return true;
std::cout << "Error: batched point location!" << std::endl;
std::cout << "Expected: a halfedge, " << hh_expected->curve()
<< std::endl;
std::cout << "Actual: a different halfedge, " << hh_actual->curve()
<< std::endl;
return false;
}
std::cout << "Error: batched point location!" << std::endl;
std::cout << "Expected: a halfedge, " << hh_expected->curve() << std::endl;
Face_const_handle fh_actual;
if (CGAL::assign(fh_actual, actual)) {
std::cout << "Actual: a face" << std::endl;
return false;;
}
Vertex_const_handle vh_actual;
if (CGAL::assign(vh_actual, actual)) {
std::cout << "Actual: a vertex." << std::endl;
return false;;
}
std::cout << "Actual: an unknowen object." << std::endl;
return false;
}
// Assign object to a vertex
Vertex_const_handle vh_expected;
if (CGAL::assign(vh_expected, expected)) {
Vertex_const_handle vh_actual;
if (CGAL::assign(vh_actual, actual)) {
if (vh_actual == vh_expected) return true;
std::cout << "Error: batched point location!" << std::endl;
std::cout << "Expected: a vertex, "<< vh_expected->point() << std::endl;
std::cout << "Actual: a different vertex: "<< vh_actual->point()
<< std::endl;
return false;
}
std::cout << "Error: batched point location!" << std::endl;
std::cout << "Expected: a vertex, "<< vh_expected->point() << std::endl;
Face_const_handle fh_actual;
if (CGAL::assign(fh_actual, actual)) {
std::cout << "Actual: a face." << std::endl;
return false;
}
Halfedge_const_handle hh_actual;
if (CGAL::assign(hh_actual, actual)) {
std::cout << "Actual: a halfedge." << std::endl;
return false;
}
std::cout << "Actual: an unknown object." << std::endl;
return false;
}
std::cout << "Error: Unknown!" << std::endl;
return false;
}
//! \brief prints the results.
template <typename GeomTraits_T, typename TopolTraits_T>
void Batched_point_location_test<GeomTraits_T, TopolTraits_T>::
print(const std::pair<Point_2, Cell_handle>& res)
{
// Print the results.
std::cout << "The point (" << res.first << ") is located ";
if (const Face_const_handle* f =
boost::get<Face_const_handle>(&(res.second))) // inside a face
std::cout << "inside "
<< (((*f)->is_unbounded()) ? "the unbounded" : "a bounded")
<< " face." << std::endl;
else if (const Halfedge_const_handle* e =
boost::get<Halfedge_const_handle>(&(res.second))) // on an edge
std::cout << "on an edge: " << (*e)->curve() << std::endl;
else if (const Vertex_const_handle* v =
boost::get<Vertex_const_handle>(&(res.second))) // on a vertex
std::cout << "on "
<< (((*v)->is_isolated()) ? "an isolated" : "a")
<< " vertex: " << (*v)->point() << std::endl;
}
//! \brief prints the results.
template <typename GeomTraits_T, typename TopolTraits_T>
void Batched_point_location_test<GeomTraits_T, TopolTraits_T>::
print(const std::pair<Point_2, CGAL::Object>& res)
{
// Print the results.
std::cout << "The point (" << res.first << ") is located ";
Face_const_handle fh;
if (CGAL::assign(fh, res.second))
std::cout << "inside "
<< ((fh->is_unbounded()) ? "the unbounded" : "a bounded")
<< " face." << std::endl;
}
#endif

View File

@ -78,7 +78,8 @@ construct_arrangement()
{
std::ifstream in_com(this->m_filename_commands.c_str());
if (!in_com.is_open()) {
this->print_error(std::string("cannot open file ").append(this->m_filename_commands));
this->print_error(std::string("cannot open file ").
append(this->m_filename_commands));
return false;
}
@ -131,7 +132,7 @@ read_perform_opts(std::istream& is)
rc = false;
continue;
}
if (cmd == 'i') CGAL::insert(*(this->m_arr), this->m_xcurves[id]);
if (cmd == 'i') insert(*(this->m_arr), this->m_xcurves[id]);
if (cmd == 'd') {
if (!remove(this->m_xcurves[id])) rc = false;
@ -154,9 +155,8 @@ remove(const X_monotone_curve_2& xcv)
const Geom_traits* traits = this->m_arr->geometry_traits();
typename Geom_traits::Equal_2 equal = traits->equal_2_object();
typename Arrangement::Edge_iterator eit;
for (eit = this->m_arr->edges_begin(); eit != this->m_arr->edges_end(); ++eit)
{
typename Arrangement::Edge_iterator eit = this->m_arr->edges_begin();
for (; eit != this->m_arr->edges_end(); ++eit) {
const X_monotone_curve_2& xcv_arr = eit->curve();
if (equal(xcv, xcv_arr)) {
this->m_arr->remove_edge(eit);

View File

@ -15,7 +15,7 @@
#include <CGAL/Arr_point_location/Arr_lm_middle_edges_generator.h>
#include <CGAL/Arr_point_location/Arr_lm_specified_points_generator.h>
#include <CGAL/Arr_point_location_result.h>
//#include <CGAL/Arr_triangulation_point_location.h>
#include <CGAL/Arr_triangulation_point_location.h>
#include "IO_test.h"
@ -97,9 +97,8 @@ protected:
typedef typename CGAL::Arr_trapezoid_ric_point_location<Arrangement>
Trapezoid_ric_point_location;
// typedef CGAL::Arr_triangulation_point_location<Arrangement>
// Triangulation_point_location;
typedef CGAL::Arr_triangulation_point_location<Arrangement>
Triangulation_point_location;
// ===> Add new point location type here <===
@ -125,7 +124,7 @@ protected:
Lm_halton_point_location* m_halton_lm_pl; // 6
Lm_middle_edges_point_location* m_middle_edges_lm_pl; // 7
Lm_specified_points_point_location* m_specified_points_lm_pl; // 8
// Triangulation_point_location m_triangulation_pl; // 9
Triangulation_point_location* m_triangulation_pl; // 9
Trapezoid_ric_point_location* m_trapezoid_ric_pl; // 10
Trapezoid_ric_point_location* m_trapezoid_ric_no_grnt_pl; // 11
@ -137,13 +136,13 @@ protected:
// // ===> Change the number of point-location startegies
// // when a new point location is added. <===
#define MAX_NUM_POINT_LOCATION_STRATEGIES 11
#define MAX_NUM_POINT_LOCATION_STRATEGIES 12
int verify(Objects_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES],
size_t size, unsigned int pls_num);
size_t size, size_t pls_num);
int verify(Variants_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES],
size_t size, unsigned int pls_num);
size_t size, size_t pls_num);
public:
/*! Constructor */
@ -222,7 +221,7 @@ Point_location_test(const Geom_traits& geom_traits) :
m_halton_lm_pl(NULL),
m_middle_edges_lm_pl(NULL),
m_specified_points_lm_pl(NULL),
// m_triangulation_pl(NULL),
m_triangulation_pl(NULL),
m_trapezoid_ric_pl(NULL),
m_trapezoid_ric_no_grnt_pl(NULL),
m_random_g(NULL),
@ -258,7 +257,7 @@ bool Point_location_test<Geom_traits_T, Topol_traits_T>::init()
}
/*! Clear the data structures */
template<class Geom_traits_T, typename Topol_traits_T>
template <typename Geom_traits_T, typename Topol_traits_T>
void Point_location_test<Geom_traits_T, Topol_traits_T>::clear()
{
Base::clear();
@ -267,7 +266,7 @@ void Point_location_test<Geom_traits_T, Topol_traits_T>::clear()
}
/*! Clear the data structures */
template<class Geom_traits_T, typename Topol_traits_T>
template <typename Geom_traits_T, typename Topol_traits_T>
void Point_location_test<Geom_traits_T, Topol_traits_T>::
deallocate_pl_strategies()
{
@ -334,10 +333,13 @@ deallocate_pl_strategies()
}
#endif
// if (m_triangulation_pl) {
// delete m_triangulation_pl;
// m_triangulation_pl = NULL;
// }
#if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS)
if (m_triangulation_pl) {
delete m_triangulation_pl;
m_triangulation_pl = NULL;
}
#endif
if (m_trapezoid_ric_pl) {
delete m_trapezoid_ric_pl;
m_trapezoid_ric_pl = NULL;
@ -408,10 +410,10 @@ allocate_pl_strategies()
return false;
if (!(m_specified_points_lm_pl = new Lm_specified_points_point_location()))
return false;
#endif
// if (!(m_triangulation_pl = new Triangulation_point_location()))
// return false;
#if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS)
if (!(m_triangulation_pl = new Triangulation_point_location())) return false;
#endif
if (!(m_trapezoid_ric_pl = new Trapezoid_ric_point_location())) return false;
@ -474,13 +476,14 @@ construct_pl_strategies()
timer.stop();
std::cout << "Specified_points lm construction took "
<< timer.time() << std::endl;
#endif
// timer.reset(); timer.start();
// m_triangulation_pl = new Triangulation_point_location(*m_arr); // 9
// timer.stop();
// std::cout << "Triangulation lm construction took "
// << timer.time() << std::endl;
#if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS)
timer.reset(); timer.start();
m_triangulation_pl = new Triangulation_point_location(*m_arr); // 9
timer.stop();
std::cout << "Triangulation lm construction took "
<< timer.time() << std::endl;
#endif
timer.reset(); timer.start();
@ -550,13 +553,14 @@ bool Point_location_test<Geom_traits_T, Topol_traits_T>::attach_pl_strategies()
timer.stop();
std::cout << "Specified_points lm construction took "
<< timer.time() << std::endl;
#endif
// timer.reset(); timer.start();
// m_location triangulation_lm_pl->attach(*m_arr);
// timer.stop();
// std::cout << "Triangulation lm construction took "
// << timer.time() << std::endl;
#if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS)
timer.reset(); timer.start();
m_triangulation_pl->attach(*m_arr);
timer.stop();
std::cout << "Triangulation lm construction took "
<< timer.time() << std::endl;
#endif
timer.reset(); timer.start();
@ -594,7 +598,7 @@ bool Point_location_test<Geom_traits_T, Topol_traits_T>::perform()
// std::cout << "Time in seconds" << std::endl;
std::cout << std::endl;
unsigned int pl_index = 0;
size_t pl_index = 0;
query(*m_naive_pl, "Naive", m_query_points.begin(), m_query_points.end(),
std::back_inserter(objs[pl_index++])); // Naive
@ -631,12 +635,12 @@ bool Point_location_test<Geom_traits_T, Topol_traits_T>::perform()
query(*m_specified_points_lm_pl, "Landmarks specified points",
m_query_points.begin(), m_query_points.end(),
std::back_inserter(objs[pl_index++])); // Landmarks specified points
#endif
// Triangulation
// query(*m_triangulation_pl, "Triangulation",
// m_query_points.begin(), m_query_points.end(),
// std::back_inserter(objs[pl_index++])); // Triangulation
#if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS)
query(*m_triangulation_pl, "Triangulation",
m_query_points.begin(), m_query_points.end(),
std::back_inserter(objs[pl_index++])); // Triangulation
#endif
query(*m_trapezoid_ric_pl, "Trapezoidal RIC",
@ -653,7 +657,7 @@ bool Point_location_test<Geom_traits_T, Topol_traits_T>::perform()
// ===> Add a call to operate the new point location. <===
// Number of point location strategies used.
unsigned int pls_num = pl_index;
size_t pls_num = pl_index;
std::cout << "Number of strategies is " << pls_num << std::endl;
// End Location
@ -681,7 +685,7 @@ bool Point_location_test<Geom_traits_T, Topol_traits_T>::perform()
template <typename Geom_traits_T, typename Topol_traits_T>
int Point_location_test<Geom_traits_T, Topol_traits_T>::
verify(Objects_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES],
size_t size, unsigned int pls_num)
size_t size, size_t pls_num)
{
Vertex_const_handle vh_ref, vh_cur;
Halfedge_const_handle hh_ref, hh_cur;
@ -690,32 +694,33 @@ verify(Objects_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES],
int result = 0;
// Assign and check results
unsigned int qi; //qi is the query point index
size_t qi; //qi is the query point index
for (qi = 0; qi < size; ++qi) {
// Assign object to a face
if (CGAL::assign(fh_ref, objs[0][qi])) {
for (unsigned int pl = 1; pl < pls_num; ++pl) {
for (size_t pl = 1; pl < pls_num; ++pl) {
if (CGAL::assign(fh_cur, objs[pl][qi])) {
if (fh_cur != fh_ref) {
std::cout << "Error: point location number "
<< pl << " return a different face" << std::endl;
std::cout << "Error: point location number " << pl << std::endl;
std::cout << "Expecte: a face." << std::endl;
std::cout << "Actual: a different face" << std::endl;
result += -1;
}
continue;
}
std::cout << "Error in point location number " << pl;
std::cout << "Error: point location number " << pl << std::endl;
std::cout << "Expecte: a face." << std::endl;
result += -1;
if (CGAL::assign(hh_cur, objs[pl][qi])) {
std::cout << ", an halfedge returned instead of a face" << std::endl;
std::cout << "Actual: a halfedge." << std::endl;
continue;
}
if (CGAL::assign(vh_cur, objs[pl][qi])) {
std::cout << ", a vertex returned instead of a face" << std::endl;
std::cout << "Actual: a vertex." << std::endl;
continue;
}
std::cout << ", an unknowen object returned instead of a face"
<< std::endl;
std::cout << "Actual: an unknowen object." << std::endl;
}
//if (fh_ref->is_unbounded())
// std::cout << "Unbounded face." << std::endl;
@ -726,66 +731,66 @@ verify(Objects_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES],
// Assign object to a halfedge
if (CGAL::assign (hh_ref, objs[0][qi])) {
std::cout << "Halfedge: " << hh_ref->curve() << std::endl;
for (unsigned int pl = 1; pl < pls_num; ++pl) {
for (size_t pl = 1; pl < pls_num; ++pl) {
if (CGAL::assign(hh_cur, objs[pl][qi])) {
if ((hh_cur != hh_ref) && (hh_cur->twin() != hh_ref)) {
std::cout << "Error: point location number "
<< pl << " return a different halfedge" << std::endl;
std::cout << "Halfedge (curr): " << hh_cur->curve() << std::endl;
std::cout << "Error: point location number " << pl << std::endl;
std::cout << "Expected: a halfedge, " << hh_ref->curve()
<< std::endl;
std::cout << "Actual: a different halfedge: " << hh_cur->curve()
<< std::endl;
result += -1;
}
continue;
}
std::cout << "Error in point location number " << pl;
std::cout << "Error: point location number " << pl << std::endl;
std::cout << "Expected: a halfedge, " << hh_ref->curve() << std::endl;
result += -1;
if (CGAL::assign(fh_cur, objs[pl][qi])) {
std::cout << ", a face returned instead of an halfedge" << std::endl;
std::cout << "Actual: a face." << std::endl;
continue;
}
if (CGAL::assign(vh_cur, objs[pl][qi])) {
std::cout << ", a vertex returned instead of an halfedge"
<< std::endl;
std::cout << "Actual: a vertex." << std::endl;
continue;
}
std::cout << ", an unknowen object returned instead of an halfedge"
<< std::endl;
std::cout << "Actual: an unknowen object." << std::endl;
}
continue;
}
// Assign object to a vertex
if (CGAL::assign(vh_ref, objs[0][qi])) {
for (unsigned int pl = 1; pl < pls_num; ++pl) {
for (size_t pl = 1; pl < pls_num; ++pl) {
if (CGAL::assign(vh_cur, objs[pl][qi])) {
if (vh_cur != vh_ref) {
std::cout << "Error: point location number "
<< pl << " return a different vertex"<< std::endl;
std::cout << "Error: point location number " << pl << std::endl;
std::cout << "Expected: a vertex, "<< vh_ref->point() << std::endl;
std::cout << "Actual: a different vertex, "<< vh_cur->point()
<< std::endl;
result += -1;
}
continue;
}
std::cout << "Error in point location number " << pl;
std::cout << "Error: point location number " << pl << std::endl;
std::cout << "Expected: a vertex, "<< vh_ref->point() << std::endl;
result += -1;
if (CGAL::assign(fh_cur, objs[pl][qi])) {
std::cout << ", a face returned instead of a vertex" << std::endl;
std::cout << "Actual: a face." << std::endl;
continue;
}
if (CGAL::assign(hh_cur, objs[pl][qi])) {
std::cout << ", an halfedge returned instead of a vertex"
<< std::endl;
std::cout << "Actual: a halfedge." << std::endl;
continue;
}
std::cout << ", an unknown object returned instead of a vertex"
<< std::endl;
std::cout << "Actual: an unknown object." << std::endl;
}
std::cout << "Vertex: "<< vh_ref->point() << std::endl;
continue;
}
std::cout << "Illegal point-location result." << std::endl;
std::cout << "Error: Unknown!" << std::endl;
result += -1;
}
return result;
@ -795,7 +800,7 @@ verify(Objects_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES],
template <typename Geom_traits_T, typename Topol_traits_T>
int Point_location_test<Geom_traits_T, Topol_traits_T>::
verify(Variants_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES],
size_t size, unsigned int pls_num)
size_t size, size_t pls_num)
{
const Vertex_const_handle* vh_ref;
const Halfedge_const_handle* hh_ref;
@ -808,36 +813,37 @@ verify(Variants_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES],
int result = 0;
// Assign and check results
unsigned int qi; //qi is the query point index
size_t qi; //qi is the query point index
for (qi = 0; qi < size; ++qi) {
// Assign object to a face
fh_ref = boost::get<Face_const_handle>(&(objs[0][qi]));
if (fh_ref) {
for (unsigned int pl = 1; pl < pls_num; ++pl) {
for (size_t pl = 1; pl < pls_num; ++pl) {
fh_cur = boost::get<Face_const_handle>(&(objs[pl][qi]));
if (fh_cur) {
if ((*fh_cur) != (*fh_ref)) {
std::cout << "Error: point location number "
<< pl << " return a different face" << std::endl;
std::cout << "Error: point location number " << pl << std::endl;
std::cout << "Expected: a face." << std::endl;
std::cout << "Actual: a different face." << std::endl;
result += -1;
}
continue;
}
std::cout << "Error in point location number " << pl;
std::cout << "Error: point location number " << pl << std::endl;
std::cout << "Expected: a face." << std::endl;
result += -1;
hh_cur = boost::get<Halfedge_const_handle>(&(objs[pl][qi]));
if (hh_cur) {
std::cout << ", an halfedge returned instead of a face" << std::endl;
std::cout << "Actual: a halfedge." << std::endl;
continue;
}
vh_cur = boost::get<Vertex_const_handle>(&(objs[pl][qi]));
if (vh_cur) {
std::cout << ", a vertex returned instead of a face" << std::endl;
std::cout << "Actual: a vertex." << std::endl;
continue;
}
std::cout << ", an unknowen object returned instead of a face"
<< std::endl;
std::cout << "Actual: an unknowen object." << std::endl;
}
//if ((*fh_ref)->is_unbounded())
// std::cout << "Unbounded face." << std::endl;
@ -849,34 +855,34 @@ verify(Variants_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES],
// Assign object to a halfedge
hh_ref = boost::get<Halfedge_const_handle>(&(objs[0][qi]));
if (hh_ref) {
std::cout << "Halfedge: " << (*hh_ref)->curve() << std::endl;
for (unsigned int pl = 1; pl < pls_num; ++pl) {
for (size_t pl = 1; pl < pls_num; ++pl) {
hh_cur = boost::get<Halfedge_const_handle>(&(objs[pl][qi]));
if (hh_cur) {
if (((*hh_cur) != (*hh_ref)) && ((*hh_cur)->twin() != (*hh_ref))) {
std::cout << "Error: point location number "
<< pl << " return a different halfedge" << std::endl;
std::cout << "Halfedge (curr): " << (*hh_cur)->curve() << std::endl;
std::cout << "Error: point location number " << pl << std::endl;
std::cout << "Expected: a halfedge, " << (*hh_ref)->curve()
<< std::endl;
std::cout << "Actual: a different halfedge, " << (*hh_cur)->curve()
<< std::endl;
result += -1;
}
continue;
}
std::cout << "Error in point location number " << pl;
std::cout << "Error: point location number " << pl << std::endl;
std::cout << "Expected: a halfedge, " << (*hh_ref)->curve()
<< std::endl;
result += -1;
fh_cur = boost::get<Face_const_handle>(&(objs[pl][qi]));
if (fh_cur) {
std::cout << ", a face returned instead of an halfedge" << std::endl;
std::cout << "Actual: a face." << std::endl;
continue;
}
vh_cur = boost::get<Vertex_const_handle>(&(objs[pl][qi]));
if (vh_cur) {
std::cout << ", a vertex returned instead of an halfedge"
<< std::endl;
std::cout << "Actual: a vertex." << std::endl;
continue;
}
std::cout << ", an unknowen object returned instead of an halfedge"
<< std::endl;
std::cout << "Actual: an unknowen object." << std::endl;
}
continue;
}
@ -884,38 +890,38 @@ verify(Variants_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES],
// Assign object to a vertex
vh_ref = boost::get<Vertex_const_handle>(&(objs[0][qi]));
if (vh_ref) {
for (unsigned int pl = 1; pl < pls_num; ++pl) {
for (size_t pl = 1; pl < pls_num; ++pl) {
vh_cur = boost::get<Vertex_const_handle>(&(objs[pl][qi]));
if (vh_cur) {
if ((*vh_cur) != (*vh_ref)) {
std::cout << "Error: point location number "
<< pl << " return a different vertex"<< std::endl;
std::cout << "Error: point location number " << pl << std::endl;
std::cout << "Expected: a vertex: "<< (*vh_ref)->point()
<< std::endl;
std::cout << "Actual: a different vertex: "<< (*vh_cur)->point()
<< std::endl;
result += -1;
}
continue;
}
std::cout << "Error in point location number " << pl;
std::cout << "Error: point location number " << pl << std::endl;
std::cout << "Expected: a vertex: "<< (*vh_ref)->point() << std::endl;
result += -1;
fh_cur = boost::get<Face_const_handle>(&(objs[pl][qi]));
if (fh_cur) {
std::cout << ", a face returned instead of a vertex" << std::endl;
std::cout << "Actual: a face." << std::endl;
continue;
}
hh_cur = boost::get<Halfedge_const_handle>(&(objs[pl][qi]));
if (hh_cur) {
std::cout << ", an halfedge returned instead of a vertex"
<< std::endl;
std::cout << "Actual: a halfedge." << std::endl;
continue;
}
std::cout << ", an unknown object returned instead of a vertex"
<< std::endl;
std::cout << "Actual: an unknown object." << std::endl;
}
std::cout << "Vertex: "<< (*vh_ref)->point() << std::endl;
continue;
}
std::cout << "Illegal point-location result." << std::endl;
std::cout << "Error: Unknown!" << std::endl;
result += -1;
}
return result;

View File

@ -0,0 +1,315 @@
#ifndef CGAL_BATCHED_POINT_LOCATION_TEST_H
#define CGAL_BATCHED_POINT_LOCATION_TEST_H
#include <vector>
#include <list>
#include <utility>
#include <CGAL/basic.h>
#include <CGAL/Arr_vertical_decomposition_2.h>
#include <CGAL/Arr_point_location_result.h>
#include "IO_test.h"
/*! Point location test */
template <typename GeomTraits_T, typename TopolTraits_T>
class Vertical_decomposition_test : public IO_test<GeomTraits_T> {
public:
typedef GeomTraits_T Geom_traits;
typedef TopolTraits_T Topol_traits;
private:
typedef IO_test<Geom_traits> Base;
public:
typedef typename Base::Point_2 Point_2;
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Base::Curve_2 Curve_2;
typedef typename Base::Points_vector Points_vector;
typedef typename Base::Xcurves_vector Xcurves_vector;
typedef typename Base::Curves_vector Curves_vector;
typedef CGAL::Arrangement_on_surface_2<Geom_traits, Topol_traits>
Arrangement;
typedef typename Arrangement::Vertex_handle Vertex_handle;
typedef typename Arrangement::Halfedge_handle Halfedge_handle;
typedef typename Arrangement::Face_handle Face_handle;
typedef typename Arrangement::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement::Face_const_handle Face_const_handle;
typedef typename Arrangement::Edge_const_iterator Edge_const_iterator;
typedef typename Arrangement::Vertex_const_iterator Vertex_const_iterator;
typedef typename std::pair<CGAL::Object, CGAL::Object> Object_pair;
typedef typename std::pair<Vertex_const_handle, Object_pair>
Vert_decomp_entry;
typedef typename std::list<Vert_decomp_entry> Vert_decomp_list;
typedef CGAL::Arr_point_location_result<Arrangement> Point_location_result;
typedef typename Point_location_result::Type Result_type;
protected:
/*! The geometry traits. */
const Geom_traits& m_geom_traits;
/*! The arrangement. */
Arrangement m_arr;
/*! Verbosity */
size_t m_verbose_level;
/*! Verify the results.
*/
template <typename InputIterator>
bool verify(InputIterator begin, InputIterator end);
/*! Compare the results.
*/
bool compare(const Result_type& expected, const CGAL::Object& actual);
/*! print the results.
*/
void print(const Vert_decomp_entry& result);
public:
/*! Constructor from a geometry traits object.
*/
Vertical_decomposition_test(const Geom_traits& geom_traits);
/*! Destructor */
virtual ~Vertical_decomposition_test() { clear(); }
/*! Perform the test.
* \return true upon success and false otherwise.
*/
virtual bool perform();
/*! Clear the data structure. */
virtual void clear();
/*! Initialize the data structure.
* \return true upon success and false otherwise.
*/
virtual bool init();
/*! Set the verbosity level.
*/
void set_verbose_level(size_t verbose_level);
};
/*!
* Constructor from a geometry traits object.
*/
template <typename GeomTraits_T, typename TopolTraits_T>
Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::
Vertical_decomposition_test(const Geom_traits& geom_traits) :
Base(geom_traits),
m_geom_traits(geom_traits),
m_verbose_level(0)
{}
//! \brief sets the verbosity level.
template <typename GeomTraits_T, typename TopolTraits_T>
void Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::
set_verbose_level(size_t verbose_level)
{ m_verbose_level = verbose_level; }
/*! Clear the data structures */
template <typename GeomTraits_T, typename TopolTraits_T>
void Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::clear()
{
m_arr.clear();
Base::clear();
}
template <typename GeomTraits_T, typename TopolTraits_T>
bool Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::init()
{
// Initialize the input.
if (!Base::init()) return false;
// Insert all into the arrangement
CGAL::insert(m_arr, this->m_xcurves.begin(), this->m_xcurves.end());
// insert(*m_arr, m_points.begin(), m_points.end());
CGAL::insert(m_arr, this->m_curves.begin(), this->m_curves.end());
// Print the size of the arrangement.
if (m_verbose_level > 1)
std::cout << "V = " << m_arr.number_of_vertices()
<< ", E = " << m_arr.number_of_edges()
<< ", F = " << m_arr.number_of_faces() << std::endl;
return true;
}
//! \brief performs the test.
template <typename GeomTraits_T, typename TopolTraits_T>
bool Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::perform()
{
// Apply vertical decomposition.
Vert_decomp_list results;
CGAL::decompose(m_arr, std::back_inserter(results));
// Verify the results.
return verify(results.begin(), results.end());
}
//! \brief verifies the results.
template <typename GeomTraits_T, typename TopolTraits_T>
template <typename InputIterator>
bool Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::
verify(InputIterator begin, InputIterator end)
{
typedef TopolTraits_T TopolTraits;
InputIterator it;
if (m_verbose_level > 1) for (it = begin; it != end; ++it) print(*it);
// Compare the results.
typename TopolTraits::Default_vertical_ray_shooting_strategy vs(m_arr);
for (it = begin; it != end; ++it) {
Vertex_const_handle vh = it->first;
const Object_pair& res = it->second;
const CGAL::Object& obj_below_actual = res.first;
const CGAL::Object& obj_above_actual = res.second;
Result_type obj_below_expected = vs.ray_shoot_down(vh->point());
Result_type obj_above_expected = vs.ray_shoot_up(vh->point());
if (!compare(obj_below_expected, obj_below_actual)) return false;
if (!compare(obj_above_expected, obj_above_actual)) return false;
}
return true;
}
template <typename GeomTraits_T, typename TopolTraits_T>
bool Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::
compare(const Result_type& expected, const CGAL::Object& actual)
{
// Assign object to a fase.
const Face_const_handle* fh_expected =
boost::get<Face_const_handle>(&(expected));
if (fh_expected) {
Vertex_const_handle vh_actual;
if (CGAL::assign(vh_actual, actual)) {
std::cout << "Error: vertical decomposition!" << std::endl;
std::cout << "Expected: a face." << std::endl;
std::cout << "Actual: a vertex." << std::endl;
return false;
}
Halfedge_const_handle hh_actual;
if (CGAL::assign(hh_actual, actual)) {
std::cout << "Error: vertical decomposition!" << std::endl;
std::cout << "Expected: a face." << std::endl;
std::cout << "Actual: a halfedge." << std::endl;
return false;
}
return true;
}
// Assign object to a halfedge.
const Halfedge_const_handle* hh_expected =
boost::get<Halfedge_const_handle>(&(expected));
if (hh_expected) {
Halfedge_const_handle hh_actual;
if (CGAL::assign(hh_actual, actual)) {
if (*hh_expected == hh_actual) return true;
std::cout << "Error: vertical decomposition!" << std::endl;
std::cout << "Expected: a halfedge, " << (*hh_expected)->curve()
<< std::endl;
std::cout << "Actual: a different halfedge." << hh_actual->curve()
<< std::endl;
return false;
}
std::cout << "Error: vertical decomposition!" << std::endl;
std::cout << "Expected: a halfedge, " << (*hh_expected)->curve()
<< std::endl;
Vertex_const_handle vh_actual;
if (CGAL::assign(vh_actual, actual)) {
std::cout << "Actual: a vertex, " << vh_actual->point() << std::endl;
return false;
}
Face_const_handle fh_actual;
if (CGAL::assign(fh_actual, actual)) {
std::cout << "Actual: a face." << std::endl;
return false;
}
std::cout << "Actual: an unknowen object." << std::endl;
return false;
}
// Assign object to a vertex.
const Vertex_const_handle* vh_expected =
boost::get<Vertex_const_handle>(&(expected));
if (vh_expected) {
Vertex_const_handle vh_actual;
if (CGAL::assign(vh_actual, actual)) {
if (*vh_expected == vh_actual) return true;
std::cout << "Error: vertical decomposition!" << std::endl;
std::cout << "Expected: a vertex, " << (*vh_expected)->point()
<< std::endl;
std::cout << "Actual: a different vertex, " << vh_actual->point()
<< std::endl;
return false;
}
std::cout << "Error: vertical decomposition!" << std::endl;
std::cout << "Expected: a vertex, " << (*vh_expected)->point() << std::endl;
Halfedge_const_handle hh_actual;
if (CGAL::assign(hh_actual, actual)) {
std::cout << "Actual: a halfedge, " << hh_actual->curve() << std::endl;
return false;
}
Face_const_handle fh_actual;
if (CGAL::assign(fh_actual, actual)) {
std::cout << "Actual: a face." << std::endl;
return false;
}
std::cout << "Actual: an unknowen object." << std::endl;
return false;
}
std::cout << "Error: Unknown!" << std::endl;
return false;
}
//! \brief prints the results.
template <typename GeomTraits_T, typename TopolTraits_T>
void Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::
print(const Vert_decomp_entry& result)
{
// Print the result.
Vertex_const_handle vh;
Halfedge_const_handle hh;
Face_const_handle fh;
const Object_pair& res = result.second;
std::cout << "Vertex (" << result.first->point() << ") : ";
std::cout << " feature below: ";
if (CGAL::assign(hh, res.first)) std::cout << '[' << hh->curve() << ']';
else if (CGAL::assign(vh, res.first)) std::cout << '(' << vh->point() << ')';
else if (CGAL::assign(fh, res.first)) std::cout << "NONE";
else std::cout << "EMPTY";
std::cout << " feature above: ";
if (CGAL::assign(hh, res.second)) std::cout << '[' << hh->curve() << ']';
else if (CGAL::assign(vh, res.second)) std::cout << '(' << vh->point() << ')';
else if (CGAL::assign(fh, res.second)) std::cout << "NONE";
else std::cout << "EMPTY";
std::cout << std::endl;
}
#endif

View File

@ -902,6 +902,80 @@ test_point_location_linear()
compile_and_run_with_flags test_point_location linear "$flags"
}
#---------------------------------------------------------------------#
# batchecd point location with segments
#---------------------------------------------------------------------#
test_batched_point_location_segments()
{
local nt=$CGAL_GMPQ_NT;
local kernel=$CARTESIAN_KERNEL;
local geom_traits=$SEGMENT_GEOM_TRAITS;
local flags="-DTEST_NT=$nt -DTEST_KERNEL=$kernel -DTEST_GEOM_TRAITS=$geom_traits";
compile_and_run_with_flags test_batched_point_location segments "$flags"
}
#---------------------------------------------------------------------#
# batchecd point location with linear objects
#---------------------------------------------------------------------#
test_batched_point_location_linear()
{
local nt=$CGAL_GMPQ_NT;
local kernel=$CARTESIAN_KERNEL;
local geom_traits=$LINEAR_GEOM_TRAITS;
local flags="-DTEST_NT=$nt -DTEST_KERNEL=$kernel -DTEST_GEOM_TRAITS=$geom_traits";
compile_and_run_with_flags test_batched_point_location linear "$flags"
}
#---------------------------------------------------------------------#
# batchecd point location with geodesic arcs on the sphere
#---------------------------------------------------------------------#
test_batched_point_location_spherical_arcs()
{
local nt=$CGAL_GMPQ_NT;
local kernel=$CARTESIAN_KERNEL;
local geom_traits=$GEODESIC_ARC_ON_SPHERE_GEOM_TRAITS;
local topol_traits=$SPHERICAL_TOPOL_TRAITS;
local flags="-DTEST_NT=$nt -DTEST_KERNEL=$kernel -DTEST_GEOM_TRAITS=$geom_traits -DTEST_TOPOL_TRAITS=$topol_traits";
compile_and_run_with_flags test_batched_point_location geodesic_arcs_on_sphere "$flags"
}
#---------------------------------------------------------------------#
# vertical decomposition with segments
#---------------------------------------------------------------------#
test_vertical_decomposition_segments()
{
local nt=$CGAL_GMPQ_NT;
local kernel=$CARTESIAN_KERNEL;
local geom_traits=$SEGMENT_GEOM_TRAITS;
local flags="-DTEST_NT=$nt -DTEST_KERNEL=$kernel -DTEST_GEOM_TRAITS=$geom_traits";
compile_and_run_with_flags test_vertical_decomposition segments "$flags"
}
#---------------------------------------------------------------------#
# vertical decomposition with linear objects
#---------------------------------------------------------------------#
test_vertical_decomposition_linear()
{
local nt=$CGAL_GMPQ_NT;
local kernel=$CARTESIAN_KERNEL;
local geom_traits=$LINEAR_GEOM_TRAITS;
local flags="-DTEST_NT=$nt -DTEST_KERNEL=$kernel -DTEST_GEOM_TRAITS=$geom_traits";
compile_and_run_with_flags test_vertical_decomposition linear "$flags"
}
#---------------------------------------------------------------------#
# vertical decomposition with geodesic arcs on the sphere
#---------------------------------------------------------------------#
test_vertical_decomposition_spherical_arcs()
{
local nt=$CGAL_GMPQ_NT;
local kernel=$CARTESIAN_KERNEL;
local geom_traits=$LINEAR_GEOM_TRAITS;
local topol_traits=$SPHERICAL_TOPOL_TRAITS;
local flags="-DTEST_NT=$nt -DTEST_KERNEL=$kernel -DTEST_GEOM_TRAITS=$geom_traits -DTEST_TOPOL_TRAITS=$topol_traits";
compile_and_run_with_flags test_vertical_decomposition geodesic_arcs_on_sphere "$flags"
}
#---------------------------------------------------------------------#
# segment traits
#---------------------------------------------------------------------#
@ -1425,6 +1499,14 @@ test_point_location_linear
test_point_location_dynamic_segments
test_batched_point_location_segments
test_batched_point_location_linear
test_batched_point_location_spherical_arcs
test_vertical_decomposition_segments
test_vertical_decomposition_linear
# test_vertical_decomposition_spherical_arcs
compile_and_run test_dual
compile_and_run test_do_intersect
compile_and_run test_zone

View File

@ -0,0 +1,2 @@
0 0 -1 0 0 1 1 0 -1 0
0 0 -1 0 0 1 1 -1 0 0

View File

@ -0,0 +1,3 @@
0 0 -1 0 0 1 1 0 -1 0
0 0 -1 0 0 1 1 -1 0 0
0 -1 0 1 0 0 0

View File

@ -0,0 +1,8 @@
-1 0 -1 0 -1 -1 0
0 -1 -1 1 0 -1 0
1 0 -1 0 1 -1 0
0 1 -1 -1 0 -1 0
-1 0 1 0 -1 1 0
0 -1 1 1 0 1 0
1 0 1 0 1 1 0
0 1 1 -1 0 1 0

View File

@ -0,0 +1,9 @@
-1 0 -1 0 -1 -1 0
0 -1 -1 1 0 -1 0
1 0 -1 0 1 -1 0
0 1 -1 -1 0 -1 0
-1 0 1 0 -1 1 0
0 -1 1 1 0 1 0
1 0 1 0 1 1 0
0 1 1 -1 0 1 0
1 0 -1 1 0 1 0

View File

@ -0,0 +1,281 @@
#VRML V2.0 utf8
Configuration {
accumulation Accumulation { enabled TRUE }
}
ColorBackground {
color 1 1 1 1
clearStencil TRUE
}
NavigationInfo { type [ "EXAMINE" "ANY" ] }
Viewpoint {
type "ORTHOGONAL"
fieldOfView 2.96
# radiusScale 0.7
}
DEF TRANSFORMER_NAV NavigationInfo { type [ "TRANSFORM" ] }
DEF DRAW_OPAQUE_KEY SingleKeySensor { key "o" }
DEF DRAW_HALOED_KEY SingleKeySensor { key "l" state TRUE }
DEF DRAW_SURFACE_KEY SingleKeySensor { key "b" state TRUE }
DEF EXPORT_KEY SingleKeySensor { key "O" }
DEF SNAP_KEY SingleKeySensor { key "S" }
DEF VERTEX_SHAPE_KEY SingleKeySensor {
key "v"
boolean FALSE
numberOfStates 5
intState 2 # disc
}
DEF EDGE_SHAPE_KEY SingleKeySensor {
key "e"
boolean FALSE
numberOfStates 4
intState 2 # strip
}
DEF HIDE_SINGULARITIES_KEY SingleKeySensor {
boolean FALSE
key "s"
}
DEF HIDE_DISCONTINUITY_KEY SingleKeySensor {
boolean FALSE
key "d"
}
DEF SNAP Snapshot {
image Image { }
fileFormat "jpg"
quality 98
sequence FALSE
dirName "."
fileName "test03"
}
Transform {
rotation 1 0 0 -1.5708
bboxCenter 0 0 0
bboxSize 1.5 1.5 1.5
children [
Switch {
whichChoice 0
children [
DEF ARRANGMENT Group {
children [
Shape {
drawDepth FALSE
appearance Appearance {
material Material {
diffuseColor 0.5 0.5 0.5
ambientIntensity 0.7
specularColor 0.5 0.5 0.5
}
}
geometry Sphere {
slices 32
stacks 32
}
}
Shape {
appearance Appearance {
material Material {
transparency 0.0001
}
}
geometry DEF GEOM ArrangementOnSphereMarked {
drawSurface FALSE
# drawOpaque TRUE
drawHaloed TRUE
aosEdgeStyle "strip"
aosEdgeRadius 0.03
aosEdgeLineWidth 3
aosVertexStyle "disc"
aosVertexRadius 0.1
aosVertexPointSize 6
aosIsolatedVertexStyle "disc"
# insertionStrategy "increment"
aosMarkedEdgeIndex -1
aosMarkedVertexIndex 6 7
coord DEF COORD ExactCoordinate {
ratPoint [
-1 0 -1
0 -1 -1
1 0 -1
0 1 -1
-1 0 1
0 -1 1
1 0 1
0 1 1
#
1 0 -2
1 0 -1
1 0 0
1 0 1
1 0 2
]
}
pointIndex [8 9 10 11 12]
curveIndex [0 1, 1 2, 2 3, 3 0, 4 5, 5 6, 6 7, 7 4]
}
}
]
}
]
}
# The singularity points:
DEF SINGULARITIES_SWITCH Switch {
whichChoice 0
children [
Group {
children [
Shape {
appearance DEF BOUNDARY_APP Appearance {
material Material {
# ambientIntensity 1
diffuseColor 0.4 0.4 0.4
# specularColor 0.8 0.8 0.8
# transparency 0.0001
}
}
geometry Sphere {
center 0 0 1
radius 0.05
}
}
Shape {
appearance USE AXES_APP
geometry Sphere {
center 0 0 -1
radius 0.05
}
}
]
}
]
}
# The discontinuity arc:
DEF DISCONTINUITY_SWITCH Switch {
whichChoice 0
children [
Shape {
appearance USE BOUNDARY_APP
geometry Extrusion {
creaseAngle 2.0
beginCap TRUE
endCap TRUE
loop FALSE
crossSectionRadius 0.025
spine [
0 0 1,
-0.0980171 0 0.995185,
-0.19509 0 0.980785,
-0.290285 0 0.95694,
-0.382683 0 0.92388,
-0.471397 0 0.881921,
-0.55557 0 0.83147,
-0.634393 0 0.77301,
-0.707107 0 0.707107,
-0.77301 0 0.634393,
-0.83147 0 0.55557,
-0.881921 0 0.471397,
-0.92388 0 0.382683,
-0.95694 0 0.290285,
-0.980785 0 0.19509,
-0.995185 0 0.0980171,
-1 0 0,
-0.995185 0 -0.0980171,
-0.980785 0 -0.19509,
-0.95694 0 -0.290285,
-0.92388 0 -0.382683,
-0.881921 0 -0.471397,
-0.83147 0 -0.55557,
-0.77301 0 -0.634393,
-0.707107 0 -0.707107,
-0.634393 0 -0.77301,
-0.55557 0 -0.83147,
-0.471397 0 -0.881921,
-0.382683 0 -0.92388,
-0.290285 0 -0.95694,
-0.19509 0 -0.980785,
-0.0980171 0 -0.995185,
0 0 -1,
]
}
}
]
}
# The axes:
DEF AXES Transform {
scale 0.1 0.1 0.1
children [
Shape {
appearance DEF AXES_APP Appearance {
material Material {
# ambientIntensity 1
diffuseColor 0.4 0.4 0.4
# specularColor 0.3 0.3 0.3
# transparency 0.0001
}
}
geometry Sphere { radius 0.1 }
}
DEF CS_AXIS Transform {
translation 0 1.5 0
children [
Shape {
appearance USE AXES_APP
geometry Cylinder {
radius 0.1
height 3
set_is_bottom_visible FALSE
set_is_top_visible FALSE
}
}
Transform {
translation 0 1.7 0
children [
Shape {
appearance USE AXES_APP
geometry Cone {
bottomRadius 0.2
height 0.4
}
}
]
}
]
}
Transform {
rotation 0 0 -1 1.57
children [ USE CS_AXIS ]
}
Transform {
rotation 1 0 0 1.57
children [ USE CS_AXIS ]
}
]
}
# Transform {
# translation 2 0 0
# children [
# USE ARRANGMENT
# ]
# }
]
}
ROUTE DRAW_OPAQUE_KEY.state TO GEOM.drawOpaque
ROUTE DRAW_HALOED_KEY.state TO GEOM.drawHaloed
ROUTE SNAP_KEY.state TO SNAP.trigger
# ROUTE EXPORT_KEY.press TO GEOM.export
ROUTE HIDE_DISCONTINUITY_KEY.intState TO DISCONTINUITY_SWITCH.whichChoice
ROUTE HIDE_SINGULARITIES_KEY.intState TO SINGULARITIES_SWITCH.whichChoice
ROUTE VERTEX_SHAPE_KEY.intState TO GEOM.aosVertexStyleId
ROUTE EDGE_SHAPE_KEY.intState TO GEOM.aosEdgeStyleId

View File

@ -0,0 +1,280 @@
#VRML V2.0 utf8
Configuration {
accumulation Accumulation { enabled TRUE }
}
ColorBackground {
color 1 1 1 1
clearStencil TRUE
}
NavigationInfo { type [ "EXAMINE" "ANY" ] }
Viewpoint {
type "ORTHOGONAL"
fieldOfView 2.96
# radiusScale 0.7
}
DEF TRANSFORMER_NAV NavigationInfo { type [ "TRANSFORM" ] }
DEF DRAW_OPAQUE_KEY SingleKeySensor { key "o" }
DEF DRAW_HALOED_KEY SingleKeySensor { key "l" state TRUE }
DEF DRAW_SURFACE_KEY SingleKeySensor { key "b" state TRUE }
DEF EXPORT_KEY SingleKeySensor { key "O" }
DEF SNAP_KEY SingleKeySensor { key "S" }
DEF VERTEX_SHAPE_KEY SingleKeySensor {
key "v"
boolean FALSE
numberOfStates 5
intState 2 # disc
}
DEF EDGE_SHAPE_KEY SingleKeySensor {
key "e"
boolean FALSE
numberOfStates 4
intState 2 # strip
}
DEF HIDE_SINGULARITIES_KEY SingleKeySensor {
boolean FALSE
key "s"
}
DEF HIDE_DISCONTINUITY_KEY SingleKeySensor {
boolean FALSE
key "d"
}
DEF SNAP Snapshot {
image Image { }
fileFormat "jpg"
quality 98
sequence FALSE
dirName "."
fileName "test04"
}
Transform {
rotation 1 0 0 -1.5708
bboxCenter 0 0 0
bboxSize 1.5 1.5 1.5
children [
Switch {
whichChoice 0
children [
DEF ARRANGMENT Group {
children [
Shape {
drawDepth FALSE
appearance Appearance {
material Material {
diffuseColor 0.5 0.5 0.5
ambientIntensity 0.7
specularColor 0.5 0.5 0.5
}
}
geometry Sphere {
slices 32
stacks 32
}
}
Shape {
appearance Appearance {
material Material {
transparency 0.0001
}
}
geometry DEF GEOM ArrangementOnSphereMarked {
drawSurface FALSE
# drawOpaque TRUE
drawHaloed TRUE
aosEdgeStyle "strip"
aosEdgeRadius 0.03
aosEdgeLineWidth 3
aosVertexStyle "disc"
aosVertexRadius 0.1
aosVertexPointSize 6
aosIsolatedVertexStyle "disc"
# insertionStrategy "increment"
aosMarkedEdgeIndex -1
aosMarkedVertexIndex 7
coord DEF COORD ExactCoordinate {
ratPoint [
-1 0 -1
0 -1 -1
1 0 -1
0 1 -1
-1 0 1
0 -1 1
1 0 1
0 1 1
1 0 -1 1 0 0 1 0 1
#
0 -1 0
0 1 0
]
}
pointIndex [11 12]
curveIndex [0 1, 1 2, 2 3, 3 0, 4 5, 5 6, 6 7, 7 4,
8 9, 9 10]
}
}
]
}
]
}
# The singularity points:
DEF SINGULARITIES_SWITCH Switch {
whichChoice 0
children [
Group {
children [
Shape {
appearance DEF BOUNDARY_APP Appearance {
material Material {
# ambientIntensity 1
diffuseColor 0.4 0.4 0.4
# specularColor 0.8 0.8 0.8
# transparency 0.0001
}
}
geometry Sphere {
center 0 0 1
radius 0.05
}
}
Shape {
appearance USE AXES_APP
geometry Sphere {
center 0 0 -1
radius 0.05
}
}
]
}
]
}
# The discontinuity arc:
DEF DISCONTINUITY_SWITCH Switch {
whichChoice 0
children [
Shape {
appearance USE BOUNDARY_APP
geometry Extrusion {
creaseAngle 2.0
beginCap TRUE
endCap TRUE
loop FALSE
crossSectionRadius 0.025
spine [
0 0 1,
-0.0980171 0 0.995185,
-0.19509 0 0.980785,
-0.290285 0 0.95694,
-0.382683 0 0.92388,
-0.471397 0 0.881921,
-0.55557 0 0.83147,
-0.634393 0 0.77301,
-0.707107 0 0.707107,
-0.77301 0 0.634393,
-0.83147 0 0.55557,
-0.881921 0 0.471397,
-0.92388 0 0.382683,
-0.95694 0 0.290285,
-0.980785 0 0.19509,
-0.995185 0 0.0980171,
-1 0 0,
-0.995185 0 -0.0980171,
-0.980785 0 -0.19509,
-0.95694 0 -0.290285,
-0.92388 0 -0.382683,
-0.881921 0 -0.471397,
-0.83147 0 -0.55557,
-0.77301 0 -0.634393,
-0.707107 0 -0.707107,
-0.634393 0 -0.77301,
-0.55557 0 -0.83147,
-0.471397 0 -0.881921,
-0.382683 0 -0.92388,
-0.290285 0 -0.95694,
-0.19509 0 -0.980785,
-0.0980171 0 -0.995185,
0 0 -1,
]
}
}
]
}
# The axes:
DEF AXES Transform {
scale 0.1 0.1 0.1
children [
Shape {
appearance DEF AXES_APP Appearance {
material Material {
# ambientIntensity 1
diffuseColor 0.4 0.4 0.4
# specularColor 0.3 0.3 0.3
# transparency 0.0001
}
}
geometry Sphere { radius 0.1 }
}
DEF CS_AXIS Transform {
translation 0 1.5 0
children [
Shape {
appearance USE AXES_APP
geometry Cylinder {
radius 0.1
height 3
set_is_bottom_visible FALSE
set_is_top_visible FALSE
}
}
Transform {
translation 0 1.7 0
children [
Shape {
appearance USE AXES_APP
geometry Cone {
bottomRadius 0.2
height 0.4
}
}
]
}
]
}
Transform {
rotation 0 0 -1 1.57
children [ USE CS_AXIS ]
}
Transform {
rotation 1 0 0 1.57
children [ USE CS_AXIS ]
}
]
}
# Transform {
# translation 2 0 0
# children [
# USE ARRANGMENT
# ]
# }
]
}
ROUTE DRAW_OPAQUE_KEY.state TO GEOM.drawOpaque
ROUTE DRAW_HALOED_KEY.state TO GEOM.drawHaloed
ROUTE SNAP_KEY.state TO SNAP.trigger
# ROUTE EXPORT_KEY.press TO GEOM.export
ROUTE HIDE_DISCONTINUITY_KEY.intState TO DISCONTINUITY_SWITCH.whichChoice
ROUTE HIDE_SINGULARITIES_KEY.intState TO SINGULARITIES_SWITCH.whichChoice
ROUTE VERTEX_SHAPE_KEY.intState TO GEOM.aosVertexStyleId
ROUTE EDGE_SHAPE_KEY.intState TO GEOM.aosEdgeStyleId

View File

@ -0,0 +1,8 @@
# A grid
L 0 1 -2
L 0 1 0
L 0 1 2
#
L 1 0 -2
L 1 0 0
L 1 0 2

View File

@ -0,0 +1,4 @@
L 1 0 0
L -1 0 0
L 0 1 0
L 0 -1 0

View File

@ -0,0 +1,19 @@
-3 -3
-3 -1
-3 1
-3 3
#
-1 -3
-1 -1
-1 1
-1 3
#
1 -3
1 -1
1 1
1 3
#
3 -3
3 -1
3 1
3 3

View File

@ -0,0 +1,9 @@
-1 -1
-1 0
-1 1
0 -1
0 0
0 1
1 -1
1 0
1 1

View File

@ -0,0 +1,12 @@
# A grid
0 0 8 0
0 2 8 2
0 4 8 4
0 6 8 6
0 8 8 8
#
0 0 0 8
2 0 2 8
4 0 4 8
6 0 6 8
8 0 8 8

View File

@ -0,0 +1,16 @@
1 1
1 3
1 5
1 7
3 1
3 3
3 5
3 7
5 1
5 3
5 5
5 7
7 1
7 3
7 5
7 7

View File

@ -0,0 +1,4 @@
L 1 -1 -1
L 1 -1 1
L -1 1 -1
L -1 1 1

View File

@ -0,0 +1,6 @@
0 0 2 2
1 0 2 1
0 1 1 2
2 0 0 2
1 0 0 1
2 1 1 2

View File

@ -0,0 +1,133 @@
#include <iostream>
#include <boost/lexical_cast.hpp>
#include <CGAL/basic.h>
#include "test_configuration.h"
#if ((TEST_GEOM_TRAITS == CORE_CONIC_GEOM_TRAITS) || \
(TEST_GEOM_TRAITS == BEZIER_GEOM_TRAITS) || \
(TEST_GEOM_TRAITS == RATIONAL_ARC_GEOM_TRAITS)) && !defined(CGAL_USE_CORE)
int main()
{
// bool UNTESTED_TRAITS_AS_CORE_IS_NOT_INSTALLED;
std::cout << std::endl
<< "NOTE: Core is not installed, "
<< "skipping the test ..."
<< std::endl;
return 0;
}
#elif (TEST_GEOM_TRAITS == ALGEBRAIC_GEOM_TRAITS) && \
(TEST_NT == LEDA_INT_NT || TEST_NT == LEDA_RAT_NT) && \
(! CGAL_USE_LEDA)
int main()
{
// bool UNTESTED_TRAITS_AS_LEDA_IS_NOT_INSTALLED;
std::cout << std::endl
<< "NOTE: LEDA is not installed, "
<< "skipping the test ..."
<< std::endl;
return 0;
}
#elif (TEST_GEOM_TRAITS == ALGEBRAIC_GEOM_TRAITS) && \
(TEST_NT == CGAL_GMPZ_NT || TEST_NT == CGAL_GMPQ_NT) && \
! (CGAL_USE_GMP && CGAL_USE_MPFI)
int main()
{
// bool UNTESTED_TRAITS_AS_GMP_OR_MPFI_IS_NOT_INSTALLED;
std::cout << std::endl
<< "NOTE: GMP and/or MPFI are not installed, "
<< "skipping the test ..."
<< std::endl;
return 0;
}
#elif (TEST_GEOM_TRAITS == ALGEBRAIC_GEOM_TRAITS) && \
(TEST_NT == CORE_INT_NT) && \
!CGAL_USE_CORE
int main()
{
// bool UNTESTED_TRAITS_AS_CORE_IS_NOT_INSTALLED;
std::cout << std::endl
<< "NOTE: CORE is not installed, "
<< "skipping the test ..."
<< std::endl;
return 0;
}
#else
#include "test_traits.h"
#include "Batched_point_location_test.h"
bool test(const char* points_filename, const char* xcurves_filename,
const char* curves_filename, const char* queries_filename,
size_t verbose_level)
{
Geom_traits geom_traits;
Batched_point_location_test<Geom_traits, Topol_traits> pl_test(geom_traits);
pl_test.set_verbose_level(verbose_level);
pl_test.set_filenames(points_filename, xcurves_filename, curves_filename,
queries_filename);
if (!pl_test.init()) return false;
if (!pl_test.perform()) return false;
pl_test.clear();
return true;
}
int main(int argc, char* argv[])
{
#if TEST_GEOM_TRAITS == ALGEBRAIC_GEOM_TRAITS
CGAL::set_pretty_mode(std::cout);
CGAL::set_pretty_mode(std::cerr);
#endif
size_t verbose_level = 0;
int success = 0;
size_t i = 1;
// Test 1
if ((argc > 2) && (std::strncmp(argv[1], "-v", 2) == 0)) {
verbose_level = boost::lexical_cast<size_t>(argv[2]);
i += 2;
}
if (argc < (static_cast< int >(i) + 4)) {
std::cout << "Usage: " << argv[0]
<< " point-file xcurve-file curve-file query-file"
<< std::endl;
std::cout << "point-file - the input point file" << std::endl;
std::cout << "xcurve-file - the input x-monotone curves file" << std::endl;
std::cout << "curve-file - the input curve file" << std::endl;
std::cerr << "query-file - the input query point file" << std::endl;
return -1;
}
for (; static_cast< int >(i) < argc; i += 4) {
const char* points_filename = argv[i];
const char* xcurves_filename = argv[i+1];
const char* curves_filename = argv[i+2];
const char* queries_filename = argv[i+3];
if (!test(points_filename, xcurves_filename, curves_filename,
queries_filename, verbose_level))
{
std::cout << "ERROR : " << argv[0] << " "
<< points_filename << " " << xcurves_filename << " "
<< curves_filename << " " << queries_filename << std::endl;
success = -1;
}
}
return success;
}
#endif

View File

@ -0,0 +1,4 @@
./data/empty.zero ./data/empty.zero ./data/batched_point_location/geodesic_arcs_on_sphere/curves/test01.txt ./data/batched_point_location/geodesic_arcs_on_sphere/queries/test01.txt
./data/empty.zero ./data/empty.zero ./data/batched_point_location/geodesic_arcs_on_sphere/curves/test02.txt ./data/batched_point_location/geodesic_arcs_on_sphere/queries/test02.txt
./data/empty.zero ./data/empty.zero ./data/batched_point_location/geodesic_arcs_on_sphere/curves/test03.txt ./data/batched_point_location/geodesic_arcs_on_sphere/queries/test03.txt
./data/empty.zero ./data/empty.zero ./data/batched_point_location/geodesic_arcs_on_sphere/curves/test04.txt ./data/batched_point_location/geodesic_arcs_on_sphere/queries/test04.txt

View File

@ -0,0 +1,3 @@
./data/empty.zero ./data/empty.zero ./data/batched_point_location/linear/curves/test01.txt ./data/batched_point_location/linear/queries/test01.txt
./data/empty.zero ./data/empty.zero ./data/batched_point_location/linear/curves/test02.txt ./data/batched_point_location/linear/queries/test02.txt
./data/empty.zero ./data/empty.zero ./data/batched_point_location/linear/curves/test03.txt ./data/batched_point_location/linear/queries/test03.txt

View File

@ -0,0 +1 @@
./data/empty.zero ./data/empty.zero ./data/batched_point_location/segments/curves/test01.txt ./data/batched_point_location/segments/queries/test01.txt

View File

@ -1 +1 @@
./data/empty.zero ./data/empty.zero ./data/point_location_circle_segments/curves/test01.txt ./data/point_location_circle_segments/queries/test01.txt
./data/empty.zero ./data/empty.zero ./data/point_location/circle_segments/curves/test01.txt ./data/point_location/circle_segments/queries/test01.txt

View File

@ -1,3 +1,3 @@
./data/empty.zero ./data/empty.zero ./data/point_location_linear/curves/test01.txt ./data/point_location_linear/queries/test01.txt
./data/empty.zero ./data/point_location_linear/xcurves/test02.txt ./data/empty.zero ./data/point_location_linear/queries/test02.txt
./data/empty.zero ./data/empty.zero ./data/point_location_linear/curves/test03.txt ./data/point_location_linear/queries/test03.txt
./data/empty.zero ./data/empty.zero ./data/point_location/linear/curves/test01.txt ./data/point_location/linear/queries/test01.txt
./data/empty.zero ./data/point_location/linear/xcurves/test02.txt ./data/empty.zero ./data/point_location/linear/queries/test02.txt
./data/empty.zero ./data/empty.zero ./data/point_location/linear/curves/test03.txt ./data/point_location/linear/queries/test03.txt

Some files were not shown because too many files have changed in this diff Show More