Merge pull request #1487 from efifogel/Aos_2-sweep-efif

Aos 2 sweep efif
This commit is contained in:
Laurent Rineau 2016-10-05 15:09:46 +02:00 committed by GitHub
commit ea8f95ca55
31 changed files with 827 additions and 624 deletions

View File

@ -73,7 +73,7 @@ public:
}
#endif
emit CGAL::Qt::GraphicsViewInput::modelChanged( );
Q_EMIT CGAL::Qt::GraphicsViewInput::modelChanged( );
}
void setScene( QGraphicsScene* scene )

View File

@ -39,7 +39,7 @@ class ArrangementDemoTabBase : public QWidget
{
Q_OBJECT
signals:
Q_SIGNALS:
void modelChanged( );
public:
@ -198,7 +198,7 @@ public:
// TODO: Add a connection to update the demo window when the fill color
// changes
emit modelChanged( );
Q_EMIT modelChanged( );
}
protected:

View File

@ -76,7 +76,7 @@ class ArrangementDemoWindow : public CGAL::Qt::DemosMainWindow
template < class ArrType >
void makeOverlayTab( ArrType* arr1, ArrType* arr2 );
public slots:
public Q_SLOTS:
void updateMode( QAction* a );
void updateEnvelope( QAction* a );
void updateSnapping( QAction* a );
@ -95,7 +95,7 @@ public slots:
void on_actionFillColor_triggered( );
signals:
Q_SIGNALS:
void modelChanged( );
protected:

View File

@ -89,7 +89,7 @@ processInput( CGAL::Object o )
CGAL::insert( *( this->arrangement ), curve );
}
emit CGAL::Qt::GraphicsViewInput::modelChanged( );
Q_EMIT CGAL::Qt::GraphicsViewInput::modelChanged( );
}
template < typename Arr_ >

View File

@ -17,6 +17,8 @@ if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND CGAL_Core_FOUND)
# Arrangement package includes
include_directories( BEFORE ../../include )
add_definitions(-DQT_NO_KEYWORDS)
qt5_wrap_ui( arrangement_2_uis
ArrangementDemoWindow.ui
NewTabDialog.ui

View File

@ -41,10 +41,10 @@ public:
Callback( QObject* parent );
virtual void reset( );
public slots:
public Q_SLOTS:
virtual void slotModelChanged( );
signals:
Q_SIGNALS:
void modelChanged( );
protected:

View File

@ -69,5 +69,5 @@ void ColorItemEditor::mousePressEvent(QMouseEvent* /* e */)
this->setColor( selectedColor );
}
emit confirmed();
Q_EMIT confirmed();
}

View File

@ -60,7 +60,7 @@ public:
QColor color( ) const;
void setColor( QColor c );
signals:
Q_SIGNALS:
void confirmed( );
protected:

View File

@ -116,7 +116,7 @@ public: // methods
this->updateBoundingBox( );
}
public slots:
public Q_SLOTS:
void modelChanged( )
{
if ( this->curves.size( ) == 0 )
@ -303,7 +303,7 @@ public: // methods
}
}
public slots:
public Q_SLOTS:
void modelChanged( )
{
if ( this->curves.size( ) == 0 )

View File

@ -108,7 +108,7 @@ void DeleteCurveCallback< Arr_ >::reset( )
{
this->highlightedCurve->clear( );
this->removableHalfedge = Halfedge_handle( );
emit modelChanged( );
Q_EMIT modelChanged( );
}
template < typename Arr_ >
@ -221,7 +221,7 @@ highlightNearestCurve( QGraphicsSceneMouseEvent* event )
this->highlightedCurve->insert( this->removableHalfedge->curve( ) );
}
emit modelChanged( );
Q_EMIT modelChanged( );
}
#endif // DELETE_CURVE_CALLBACK_H

View File

@ -41,7 +41,7 @@ public:
virtual void setEnvelopeVertexRadius( int radius ) = 0;
virtual int getEnvelopeVertexRadius( ) const = 0;
public slots:
public Q_SLOTS:
virtual void showLowerEnvelope( bool b ) = 0;
virtual void showUpperEnvelope( bool b ) = 0;

View File

@ -27,7 +27,7 @@ FillFaceCallbackBase::FillFaceCallbackBase( QObject* parent ) :
void FillFaceCallbackBase::setColor( QColor c )
{
this->fillColor = c;
emit modelChanged( );
Q_EMIT modelChanged( );
}
QColor FillFaceCallbackBase::getColor( ) const

View File

@ -123,14 +123,14 @@ FillFaceCallback<Arr_>::FillFaceCallback(Arrangement* arr_, QObject* parent_):
template < class Arr_ >
void FillFaceCallback< Arr_ >::reset( )
{
emit modelChanged( );
Q_EMIT modelChanged( );
}
template < class Arr_ >
void FillFaceCallback<Arr_>::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
this->fillFace( event );
emit modelChanged( );
Q_EMIT modelChanged( );
}
template < class Arr_ >

View File

@ -145,7 +145,7 @@ protected:
}
this->pointsGraphicsItem.clear( );
Curve_2 res( this->p1, this->p2 );
emit generate( CGAL::make_object( res ) );
Q_EMIT generate( CGAL::make_object( res ) );
}
}
@ -243,7 +243,7 @@ protected:
construct_poly( this->points.begin( ), this->points.end( ) );
this->points.clear( );
emit generate( CGAL::make_object( res ) );
Q_EMIT generate( CGAL::make_object( res ) );
}
else
{ // start the next segment
@ -440,7 +440,7 @@ protected:
this->points.clear( );
this->pointsGraphicsItem.clear( );
emit generate( CGAL::make_object( res ) );
Q_EMIT generate( CGAL::make_object( res ) );
}
else if ( this->conicType == CONIC_CIRCLE )
{
@ -460,7 +460,7 @@ protected:
this->points.clear( );
this->pointsGraphicsItem.clear( );
emit generate( CGAL::make_object( res ) );
Q_EMIT generate( CGAL::make_object( res ) );
}
else if ( this->conicType == CONIC_ELLIPSE )
{
@ -494,7 +494,7 @@ protected:
Curve_2 res = Curve_2( r, s, t, u, v, ww );
this->points.clear( );
this->pointsGraphicsItem.clear( );
emit generate( CGAL::make_object( res ) );
Q_EMIT generate( CGAL::make_object( res ) );
}
else if ( this->conicType == CONIC_THREE_POINT )
{
@ -510,7 +510,7 @@ protected:
if ( ! ker.collinear_2_object()( p1, p2, p3 ) )
{
Curve_2 res( p1, p2, p3 );
emit generate( CGAL::make_object( res ) );
Q_EMIT generate( CGAL::make_object( res ) );
}
else
{
@ -543,7 +543,7 @@ protected:
Curve_2 res( p1, p2, p3, p4, p5 );
if ( res.is_valid( ) )
{
emit generate( CGAL::make_object( res ) );
Q_EMIT generate( CGAL::make_object( res ) );
}
else
{
@ -715,7 +715,7 @@ protected: // methods
res = Curve_2( Line_2( this->p1, this->p2 ) );
}
emit generate( CGAL::make_object( res ) );
Q_EMIT generate( CGAL::make_object( res ) );
}
}
@ -802,13 +802,13 @@ protected:
{
Curve_2 res( circle, pp1, pp3 );
// std::cout << res << std::endl;
emit generate( CGAL::make_object( res ) );
Q_EMIT generate( CGAL::make_object( res ) );
}
else
{
Curve_2 res( circle, pp3, pp1 );
// std::cout << res << std::endl;
emit generate( CGAL::make_object( res ) );
Q_EMIT generate( CGAL::make_object( res ) );
}
}
else

View File

@ -133,7 +133,7 @@ GraphicsViewSegmentInput<K_>::mousePressEvent(QGraphicsSceneMouseEvent* event)
this->scene->removeItem( &(segmentGuide ) );
}
Segment_2 res( this->p1, this->p2 );
emit generate( CGAL::make_object( res ) );
Q_EMIT generate( CGAL::make_object( res ) );
}
}

View File

@ -117,7 +117,7 @@ void MergeEdgeCallback< Arr_ >::reset( )
this->highlightedCurve->clear( );
this->highlightedCurve2->clear( );
this->mergeableHalfedge = Halfedge_handle( );
emit modelChanged( );
Q_EMIT modelChanged( );
}
template < typename Arr_ >
@ -141,7 +141,7 @@ void MergeEdgeCallback<Arr_>::mousePressEvent(QGraphicsSceneMouseEvent* event)
this->reset( );
}
emit modelChanged( );
Q_EMIT modelChanged( );
}
template < typename Arr_ >
@ -156,7 +156,7 @@ void MergeEdgeCallback<Arr_>::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
}
this->highlightedCurve->clear( );
this->highlightedCurve->insert( halfedge->curve( ) );
emit modelChanged( );
Q_EMIT modelChanged( );
}
else
{
@ -164,7 +164,7 @@ void MergeEdgeCallback<Arr_>::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
this->getNearestMergeableCurve( this->mergeableHalfedge, event );
this->highlightedCurve2->clear( );
this->highlightedCurve2->insert( nextHalfedge->curve( ) );
emit modelChanged( );
Q_EMIT modelChanged( );
}
}

View File

@ -41,7 +41,7 @@ class OverlayDialog : public QDialog
std::vector< CGAL::Object > selectedArrangements( ) const;
public slots:
public Q_SLOTS:
void on_pickPushButton_pressed( );
void on_unpickPushButton_pressed( );

View File

@ -135,7 +135,7 @@ PointLocationCallback< Arr_ >::
reset( )
{
this->highlightedCurves->clear( );
emit modelChanged( );
Q_EMIT modelChanged( );
}
template < typename Arr_ >
@ -158,7 +158,7 @@ highlightPointLocation( QGraphicsSceneMouseEvent* event )
typename Traits::Left_side_category category;
this->highlightPointLocation( event, category );
emit modelChanged( );
Q_EMIT modelChanged( );
}
template < typename Arr_ >

View File

@ -57,7 +57,7 @@ public:
void setPointRadius( double d );
double getPointRadius( ) const;
public slots:
public Q_SLOTS:
virtual void modelChanged( );
protected:

View File

@ -141,8 +141,8 @@ void PropertyValueDelegate::commit( )
QWidget* editor = qobject_cast< QWidget* >( sender( ) );
if ( editor )
{
emit( commitData( editor ) );
emit( closeEditor( editor ) );
Q_EMIT( commitData( editor ) );
Q_EMIT( closeEditor( editor ) );
}
}

View File

@ -39,7 +39,7 @@ public:
const QModelIndex& index ) const;
bool eventFilter( QObject* object, QEvent* event );
public slots:
public Q_SLOTS:
void commit( );
};

View File

@ -174,7 +174,7 @@ void SplitEdgeCallback< Arr_ >::reset( )
{
this->hasFirstPoint = false;
this->segmentGuide.setLine( 0, 0, 0, 0 );
emit modelChanged( );
Q_EMIT modelChanged( );
}
template < typename Arr_ >
@ -235,7 +235,7 @@ splitEdges( const Point_2& clickedPoint, TTraits traits )
this->reset( );
}
emit modelChanged( );
Q_EMIT modelChanged( );
}
template < typename Arr_ >
@ -279,7 +279,7 @@ void SplitEdgeCallback<Arr_>::updateGuide(const Point_2& clickedPoint,
Segment_2 currentSegment( pt1, pt2 );
QLineF qSegment = this->convert( currentSegment );
this->segmentGuide.setLine( qSegment );
emit modelChanged( );
Q_EMIT modelChanged( );
}
}
@ -299,7 +299,7 @@ updateGuide(const Point_2& clickedPoint,
Segment_2 currentSegment( pt1, pt2 );
QLineF qSegment = this->convert( currentSegment );
this->segmentGuide.setLine( qSegment );
emit modelChanged( );
Q_EMIT modelChanged( );
}
}

View File

@ -56,7 +56,7 @@ public:
void reset( );
public slots:
public Q_SLOTS:
virtual void modelChanged( );
protected:

View File

@ -199,7 +199,7 @@ void VerticalRayShootCallback< Arr_ >::reset( )
this->activeRay->setLine( 0, 0, 0, 0 );
this->rayGraphicsItem.reset( );
this->highlightedCurves->clear( );
emit modelChanged( );
Q_EMIT modelChanged( );
}
template < typename Arr_ >
@ -285,7 +285,7 @@ highlightPointLocation( QGraphicsSceneMouseEvent* event )
}
}
emit modelChanged( );
Q_EMIT modelChanged( );
}
template < typename Arr_ >

View File

@ -12,12 +12,9 @@
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// (based on old version by Tali Zvi)
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
// (based on old version by Tali Zvi)
#ifndef CGAL_BASIC_SWEEP_LINE_2_H
#define CGAL_BASIC_SWEEP_LINE_2_H
@ -25,8 +22,9 @@
/*! \file
* Definition of the Basic_sweep_line_2 class.
*/
// #include <cstdint>
#include <boost/mpl/assert.hpp>
#include <CGAL/assertions.h>
#include <CGAL/memory.h>
#include <CGAL/Sweep_line_2/Sweep_line_functors.h>
@ -42,32 +40,62 @@
#ifndef CGAL_SL_VERBOSE
#define CGAL_SL_DEBUG(a)
#define CGAL_PRINT_INSERT(a)
#define CGAL_PRINT_ERASE(a)
#define CGAL_PRINT_NEW_EVENT(p, e)
#define CGAL_PRINT_UPDATE_EVENT(p, e)
#define CGAL_PRINT(a)
#define CGAL_SL_PRINT(a)
#define CGAL_SL_PRINT_TEXT(text)
#define CGAL_SL_PRINT_EOL()
#define CGAL_SL_PRINT_START(name)
#define CGAL_SL_PRINT_START_EOL(name)
#define CGAL_SL_PRINT_END(name)
#define CGAL_SL_PRINT_END_EOL(name)
#define CGAL_SL_PRINT_CURVE(text)
#define CGAL_SL_PRINT_EVENT_INFO(event)
#define CGAL_SL_PRINT_STATUS_LINE()
#define CGAL_SL_PRINT_INSERT(a)
#define CGAL_SL_PRINT_ERASE(a)
#define CGAL_SL_PRINT_NEW_EVENT(p, e)
#define CGAL_SL_PRINT_UPDATE_EVENT(p, e)
#else
#include <iostream>
#define CGAL_SL_DEBUG(a) {a;}
#define CGAL_PRINT_INSERT(a) { std::cout << "+++ inserting "; \
(a)->Print(); \
std::cout << " currentPos = "; \
this->PrintEvent(this->m_currentEvent); \
std::cout << std::endl; \
}
#define CGAL_PRINT_ERASE(a) { std::cout << "--- erasing "; \
(a)->Print(); }
#define CGAL_PRINT_NEW_EVENT(p, e) \
{ std::cout << "%%% a new event was created at " << (p) << std::endl; \
(e)->Print(); }
#define CGAL_PRINT_UPDATE_EVENT(p, e) \
{ std::cout << "%%% an event was updated at " << (p) << std::endl; \
(e)->Print(); }
#define CGAL_PRINT(a) { std::cout << a; }
#define CGAL_SL_DEBUG(a) {a;}
#define CGAL_SL_PRINT(a) std::cout << a
#define CGAL_SL_PRINT_TEXT(text) this->print_text(text)
#define CGAL_SL_PRINT_EOL() this->print_eol()
#define CGAL_SL_PRINT_START(name) this->print_start(name, false)
#define CGAL_SL_PRINT_START_EOL(name) this->print_start(name, true)
#define CGAL_SL_PRINT_END(name) this->print_end(name, false)
#define CGAL_SL_PRINT_END_EOL(name) this->print_end(name, true)
#define CGAL_SL_PRINT_CURVE(text) this->print_curve(text)
#define CGAL_SL_PRINT_EVENT_INFO(event) this->print_event_info(event)
#define CGAL_SL_PRINT_STATUS_LINE() this->PrintStatusLine()
#define CGAL_SL_PRINT_INSERT(a) { \
this->print_text("+++ inserting "); \
(a)->Print(); \
this->print_eol(); \
this->print_text(" currentPos = "); \
this->PrintEvent(this->m_currentEvent); \
this->print_eol(); \
}
#define CGAL_SL_PRINT_ERASE(a) { \
this->print_text("--- erasing "); \
(a)->Print(); \
this->print_eol(); \
}
#define CGAL_SL_PRINT_NEW_EVENT(p, e) { \
this->print_text("%%% a new event was created at "); \
CGAL_SL_PRINT(p); \
this->print_eol(); \
}
#define CGAL_SL_PRINT_UPDATE_EVENT(p, e) { \
this->print_text("%%% an event was updated at "); \
CGAL_SL_PRINT(p); \
this->print_eol(); \
this->print_event_info(e); \
}
#endif
@ -121,6 +149,8 @@ public:
typedef typename Event::Subcurve_iterator
Event_subcurve_iterator;
typedef typename Event::Subcurve_const_iterator
Event_subcurve_const_iterator;
typedef Sweep_line_event<Traits_2, Subcurve> Base_event;
typedef typename Base_event::Attribute Attribute;
@ -143,61 +173,57 @@ protected:
* An auxiliary functor for comparing event pointers.
*/
struct CompEventPtr {
Comparison_result operator()(Event *e1, Event *e2) const
{
if (e1 < e2) return (SMALLER);
if (e1 > e2) return (LARGER);
return (EQUAL);
}
Comparison_result operator()(Event* e1, Event* e2) const
{ return (e1 < e2) ? SMALLER : ((e1 > e2) ? LARGER : EQUAL); }
};
typedef Multiset<Event*, CompEventPtr> Allocated_events_set;
typedef typename Allocated_events_set::iterator Allocated_events_iterator;
// Data members:
const Traits_adaptor_2* m_traits; // A traits-class object.
bool m_traitsOwner; // Whether this object was allocated by
// this class (and thus should be freed).
const Traits_adaptor_2* m_traits; // A traits-class object.
bool m_traitsOwner; // Whether this object was allocated by
// this class (and thus should be freed).
Event* m_currentEvent; // The current event.
Event* m_currentEvent; // The current event.
Compare_curves m_statusLineCurveLess;
// Comparison functor for the status line.
// Comparison functor for the status line.
Compare_events m_queueEventLess; // Comparison functor for the event queue.
Compare_events m_queueEventLess; // Comparison functor for the event queue.
Event_queue* m_queue; // The event queue (the X-structure).
Event_queue* m_queue; // The event queue (the X-structure).
Subcurve* m_subCurves; // An array of the subcurves.
Status_line m_statusLine; // The status line (the Y-structure).
Subcurve* m_subCurves; // An array of the subcurves.
Status_line m_statusLine; // The status line (the Y-structure).
Allocated_events_set m_allocated_events;
// The events that have been allocated
// (and have not yet been deallocated).
// The events that have been allocated
// (and have not yet been deallocated).
Status_line_iterator m_status_line_insert_hint;
// An iterator of the status line, which
// is used as a hint for insertions.
// An iterator of the status line, which
// is used as a hint for insertions.
bool m_is_event_on_above; // Indicates if the current event is on
// the interior of existing curve. This
// may happen only with events that are
// associated with isolated query points.
bool m_is_event_on_above; // Indicates if the current event is on
// the interior of existing curve. This
// may happen only with events that are
// associated with isolated query points.
Event_alloc m_eventAlloc; // An allocator for the events objects.
Subcurve_alloc m_subCurveAlloc; // An allocator for the subcurve objects.
Event_alloc m_eventAlloc; // An allocator for the events objects.
Subcurve_alloc m_subCurveAlloc; // An allocator for the subcurve objects.
Event m_masterEvent; // A master Event (created once by the
// constructor) for the allocator's usage.
Event m_masterEvent; // A master Event (created once by the
// constructor) for the allocator's usage.
Subcurve m_masterSubcurve; // A master Subcurve (created once by the
// constructor) for the allocator's usage.
Subcurve m_masterSubcurve; // A master Subcurve (created once by the
// constructor) for the allocator's usage.
//! \todo m_num_of_subCurves should be a size_t for "huge" data sets
unsigned int m_num_of_subCurves; // Number of subcurves.
unsigned int m_num_of_subCurves; // Number of subcurves.
Visitor* m_visitor; // The sweep-line visitor that will be
// notified during the sweep.
Visitor* m_visitor; // The sweep-line visitor that will be
// notified during the sweep.
public:
/*! Constructor.
@ -220,15 +246,14 @@ public:
* \pre The value-type of CurveInputIterator is X_monotone_curve_2.
*/
template <typename CurveInputIterator>
void sweep(CurveInputIterator curves_begin,
CurveInputIterator curves_end)
void sweep(CurveInputIterator curves_begin, CurveInputIterator curves_end)
{
m_visitor->before_sweep();
_init_sweep(curves_begin, curves_end);
//m_visitor ->after_init();
//m_visitor->after_init();
_sweep();
_complete_sweep();
m_visitor ->after_sweep();
m_visitor->after_sweep();
}
/*! Run the sweep-line algorithm on a range of x-monotone curves and a range
@ -252,10 +277,10 @@ public:
m_visitor->before_sweep();
_init_sweep(curves_begin, curves_end);
_init_points(action_points_begin, action_points_end, Base_event::ACTION);
//m_visitor ->after_init();
//m_visitor->after_init();
_sweep();
_complete_sweep();
m_visitor ->after_sweep();
m_visitor->after_sweep();
}
/*! Run the sweep-line alogrithm on a range of x-monotone curves, a range
@ -284,43 +309,35 @@ public:
_init_sweep(curves_begin, curves_end);
_init_points(action_points_begin, action_points_end, Base_event::ACTION);
_init_points(query_points_begin, query_points_end, Base_event::QUERY);
//m_visitor ->after_init();
//m_visitor->after_init();
_sweep();
_complete_sweep();
m_visitor->after_sweep();
}
/*! Get an iterator for the first subcurve in the status line. */
Status_line_iterator status_line_begin()
{ return (m_statusLine.begin()); }
Status_line_iterator status_line_begin() { return m_statusLine.begin(); }
/*! Get a past-the-end iterator for the subcurves in the status line. */
Status_line_iterator status_line_end()
{ return (m_statusLine.end()); }
Status_line_iterator status_line_end() { return m_statusLine.end(); }
/*! Get the status line size. */
unsigned int status_line_size() const
{ return (m_statusLine.size()); }
unsigned int status_line_size() const { return m_statusLine.size(); }
/*! Check if the status line is empty. */
bool is_status_line_empty() const
{ return (m_statusLine.empty()); }
bool is_status_line_empty() const { return m_statusLine.empty(); }
/*! Get an iterator for the first event in event queue. */
Event_queue_iterator event_queue_begin()
{ return (m_queue->begin()); }
Event_queue_iterator event_queue_begin() { return m_queue->begin(); }
/*! Get a past-the-end iterator for the events in the in event queue. */
Event_queue_iterator event_queue_end()
{ return (m_queue->end()); }
Event_queue_iterator event_queue_end() { return m_queue->end(); }
/*! Get the event queue size. */
unsigned int event_queue_size() const
{ return (m_queue->size()); }
unsigned int event_queue_size() const { return m_queue->size(); }
/*! Check if the event queue is empty. */
bool is_event_queue_empty() const
{ return (m_queue->empty()); }
bool is_event_queue_empty() const { return m_queue->empty(); }
/*! Stop the sweep by erasing the event queue (except for the current event).
* This function may called by the visitor during 'arter_handle_event' in
@ -512,6 +529,19 @@ protected:
{ CGAL_error(); }
#ifdef CGAL_SL_VERBOSE
uint8_t m_indent_size;
bool m_need_indent;
void print_text(const char* text, bool do_eol = false);
void print_eol();
void increase_indent();
void decrease_indent();
void print_start(const char* name, bool do_eol = true);
void print_end(const char* name, bool do_eol = true);
void print_curve(const Base_subcurve* sc);
void print_event_info(const Event* e);
void PrintEventQueue();
void PrintSubCurves();
void PrintStatusLine();

View File

@ -12,12 +12,9 @@
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// (based on old version by Tali Zvi)
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
// (based on old version by Tali Zvi)
#ifndef CGAL_SWEEP_LINE_2_H
#define CGAL_SWEEP_LINE_2_H
@ -39,7 +36,7 @@ namespace CGAL {
* on the algorithm of Bentley and Ottmann.
* It extends the algorithm to support not only segments but general x-monotone
* curves as well and isolated points.
* The X_monotone_curve_2 type and Point_2 are defined by the traits class that
* The X_monotone_curve_2 type and Point_2 are defined by the traits class that
* is one of the template arguments.
*
* The algorithm is also extended to support the following degenerate cases:
@ -50,22 +47,22 @@ namespace CGAL {
*
* General flow:
* After the initialization stage, the events are handled from left to right.
*
*
* For each event
*
* First pass - handles special cases in which curves start or end
* First pass - handles special cases in which curves start or end
* at the interior of another curve
* Handle left curves - iterate over the curves that intersect
* Handle left curves - iterate over the curves that intersect
* at the event point and defined lexicographically to the left
* of the event.
* Handle right curves - iterate over the curves that intersect
* of the event.
* Handle right curves - iterate over the curves that intersect
* the event point and defined lexicographically to the right
* of the event point. This is where new intersection points
* of the event point. This is where new intersection points
* are calculated.
* End
*
* Convensions through out the code:
* In order to make the code as readable as possible, some convensions were
* In order to make the code as readable as possible, some convensions were
* made in regards to variable naming:
*
* xp - is the intersection point between two curves
@ -73,35 +70,27 @@ namespace CGAL {
*
*/
template < class Traits_,
class Visitor_,
class Subcurve_ = Sweep_line_subcurve<Traits_>,
class Event_ = Sweep_line_event<Traits_, Subcurve_>,
typename Allocator_ = CGAL_ALLOCATOR(int) >
class Sweep_line_2 : public Basic_sweep_line_2<Traits_,
Visitor_,
Subcurve_,
Event_,
Allocator_>
template <typename Traits_, typename Visitor_,
typename Subcurve_ = Sweep_line_subcurve<Traits_>,
typename Event_ = Sweep_line_event<Traits_, Subcurve_>,
typename Allocator_ = CGAL_ALLOCATOR(int) >
class Sweep_line_2 :
public Basic_sweep_line_2<Traits_, Visitor_, Subcurve_, Event_, Allocator_>
{
public:
typedef Traits_ Traits_2;
typedef Visitor_ Visitor;
typedef Event_ Event;
typedef Subcurve_ Subcurve;
typedef Allocator_ Allocator;
typedef Basic_sweep_line_2<Traits_2,
Visitor,
Subcurve,
Event,
Allocator> Base;
typedef Basic_sweep_line_2<Traits_2, Visitor, Subcurve, Event, Allocator>
Base;
typedef typename Base::Traits_adaptor_2 Traits_adaptor_2;
typedef typename Traits_adaptor_2::Point_2 Point_2;
typedef typename Traits_adaptor_2::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Base::Event_queue_iterator Event_queue_iterator;
typedef typename Event::Subcurve_iterator Event_subcurve_iterator;
@ -109,24 +98,22 @@ public:
typedef typename Base_event::Attribute Attribute;
typedef typename Base::Base_subcurve Base_subcurve;
typedef std::list<Subcurve*> Subcurve_container;
typedef typename Subcurve_container::iterator Subcurve_iterator;
typedef typename Subcurve_container::iterator Subcurve_iterator;
typedef typename Base::Status_line_iterator Status_line_iterator;
typedef CGAL::Curve_pair<Subcurve> Curve_pair;
typedef CGAL::Curve_pair_hasher<Subcurve> Curve_pair_hasher;
typedef CGAL::Equal_curve_pair<Subcurve> Equal_curve_pair;
typedef Open_hash<Curve_pair,
Curve_pair_hasher,
Equal_curve_pair> Curve_pair_set;
typedef CGAL::Curve_pair<Subcurve> Curve_pair;
typedef CGAL::Curve_pair_hasher<Subcurve> Curve_pair_hasher;
typedef CGAL::Equal_curve_pair<Subcurve> Equal_curve_pair;
typedef Open_hash<Curve_pair, Curve_pair_hasher, Equal_curve_pair>
Curve_pair_set;
typedef random_access_input_iterator<std::vector<Object> >
vector_inserter;
protected:
// Data members:
Subcurve_container m_overlap_subCurves;
// Contains all of the new sub-curves
@ -145,13 +132,10 @@ public:
/*! Constructor.
* \param visitor A pointer to a sweep-line visitor object.
*/
Sweep_line_2 (Visitor* visitor) :
Base(visitor),
m_curves_pair_set(0)
{}
Sweep_line_2(Visitor* visitor) : Base(visitor), m_curves_pair_set(0) {}
/*!
* Constructor.
* Construct.
* \param traits A pointer to a sweep-line traits object.
* \param visitor A pointer to a sweep-line visitor object.
*/
@ -160,7 +144,7 @@ public:
m_curves_pair_set(0)
{}
/*! Destrcutor. */
/*! Destrcut. */
virtual ~Sweep_line_2() {}
protected:
@ -196,14 +180,14 @@ protected:
*/
void _handle_overlap(Event* event, Subcurve* curve,
Event_subcurve_iterator iter, bool overlap_exist);
/*! Compute intersections between the two given curves.
* If the two curves intersect, create a new event (or use the event that
* If the two curves intersect, create a new event (or use the event that
* already exits in the intersection point) and insert the curves to the
* event.
* \param curve1 The first curve.
* \param curve2 The second curve.
*/
*/
void _intersect(Subcurve* c1, Subcurve* c2);
/*! When a curve is removed from the status line for good, its top and
@ -232,7 +216,6 @@ protected:
* \param sc The subcurve.
*/
void _fix_finished_overlap_subcurve(Subcurve* sc);
};
} //namespace CGAL

View File

@ -12,10 +12,6 @@
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Eric Berberich <ericb@post.tau.ac.il>
@ -46,9 +42,11 @@ Basic_sweep_line_2(Visitor* visitor) :
m_status_line_insert_hint(m_statusLine.begin()),
m_num_of_subCurves(0),
m_visitor(visitor)
{
m_visitor->attach(this);
}
#ifdef CGAL_SL_VERBOSE
, m_indent_size(0)
, m_need_indent(false)
#endif
{ m_visitor->attach(this); }
//-----------------------------------------------------------------------------
// Constructor with a given traits-class.
@ -66,9 +64,11 @@ Basic_sweep_line_2(const Traits_2* traits, Visitor* visitor) :
m_status_line_insert_hint(m_statusLine.begin()),
m_num_of_subCurves(0),
m_visitor(visitor)
{
m_visitor->attach(this);
}
#ifdef CGAL_SL_VERBOSE
, m_indent_size(0)
, m_need_indent(false)
#endif
{ m_visitor->attach(this); }
//-----------------------------------------------------------------------------
// Destrcutor.
@ -84,11 +84,9 @@ Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::~Basic_sweep_line_2()
delete m_queue;
// Free all the event that have not been de-allocated so far.
Allocated_events_iterator iter;
Event* p_event;
for (iter = m_allocated_events.begin();
iter != m_allocated_events.end(); ++iter)
{
Allocated_events_iterator iter = m_allocated_events.begin();
for (; iter != m_allocated_events.end(); ++iter) {
p_event = *iter;
m_eventAlloc.destroy(p_event);
m_eventAlloc.deallocate(p_event,1);
@ -107,12 +105,12 @@ void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::stop_sweep()
Event_queue_iterator qiter= this->m_queue->begin();
for (++qiter; qiter != this->m_queue->end(); ++qiter)
this ->deallocate_event(*qiter);
this->deallocate_event(*qiter);
// Clear the status line.
this -> m_statusLine.clear();
this-> m_statusLine.clear();
m_status_line_insert_hint = this->m_statusLine.begin();
// Empty the event queue, and leave only the first event there.
CGAL_assertion(!m_queue->empty());
Event_queue_iterator second = m_queue->begin();
@ -135,10 +133,10 @@ deallocate_event(Event* event)
{
// Remove the event from the set of allocated events.
m_allocated_events.erase(event);
// Perfrom the actual deallocation.
m_eventAlloc.destroy(event);
m_eventAlloc.deallocate(event,1);
m_eventAlloc.deallocate(event, 1);
}
//-----------------------------------------------------------------------------
@ -148,43 +146,43 @@ template <typename Tr, typename Vis, typename Subcv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_sweep()
{
CGAL_SL_DEBUG(
{
CGAL_PRINT("Ordered sequence of " << m_queue->size()
<< " initial events:\n");
Event_queue_iterator eventIter1 = m_queue->begin();
while (eventIter1 != m_queue->end()) {
CGAL_PRINT("* ");
CGAL_SL_DEBUG(PrintEvent(*eventIter1););
CGAL_PRINT( "\n");
eventIter1++;
}
}
)
CGAL_SL_PRINT_TEXT("Ordered sequence of ");
CGAL_SL_PRINT(m_queue->size());
CGAL_SL_PRINT_TEXT(" initial events:");
CGAL_SL_PRINT_EOL();
CGAL_SL_DEBUG(Event_queue_iterator eventIter1 = m_queue->begin();
while (eventIter1 != m_queue->end()) {
print_text("* ");
PrintEvent(*eventIter1);
print_eol();
eventIter1++;
})
// Looping over the events in the queue.
Event_queue_iterator eventIter = m_queue->begin();
while (eventIter != m_queue->end()) {
// Get the next event from the queue.
m_currentEvent = *eventIter;
CGAL_PRINT("------------- ");
CGAL_SL_DEBUG(PrintEvent(m_currentEvent););
CGAL_PRINT( " --------------\n");
CGAL_SL_DEBUG(PrintStatusLine();
m_currentEvent->Print(););
// Handle the subcurves that are to the left of the event point (i.e.,
CGAL_SL_PRINT_EOL();
CGAL_SL_PRINT_TEXT("------------- ");
CGAL_SL_DEBUG(PrintEvent(m_currentEvent));
CGAL_SL_PRINT_TEXT( " --------------");
CGAL_SL_PRINT_EOL();
CGAL_SL_PRINT_EOL();
CGAL_SL_PRINT_STATUS_LINE();
CGAL_SL_PRINT_EVENT_INFO(m_currentEvent);
// Handle the subcurves that are to the left of the event point (i.e.,
// subcurves that we are done with).
_handle_left_curves();
// Handle the subcurves to the right of the event point, reorder them
// and test for intersections between them and their immediate neighbors
// on the status line.
_handle_right_curves();
// Inform the visitor about the event. The visitor also determines whether
// it is possible to deallocate the event now, or will it be deallocated
// later (at the visitor's responsibility).
@ -227,7 +225,7 @@ void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_complete_sweep()
{
CGAL_assertion(m_queue->empty());
CGAL_assertion((m_statusLine.size() == 0));
// Free all subcurve objects.
for (unsigned int i = 0; i < m_num_of_subCurves; ++i)
m_subCurveAlloc.destroy(m_subCurves + i);
@ -252,7 +250,7 @@ _init_point(const Point_2& pt, Attribute type)
bool is_new = pair_res.second;
m_visitor->update_event(pair_res.first, pt, is_new);
}
//-----------------------------------------------------------------------------
// Initialize the events associated with an x-monotone curve.
//
@ -261,11 +259,11 @@ template <typename Tr, typename Vis, typename Subcv, typename Evnt,
void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::
_init_curve(const X_monotone_curve_2& curve, unsigned int index)
{
// Construct an initialize a subcurve object.
// Construct and initialize a subcurve object.
m_subCurveAlloc.construct(m_subCurves + index, m_masterSubcurve);
(m_subCurves + index)->set_hint(this->m_statusLine.end());
(m_subCurves + index)->init(curve);
// Create two events associated with the curve ends.
_init_curve_end(curve, ARR_MAX_END, m_subCurves + index);
_init_curve_end(curve, ARR_MIN_END, m_subCurves + index);
@ -321,12 +319,14 @@ _init_curve_end(const X_monotone_curve_2& cv, Arr_curve_end ind, Subcurve* sc)
template <typename Tr, typename Vis, typename Subcv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_left_curves()
{
CGAL_PRINT("Handling left curve" << std::endl;);
{
CGAL_SL_PRINT_START_EOL("handling left curves at (");
CGAL_SL_DEBUG(PrintEvent(m_currentEvent));
CGAL_SL_PRINT_EOL();
m_is_event_on_above = false;
if (! m_currentEvent->has_left_curves()) {
if (! m_currentEvent->has_left_curves()) {
// The current event does not have any incident left subcurves, so we
// should find a place for it in the status line (the function we call
// update the m_status_line_insert_hint and m_is_event_on_above members).
@ -340,7 +340,7 @@ void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_left_curves()
// this is possible only if the event is an isolated query point.
CGAL_assertion(! m_currentEvent->has_right_curves() &&
m_currentEvent->is_query());
//m_is_event_on_above = true;
m_visitor->before_handle_event(m_currentEvent);
}
@ -349,17 +349,17 @@ void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_left_curves()
}
else
m_visitor->before_handle_event(m_currentEvent);
// Nothing else to do (no left curves).
CGAL_SL_PRINT_END_EOL("handling left curves");
return;
}
CGAL_PRINT("left curves before sorting: "<<"\n";);
CGAL_SL_DEBUG(if (m_currentEvent->left_curves_begin() !=
m_currentEvent->left_curves_end() )
{
m_currentEvent->Print();
});
CGAL_SL_PRINT_TEXT("left curves before sorting:");
CGAL_SL_PRINT_EOL();
CGAL_SL_DEBUG(if (m_currentEvent->left_curves_begin() !=
m_currentEvent->left_curves_end())
{ print_event_info(m_currentEvent); });
// Use the status-line to sort all left subcurves incident to the current
// event (no geometric comparisons are neede at all).
@ -368,27 +368,26 @@ void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_left_curves()
// Now the event is updated, with its left subcurved properly sorted, and
// we can inform the visitor that we are about to handle this event.
m_visitor->before_handle_event(m_currentEvent);
CGAL_PRINT("left curves after sorting: " << std::endl);
CGAL_SL_DEBUG(if (m_currentEvent->left_curves_begin() !=
m_currentEvent->left_curves_end())
{
m_currentEvent->Print();
});
CGAL_SL_PRINT_TEXT("left curves after sorting:");
CGAL_SL_PRINT_EOL();
CGAL_SL_DEBUG(if (m_currentEvent->left_curves_begin() !=
m_currentEvent->left_curves_end() )
{ print_event_info(m_currentEvent); });
// Remove all left subcurves from the status line, and inform the visitor
// that we are done handling these subcurves.
Event_subcurve_iterator left_iter = m_currentEvent->left_curves_begin();
while (left_iter != m_currentEvent->left_curves_end()) {
Subcurve* left_sc = *left_iter;
m_visitor->add_subcurve(left_sc->last_curve(), left_sc);
++left_iter;
_remove_curve_from_status_line(left_sc);
_remove_curve_from_status_line(left_sc);
}
CGAL_PRINT( "Handling left curve END" << std::endl;);
CGAL_SL_PRINT_END_EOL("handling left curves");
}
//-----------------------------------------------------------------------------
@ -409,13 +408,13 @@ _handle_event_without_left_curves()
// subcurve in the status line).
const std::pair<Status_line_iterator, bool>& pair_res =
m_statusLine.find_lower(m_currentEvent->point(), m_statusLineCurveLess);
m_status_line_insert_hint = pair_res.first;
m_is_event_on_above = pair_res.second;
return;
}
// We have a boundary event, so we can easily locate a plave for it in the
// status line.
@ -451,45 +450,47 @@ template <typename Tr, typename Vis, typename Subcv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_sort_left_curves()
{
CGAL_SL_PRINT_START_EOL("sorting left curves");
CGAL_assertion(m_currentEvent->has_left_curves());
// Get the first curve associated with the event and its position on the
// status line. We proceed from this position up the status line until
// we encounter a subcurve that is not associated with the current event.
Subcurve* curve = *(m_currentEvent->left_curves_begin());
Status_line_iterator sl_iter = curve->hint();
CGAL_assertion(*sl_iter == curve);
// Look for the first curve in the vertical ordering that is also in the
// left curve of the event
for (++sl_iter; sl_iter != m_statusLine.end(); ++sl_iter) {
// left curve of the event
Status_line_iterator end = sl_iter;
for (++end; end != m_statusLine.end(); ++end) {
if (std::find(m_currentEvent->left_curves_begin(),
m_currentEvent->left_curves_end(), *sl_iter) ==
m_currentEvent->left_curves_end(), *end) ==
m_currentEvent->left_curves_end())
break;
}
Status_line_iterator end = sl_iter;
sl_iter = curve->hint();
if (sl_iter == m_statusLine.begin()) {
// In case the lowest subcurve in the status line is associated with the
// current event, we have the range of (sorted) subcurves ready. We
// associate this range with the event, so the curves are now sorted
// according to their vertical positions immediately to the left of the
// event.
m_currentEvent->replace_left_curves(sl_iter,end);
m_currentEvent->replace_left_curves(sl_iter, end);
CGAL_SL_PRINT_END_EOL("sorting left curves");
return;
}
// Go down the status line until we encounter a subcurve that is not
// associated with the current event.
--sl_iter;
for (;sl_iter != m_statusLine.begin(); --sl_iter) {
for (--sl_iter; sl_iter != m_statusLine.begin(); --sl_iter) {
if (std::find(m_currentEvent->left_curves_begin(),
m_currentEvent->left_curves_end(), *sl_iter) ==
m_currentEvent->left_curves_end())
{
// Associate the sorted range of subcurves with the event.
m_currentEvent->replace_left_curves(++sl_iter,end);
m_currentEvent->replace_left_curves(++sl_iter, end);
CGAL_SL_PRINT_END_EOL("sorting left curves");
return;
}
}
@ -500,9 +501,11 @@ void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_sort_left_curves()
if (std::find(m_currentEvent->left_curves_begin(),
m_currentEvent->left_curves_end(), *sl_iter) ==
m_currentEvent->left_curves_end())
m_currentEvent->replace_left_curves(++sl_iter,end);
m_currentEvent->replace_left_curves(++sl_iter, end);
else
m_currentEvent->replace_left_curves(sl_iter,end);
m_currentEvent->replace_left_curves(sl_iter, end);
CGAL_SL_PRINT_END_EOL("sorting left curves");
}
//-----------------------------------------------------------------------------
@ -512,10 +515,10 @@ template <typename Tr, typename Vis, typename Subcv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_right_curves()
{
CGAL_PRINT("Handling right curves (");
CGAL_SL_PRINT_START("Handling right curves at (");
CGAL_SL_DEBUG(PrintEvent(m_currentEvent));
CGAL_PRINT(")\n");
CGAL_SL_PRINT_EOL();
// We have nothing to do if the current event does not have any incident
// right subcurves.
if (! m_currentEvent->has_right_curves()) return;
@ -530,15 +533,17 @@ void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_right_curves()
Status_line_iterator sl_iter;
while (curr != right_end) {
CGAL_PRINT_INSERT(*curr);
CGAL_SL_PRINT_INSERT(*curr);
sl_iter = m_statusLine.insert_before(m_status_line_insert_hint, *curr);
((Subcurve*)(*curr))->set_hint(sl_iter);
Subcurve* sc = *curr;
sc->set_hint(sl_iter);
CGAL_SL_DEBUG(PrintStatusLine(););
++curr;
}
CGAL_SL_DEBUG(PrintStatusLine());
}
CGAL_SL_PRINT_STATUS_LINE();
CGAL_SL_PRINT_END_EOL("handling right curves done");
}
//-----------------------------------------------------------------------------
@ -552,11 +557,11 @@ _add_curve_to_right(Event* event, Subcurve* curve, bool /* overlap_exist */)
#if defined(CGAL_NO_ASSERTIONS)
(void) event->add_curve_to_right(curve, m_traits);
#else
std::pair<bool, Event_subcurve_iterator> pair_res =
std::pair<bool, Event_subcurve_iterator> pair_res =
event->add_curve_to_right(curve, m_traits);
CGAL_assertion(!pair_res.first);
#endif
return false;
}
@ -568,21 +573,23 @@ template <typename Tr, typename Vis, typename Subcv, typename Evnt,
void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::
_remove_curve_from_status_line(Subcurve* sc)
{
CGAL_PRINT("remove_curve_from_status_line\n";);
CGAL_SL_DEBUG(PrintStatusLine(););
CGAL_SL_DEBUG(sc->Print(););
CGAL_SL_PRINT_START("removing a curve from the status line, ");
CGAL_SL_PRINT_CURVE(sc);
CGAL_SL_PRINT_EOL();
CGAL_SL_PRINT_STATUS_LINE();
// Get the position of the subcurve on the status line.
Status_line_iterator sl_iter = sc->hint();
Status_line_iterator sl_iter = sc->hint();
CGAL_assertion(sl_iter != m_statusLine.end());
// The position of the next event can be right after the deleted subcurve.
m_status_line_insert_hint = sl_iter;
++m_status_line_insert_hint;
m_status_line_insert_hint = sl_iter;
++m_status_line_insert_hint;
// Erase the subcurve from the status line.
CGAL_SL_PRINT_ERASE(*sl_iter);
m_statusLine.erase(sl_iter);
CGAL_PRINT("remove_curve_from_status_line Done\n";)
CGAL_SL_PRINT_END_EOL("removing a curve from the status line");
}
//-----------------------------------------------------------------------------
@ -596,7 +603,7 @@ _allocate_event(const Point_2& pt, Attribute type,
Arr_parameter_space ps_x, Arr_parameter_space ps_y)
{
// Allocate the event.
Event* e = m_eventAlloc.allocate(1);
Event* e = m_eventAlloc.allocate(1);
m_eventAlloc.construct(e, m_masterEvent);
e->init(pt, type, ps_x, ps_y);
@ -606,7 +613,7 @@ _allocate_event(const Point_2& pt, Attribute type,
}
//-----------------------------------------------------------------------------
// Allocate an event at open boundary,
// Allocate an event at open boundary,
// which is not associated with a valid point.
//
template <typename Tr, typename Vis, typename Subcv, typename Evnt,
@ -614,10 +621,10 @@ template <typename Tr, typename Vis, typename Subcv, typename Evnt,
typename Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::Event*
Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::
_allocate_event_at_open_boundary(Attribute type,
Arr_parameter_space ps_x,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y)
{
Event* e = m_eventAlloc.allocate(1);
Event* e = m_eventAlloc.allocate(1);
m_eventAlloc.construct(e, m_masterEvent);
e->init_at_open_boundary(type, ps_x, ps_y);
@ -637,24 +644,24 @@ _push_event(const Point_2& pt, Attribute type,
Arr_parameter_space ps_x, Arr_parameter_space ps_y, Subcurve* sc)
{
// Look for the point in the event queue.
Event* e;
Event* e;
m_queueEventLess.set_parameter_space_in_x(ps_x);
m_queueEventLess.set_parameter_space_in_y(ps_y);
m_queueEventLess.set_parameter_space_in_y(ps_y);
const std::pair<Event_queue_iterator, bool>& pair_res =
m_queue->find_lower(pt, m_queueEventLess);
const bool exist = pair_res.second;
if (! exist) {
// The point is not found in the event queue - create a new event and
// insert it into the queue.
e = _allocate_event(pt, type, ps_x, ps_y);
e = _allocate_event(pt, type, ps_x, ps_y);
}
else {
// The event associated with the given point already exists in the queue,
// so we just have to update it.
e = *(pair_res.first);
CGAL_assertion(e->is_closed());
e->set_attribute(type);
}
@ -673,17 +680,17 @@ _push_event(const Point_2& pt, Attribute type,
e->add_curve_to_left(sc);
}
}
if (! exist) {
// Insert the new event into the queue using the hint we got when we
// looked for it.
m_queue->insert_before(pair_res.first, e);
CGAL_PRINT_NEW_EVENT(pt, e);
CGAL_SL_PRINT_NEW_EVENT(pt, e);
}
else {
CGAL_PRINT_UPDATE_EVENT(pt, e);
CGAL_SL_PRINT_UPDATE_EVENT(pt, e);
}
// Return the resulting event and a flag indicating whether we have created
// a new event.
return (std::make_pair(e, !exist));
@ -702,10 +709,10 @@ _push_event(const X_monotone_curve_2& cv, Arr_curve_end ind, Attribute type,
{
//cv has no member named 'base'
//std::cout << "cv: " << cv.base() << std::endl;
// Look for the curve end in the event queue.
Event* e;
Event* e;
m_queueEventLess.set_parameter_space_in_x(ps_x);
m_queueEventLess.set_parameter_space_in_y(ps_y);
m_queueEventLess.set_index(ind);
@ -713,14 +720,14 @@ _push_event(const X_monotone_curve_2& cv, Arr_curve_end ind, Attribute type,
const std::pair<Event_queue_iterator, bool>& pair_res =
m_queue->find_lower(cv, m_queueEventLess);
const bool exist = pair_res.second;
if (! exist) {
// The curve end is not found in the event queue - create a new event and
// insert it into the queue.
if (m_traits->is_closed_2_object()(cv, ind)) {
// The curve end is closed and so it is associated with a valid
// point.
const Point_2& pt = (ind == ARR_MIN_END) ?
const Point_2& pt = (ind == ARR_MIN_END) ?
m_traits->construct_min_vertex_2_object()(cv) :
m_traits->construct_max_vertex_2_object()(cv);

View File

@ -12,77 +12,135 @@
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_SWEEP_LINE_2_DEBUG_H
#define CGAL_SWEEP_LINE_2_DEBUG_H
#include <CGAL/Basic_sweep_line_2.h>
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// DEBUG UTILITIES //
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
template <typename Tr, typename Visit, typename Crv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Visit, Crv, Evnt, Alloc>::
print_text(const char* text, bool do_eol)
{
if (m_need_indent)
for (uint8_t i = m_indent_size; i != 0; --i) std::cout << " ";
std::cout << text;
m_need_indent = false;
if (do_eol) print_eol();
}
template <typename Tr, typename Visit, typename Crv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Visit, Crv, Evnt, Alloc>::print_eol()
{
std::cout << std::endl;
m_need_indent = true;
}
template <class Tr, class Visit, class Crv, class Evnt, class Alloc>
template <typename Tr, typename Visit, typename Crv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Visit, Crv, Evnt, Alloc>::increase_indent()
{ m_indent_size += 2; }
template <typename Tr, typename Visit, typename Crv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Visit, Crv, Evnt, Alloc>::decrease_indent()
{ m_indent_size -= 2; }
template <typename Tr, typename Visit, typename Crv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Visit, Crv, Evnt, Alloc>::
print_start(const char* name, bool do_eol)
{
print_text("Start ");
print_text(name);
if (do_eol) print_eol();
increase_indent();
}
template <typename Tr, typename Visit, typename Crv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Visit, Crv, Evnt, Alloc>::
print_end(const char* name, bool do_eol)
{
decrease_indent();
print_text("End ");
print_text(name);
if (do_eol) print_eol();
}
template <typename Tr, typename Visit, typename Crv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Visit, Crv, Evnt, Alloc>::
print_curve(const Base_subcurve* sc)
{
if (m_need_indent)
for (uint8_t i = m_indent_size; i != 0; --i) std::cout << " ";
sc->Print();
m_need_indent = false;
}
template <typename Tr, typename Visit, typename Crv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Visit, Crv, Evnt, Alloc>::PrintEventQueue()
{
CGAL_SL_DEBUG(std::cout << std::endl << "Event queue: " << std::endl;)
print_text("Event queue: ", true);
Event_queue_iterator iter = m_queue->begin();
while ( iter != m_queue->end() )
{
Event *e = *iter;
e->Print();
++iter;
while (iter != m_queue->end()) {
Event* e = *iter++;
e->Print();
}
CGAL_SL_DEBUG(std::cout << "--------------------------------" << std::endl;)
}
template <class Tr, class Visit, class Crv, class Evnt, class Alloc>
template <typename Tr, typename Visit, typename Crv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Visit, Crv, Evnt, Alloc>::PrintSubCurves()
{
CGAL_SL_DEBUG(std::cout << std::endl << "Sub curves: " << std::endl;)
for(unsigned int i=0 ; i < m_num_of_subCurves ; ++i)
{
m_subCurves[i].Print();
}
print_text("Sub curves: ", true);
for (size_t i = 0; i < m_num_of_subCurves; ++i) m_subCurves[i].Print();
print_eol();
}
template <class Tr, class Visit, class Crv, class Evnt, class Alloc>
template <typename Tr, typename Visit, typename Crv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Visit, Crv, Evnt, Alloc>::PrintStatusLine()
{
if ( m_statusLine.size() == 0) {
std::cout << std::endl << "Status line: empty" << std::endl;
if (m_statusLine.size() == 0) {
print_text("Status line: empty", true);
return;
}
std::cout << std::endl << "Status line: (" ;
if(m_currentEvent->is_closed())
std::cout << m_currentEvent->point() << ")" << std::endl;
else
{
Arr_parameter_space x = m_currentEvent->parameter_space_in_x(),
y = m_currentEvent->parameter_space_in_y();
print_text("Status line: ");
if (m_currentEvent->is_closed())
std::cout << "(" << m_currentEvent->point() << ")";
else {
Arr_parameter_space x = m_currentEvent->parameter_space_in_x();
Arr_parameter_space y = m_currentEvent->parameter_space_in_y();
PrintOpenBoundaryType(x, y);
}
print_eol();
increase_indent();
Status_line_iterator iter = m_statusLine.begin();
while ( iter != m_statusLine.end() )
{
(*iter)->Print();
while (iter != m_statusLine.end()) {
print_curve(*iter);
print_eol();
++iter;
}
std::cout << "Status line - end" << std::endl;
decrease_indent();
print_text("Status line end");
print_eol();
}
template <class Tr, class Visit, class Crv, class Evnt, class Alloc>
template <typename Tr, typename Visit, typename Crv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Visit, Crv, Evnt, Alloc>::
PrintOpenBoundaryType (Arr_parameter_space ps_x, Arr_parameter_space ps_y)
{
@ -101,19 +159,46 @@ PrintOpenBoundaryType (Arr_parameter_space ps_x, Arr_parameter_space ps_y)
}
}
template <class Tr, class Visit, class Crv, class Evnt, class Alloc>
template <typename Tr, typename Visit, typename Crv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Visit, Crv, Evnt, Alloc>::
PrintEvent(const Event* e)
{
if (e->is_closed())
std::cout << e->point();
else
{
if (e->is_closed()) std::cout << e->point();
else {
Arr_parameter_space x = e->parameter_space_in_x();
Arr_parameter_space y = e->parameter_space_in_y();
PrintOpenBoundaryType(x, y);
std::cout << " with open curve: " << e->curve();
}
}
}
template <typename Tr, typename Visit, typename Crv, typename Evnt,
typename Alloc>
void Basic_sweep_line_2<Tr, Visit, Crv, Evnt, Alloc>::
print_event_info(const Event* e)
{
print_text("Event Info: ");
PrintEvent(e);
print_eol();
increase_indent();
print_text("Left curves:", true);
increase_indent();
Event_subcurve_const_iterator iter;
for (iter = e->left_curves_begin(); iter != e->left_curves_end(); ++iter) {
print_curve(*iter);
print_eol();
}
decrease_indent();
print_text("Right curves:", true);
increase_indent();
for (iter = e->right_curves_begin(); iter != e->right_curves_end(); ++iter) {
print_curve(*iter);
print_eol();
}
decrease_indent();
decrease_indent();
print_text("End Event Info", true);
}
#endif

View File

@ -12,13 +12,9 @@
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// (based on old version by Tali Zvi)
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// (based on old version by Tali Zvi)
#ifndef CGAL_SWEEP_LINE_2_IMPL_H
#define CGAL_SWEEP_LINE_2_IMPL_H
@ -38,7 +34,7 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_init_structures()
{
// Initailize the structures maintained by the base sweep-line class.
Base::_init_structures();
// Resize the hash to be O(2*n), where n is the number of input curves.
m_curves_pair_set.resize(2 * this->m_num_of_subCurves);
}
@ -50,12 +46,14 @@ template <typename Tr, typename Vis, typename Subcv, typename Evnt,
typename Alloc>
void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_complete_sweep()
{
CGAL_SL_PRINT_START_EOL("completing the sweep");
// Complete the sweep process using base sweep-line class.
Base::_complete_sweep();
// Clean the set of curve pairs for which we have computed intersections.
m_curves_pair_set.clear();
// Free all overlapping subcurves we have created.
Subcurve_iterator itr;
for (itr = m_overlap_subCurves.begin(); itr != m_overlap_subCurves.end();
@ -64,8 +62,10 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_complete_sweep()
this->m_subCurveAlloc.destroy(*itr);
this->m_subCurveAlloc.deallocate(*itr, 1);
}
m_overlap_subCurves.clear();
CGAL_SL_PRINT_END_EOL("completing the sweep");
}
//-----------------------------------------------------------------------------
@ -75,19 +75,26 @@ template <typename Tr, typename Vis, typename Subcv, typename Evnt,
typename Alloc>
void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_left_curves()
{
CGAL_PRINT("Handling left curve" << std::endl);
CGAL_SL_PRINT_START("handling left curves at (");
CGAL_SL_DEBUG(this->PrintEvent(this->m_currentEvent));
CGAL_SL_PRINT_TEXT(")");
CGAL_SL_PRINT_EOL();
this->m_is_event_on_above = false;
if (! this->m_currentEvent->has_left_curves()) {
// In case the current event has no left subcurves incident to it, we have
// to locate a place for it in the status line.
CGAL_PRINT(" - handling special case " << std::endl);
CGAL_SL_PRINT_TEXT("Handling case: no left curves");
CGAL_SL_PRINT_EOL();
this->_handle_event_without_left_curves();
Status_line_iterator sl_pos = this->m_status_line_insert_hint;
if (this->m_is_event_on_above) {
CGAL_SL_PRINT_TEXT("The event is on a curve in the status line");
CGAL_SL_PRINT_EOL();
// The current event point starts at the interior of a subcurve that
// already exists in the status line (this may also indicate an overlap).
if (! this->m_currentEvent->has_right_curves()) {
@ -103,69 +110,70 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_left_curves()
// intersection.
CGAL_assertion(this->m_currentEvent->is_action());
this->m_currentEvent->set_weak_intersection();
}
}
// Obtain the subcurve that contains the current event, and add it to
// the left curves incident to the event.
Subcurve* sc = static_cast<Subcurve*>(*(this->m_status_line_insert_hint));
const X_monotone_curve_2& last_curve = sc->last_curve();
const X_monotone_curve_2& last_curve = sc->last_curve();
this->m_currentEvent->set_weak_intersection();
this->m_visitor->update_event(this->m_currentEvent, sc);
this->m_currentEvent->add_curve_to_left(sc);
// If necessary, add the subcurves as a right incident curve as well.
// We also check for overlaps.
bool is_overlap = _add_curve_to_right(this->m_currentEvent, sc);
this->m_traits->split_2_object()(last_curve,
this->m_currentEvent->point(),
this->m_currentEvent->point(),
sub_cv1, sub_cv2);
++(this->m_status_line_insert_hint);
++(this->m_status_line_insert_hint);
if (is_overlap) {
// Handle overlaps.
this->m_visitor->before_handle_event(this->m_currentEvent);
this->m_visitor->add_subcurve(sub_cv1, sc);
CGAL_SL_PRINT_ERASE(*sl_pos);
this->m_statusLine.erase(sl_pos);
CGAL_SL_PRINT_END_EOL("handling left curves");
return;
}
}
else {
// The event is not located on any subcurve.
this->m_visitor->before_handle_event(this->m_currentEvent);
CGAL_SL_PRINT_END_EOL("handling left curves");
return;
}
}
CGAL_PRINT("left curves before sorting: " << std::endl);
CGAL_SL_DEBUG(if (this->m_currentEvent->left_curves_begin() !=
this->m_currentEvent->left_curves_end() )
{
this->m_currentEvent->Print();
});
CGAL_SL_PRINT_TEXT("left curves before sorting:");
CGAL_SL_PRINT_EOL();
CGAL_SL_DEBUG(if (this->m_currentEvent->left_curves_begin() !=
this->m_currentEvent->left_curves_end())
{ this->print_event_info(this->m_currentEvent); });
_fix_overlap_subcurves();
this->_sort_left_curves();
this->m_visitor->before_handle_event(this->m_currentEvent);
CGAL_PRINT("left curves after sorting: " << std::endl);
CGAL_SL_DEBUG(if (this->m_currentEvent->left_curves_begin() !=
this->m_currentEvent->left_curves_end() )
{
this->m_currentEvent->Print();
});
// Check if the curve should be removed for good.
bool remove_for_good = false;
Event_subcurve_iterator left_iter =
this->m_currentEvent->left_curves_begin();
CGAL_SL_PRINT_TEXT("left curves after sorting:");
CGAL_SL_PRINT_EOL();
CGAL_SL_DEBUG(if (this->m_currentEvent->left_curves_begin() !=
this->m_currentEvent->left_curves_end() )
{ this->print_event_info(this->m_currentEvent); });
// Check if the curve should be removed for good.
bool remove_for_good = false;
Event_subcurve_iterator left_iter =
this->m_currentEvent->left_curves_begin();
while (left_iter != this->m_currentEvent->left_curves_end()) {
Subcurve* leftCurve = *left_iter;
if ((Event*)leftCurve->right_event() == this->m_currentEvent) {
Subcurve* leftCurve = *left_iter;
if ((Event*)leftCurve->right_event() == this->m_currentEvent) {
// we are done with that subcurve (current event point is his right
// end point) so we remove it from the status line for good.
remove_for_good = true;
@ -174,21 +182,22 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_left_curves()
else {
// curren event splits the subcurve.
const X_monotone_curve_2& lastCurve = leftCurve->last_curve();
this->m_traits->split_2_object()(lastCurve, this->m_currentEvent->point(),
sub_cv1, sub_cv2);
this->m_visitor->add_subcurve(sub_cv1, leftCurve);
leftCurve->set_last_curve(sub_cv2);
}
++left_iter;
//remove curve from the status line (also checks intersection
//remove curve from the status line (also checks intersection
//between the neighbouring curves,only if the curve is removed for good)
_remove_curve_from_status_line(leftCurve, remove_for_good);
_remove_curve_from_status_line(leftCurve, remove_for_good);
}
CGAL_PRINT("Handling left curve END" << std::endl);
CGAL_SL_PRINT_END_EOL("handling left curves");
}
//-----------------------------------------------------------------------------
// Handle the subcurves to the right of the current event point.
//
@ -196,49 +205,55 @@ template <typename Tr, typename Vis, typename Subcv, typename Evnt,
typename Alloc>
void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_right_curves()
{
CGAL_PRINT("Handling right curves (");
CGAL_SL_PRINT_START("handling right curves at (");
CGAL_SL_DEBUG(this->PrintEvent(this->m_currentEvent));
CGAL_PRINT(")\n");
if (! this->m_currentEvent->has_right_curves()) return;
CGAL_SL_PRINT_TEXT(")");
CGAL_SL_PRINT_EOL();
if (! this->m_currentEvent->has_right_curves()) {
CGAL_SL_PRINT_END_EOL("handling right curves");
return;
}
// Loop over the curves to the right of the status line and handle them:
// - If we are at the beginning of the curve, we insert it to the status
// - If we are at the beginning of the curve, we insert it to the status
// line, then we look if it intersects any of its neighbors.
// - If we are at an intersection point between two curves, we add them
// to the status line and attempt to intersect them with their neighbors
// - We also check to see if the two intersect again to the right of the
// - We also check to see if the two intersect again to the right of the
// point.
Event_subcurve_iterator currentOne =
Event_subcurve_iterator currentOne =
this->m_currentEvent->right_curves_begin();
Event_subcurve_iterator rightCurveEnd =
this->m_currentEvent->right_curves_end();
CGAL_PRINT_INSERT(*currentOne);
Status_line_iterator slIter =
this->m_statusLine.insert_before(this->m_status_line_insert_hint,
CGAL_SL_PRINT_INSERT(*currentOne);
Status_line_iterator slIter =
this->m_statusLine.insert_before(this->m_status_line_insert_hint,
*currentOne);
((Subcurve*)(*currentOne))->set_hint(slIter);
CGAL_SL_DEBUG(this->PrintStatusLine());
if (slIter != this->m_statusLine.begin()) {
Subcurve* sc = *currentOne;
sc->set_hint(slIter);
CGAL_SL_PRINT_STATUS_LINE();
if (slIter != this->m_statusLine.begin()) {
// get the previous curve in the y-str
Status_line_iterator prev = slIter; --prev;
_intersect(static_cast<Subcurve*>(*prev), static_cast<Subcurve*>(*slIter));
}
Event_subcurve_iterator prevOne = currentOne;
++currentOne;
while (currentOne != rightCurveEnd) {
CGAL_PRINT_INSERT(*currentOne);
CGAL_SL_PRINT_INSERT(*currentOne);
slIter = this->m_statusLine.insert_before
(this->m_status_line_insert_hint, *currentOne);
((Subcurve*)(*currentOne))->set_hint(slIter);
CGAL_SL_DEBUG(this->PrintStatusLine());
Subcurve* sc = *currentOne;
sc->set_hint(slIter);
CGAL_SL_PRINT_STATUS_LINE();
// If the two curves used to be neighbours before, we do not need to
// intersect them again.
if (!this->m_currentEvent->are_left_neighbours
@ -249,15 +264,17 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_right_curves()
prevOne = currentOne;
++currentOne;
}
CGAL_SL_DEBUG(this->PrintStatusLine());
//the next Subcurve at the status line
}
CGAL_SL_PRINT_STATUS_LINE();
//the next Subcurve at the status line
++slIter;
if (slIter != this->m_statusLine.end())
_intersect(static_cast<Subcurve*>(*prevOne),
static_cast<Subcurve*>(*slIter));
CGAL_SL_PRINT_END_EOL("handling right curves");
}
//-----------------------------------------------------------------------------
@ -268,36 +285,75 @@ template <typename Tr, typename Vis, typename Subcv, typename Evnt,
bool Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::
_add_curve_to_right(Event* event, Subcurve* curve, bool overlap_exist)
{
CGAL_SL_PRINT_START("adding a Curve to the right of (");
CGAL_SL_DEBUG(this->PrintEvent(event));
CGAL_SL_PRINT_TEXT(") ");
CGAL_SL_PRINT_CURVE(curve);
CGAL_SL_PRINT_EOL();
Event_subcurve_iterator iter;
for (iter = event->right_curves_begin(); iter != event->right_curves_end();
++iter)
{
if ((curve == *iter) || (*iter)->is_inner_node(curve))
return false;
if ((curve)->is_inner_node(*iter)) {
*iter = curve;
CGAL_SL_PRINT_CURVE(*iter);
CGAL_SL_PRINT_EOL();
if ((curve == *iter) || (*iter)->is_inner_node(curve)) {
CGAL_SL_PRINT_END_EOL("adding a Curve to the right (curve exists)");
return false;
}
if ((curve)->is_inner_node(*iter)) {
*iter = curve; // replace the current curve with the new one.
CGAL_SL_PRINT_END_EOL
("adding a Curve to the right (curve partially overlaps)");
return false;
}
/*! If the two curves have the exact same leaves, then use the new curve
* as a right curve instead of the existing one.
* \todo EF, this may not be a sufficient condition. It is possible that
* we also need to check whether the event at the right endpoint has a
* matching left curve, and only if it has, make the switch. If this is
* the case, then other modifications are necessary. I hope it's not.
*/
if ((curve)->has_same_leaves(*iter)) {
*iter = curve; // replace the current curve with the new one.
CGAL_SL_PRINT_END_EOL
("adding a Curve to the right (curve completely overlaps)");
return false;
}
if ((curve)->has_common_leaf(*iter)) {
std::list<Base_subcurve*> list_of_sc;
/*! Collect all the distinct nodes of curves including the common nodes.
* \todo EF, common nodes should be excluded. It is not incorrect to
* include a common node, because in the recursive call it becomes
* 'curve', which is an inner node of iter, and it is discarded; see 2
* conditions above.
*/
std::list<Base_subcurve*> list_of_sc;
curve->distinct_nodes(*iter, std::back_inserter(list_of_sc));
typename std::list<Base_subcurve*>::iterator sc_iter;
for (sc_iter = list_of_sc.begin(); sc_iter != list_of_sc.end(); ++sc_iter)
_add_curve_to_right(event, static_cast<Subcurve*>(*sc_iter));
CGAL_SL_PRINT_END_EOL("adding a Curve to the right (common leaf)");
return true;
}
}
std::pair<bool, Event_subcurve_iterator> pair_res =
std::pair<bool, Event_subcurve_iterator> pair_res =
event->add_curve_to_right(curve, this->m_traits);
if (! pair_res.first) return false; // no overlap occurs
if (! pair_res.first) {
// No overlap occurs.
CGAL_SL_PRINT_END_EOL("adding a Curve to the right (no overlap)");
return false;
}
_handle_overlap(event, curve, pair_res.second, overlap_exist);
// Inidicate that an overlap has occured:
CGAL_SL_PRINT_END_EOL("adding a Curve to the right (overlap)");
return true;
}
@ -309,25 +365,27 @@ template <typename Tr, typename Vis, typename Subcv, typename Evnt,
void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::
_remove_curve_from_status_line(Subcurve* leftCurve, bool remove_for_good)
{
CGAL_PRINT("remove_curve_from_status_line\n");
CGAL_SL_DEBUG(this->PrintStatusLine());
CGAL_SL_DEBUG(leftCurve->Print());
CGAL_SL_PRINT_START("removing a curve from the status line, ");
CGAL_SL_PRINT_CURVE(leftCurve);
CGAL_SL_PRINT_EOL();
CGAL_SL_PRINT_STATUS_LINE();
Status_line_iterator sliter = leftCurve->hint();
this->m_status_line_insert_hint = sliter;
++(this->m_status_line_insert_hint);
Status_line_iterator sliter = leftCurve->hint();
this->m_status_line_insert_hint = sliter;
++(this->m_status_line_insert_hint);
if (! remove_for_good) {
// the subcurve is not removed for good, so we dont need to intersect
// his neighbours after its removal.
// its neighbours after its removal.
CGAL_SL_PRINT_ERASE(*sliter);
this->m_statusLine.erase(sliter);
CGAL_PRINT("remove_curve_from_status_line Done\n")
CGAL_SL_PRINT_END_EOL("Removing a curve from the status line");
return;
}
// the subcurve will be removed for good from the stauts line, we need
// to check for intersection between his two neighbours (below and above him)
// but we need to make sure that its not the first or last subcurve
// but we need to make sure that its not the first or last subcurve
// at the status line.
CGAL_assertion(sliter != this->m_statusLine.end());
Status_line_iterator lastOne = this->m_statusLine.end();
@ -336,14 +394,15 @@ _remove_curve_from_status_line(Subcurve* leftCurve, bool remove_for_good)
if (sliter != this->m_statusLine.begin() && sliter != lastOne) {
Status_line_iterator prev = sliter; --prev;
Status_line_iterator next = sliter; ++next;
// intersect *next with *prev
// intersect *next with *prev
_intersect(static_cast<Subcurve*>(*prev),
static_cast<Subcurve*>(*next));
}
CGAL_SL_PRINT_ERASE(*sliter);
this->m_statusLine.erase(sliter);
CGAL_PRINT("remove_curve_from_status_line Done\n")
}
CGAL_SL_PRINT_END_EOL("removing a curve from the status line");
}
//-----------------------------------------------------------------------------
// Compute intersections between the two given curves.
@ -353,19 +412,19 @@ template <typename Tr, typename Vis, typename Subcv, typename Evnt,
void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_intersect(Subcurve* c1,
Subcurve* c2)
{
CGAL_SL_PRINT_START("computing intersection of ");
CGAL_SL_PRINT_CURVE(c1);
CGAL_SL_PRINT_TEXT(" and ");
CGAL_SL_PRINT_CURVE(c2);
CGAL_SL_PRINT_EOL();
typedef typename Tr::Multiplicity Multiplicity;
CGAL_PRINT("Looking for intersection between:\n\t");
CGAL_SL_DEBUG(c1->Print());
CGAL_PRINT("\t");
CGAL_SL_DEBUG(c2->Print());
CGAL_PRINT("\n");
CGAL_assertion(c1 != c2);
// look up for (c1,c2) in the table and insert if doesnt exist
Curve_pair cv_pair(c1,c2);
if (! (m_curves_pair_set.insert(cv_pair)).second )
if (! (m_curves_pair_set.insert(cv_pair)).second)
return; //the curves have already been checked for intersection
float load_factor = static_cast<float>(m_curves_pair_set.size()) /
@ -380,10 +439,10 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_intersect(Subcurve* c1,
this->m_traits->intersect_2_object()(c1->last_curve(), c2->last_curve(), vi);
if (vi == vi_end) {
CGAL_PRINT("no intersection...\n");
CGAL_SL_PRINT_END_EOL("Computing intersection (no intersection)");
return; // no intersection at all
}
// The two subCurves may start at the same point, in that case we ignore the
// first intersection point (if we got to that stage, they cannot overlap).
@ -401,7 +460,7 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_intersect(Subcurve* c1,
ARR_MIN_END);
if ((ps_x1 == ps_x2) && (ps_y1 == ps_y2) &&
((ps_x1 != ARR_INTERIOR) || (ps_y1 != ARR_INTERIOR)) &&
((ps_x1 != ARR_INTERIOR) || (ps_y1 != ARR_INTERIOR)) &&
this->m_traits->is_closed_2_object()(c1->last_curve(), ARR_MIN_END) &&
this->m_traits->is_closed_2_object()(c2->last_curve(), ARR_MIN_END))
{
@ -409,7 +468,8 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_intersect(Subcurve* c1,
(this->m_traits->construct_min_vertex_2_object()(c1->last_curve()),
this->m_traits->construct_min_vertex_2_object()(c2->last_curve())))
{
CGAL_PRINT(" [Skipping common left endpoint on boundary ...]\n");
CGAL_SL_PRINT_TEXT("Skipping common left endpoint on boundary ...");
CGAL_SL_PRINT_EOL();
++vi;
}
}
@ -425,7 +485,8 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_intersect(Subcurve* c1,
--vi_last;
if (object_cast<std::pair<Point_2, Multiplicity> >(&(*vi_last)) != NULL) {
CGAL_PRINT(" [Skipping common right endpoint...]\n");
CGAL_SL_PRINT_TEXT("Skipping common right endpoint...");
CGAL_SL_PRINT_EOL();
--vi_end;
}
}
@ -460,7 +521,8 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_intersect(Subcurve* c1,
--vi_last;
if (object_cast<std::pair<Point_2, Multiplicity> >(&(*vi_last)) != NULL)
{
CGAL_PRINT(" [Skipping common right endpoint on boundary...]\n");
CGAL_SL_PRINT_TEXT("Skipping common right endpoint on boundary...");
CGAL_SL_PRINT_EOL();
--vi_end;
}
}
@ -492,23 +554,27 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_intersect(Subcurve* c1,
if (xp_point != NULL) {
xp = xp_point->first;
multiplicity = xp_point->second;
CGAL_PRINT("found an intersection point: " << xp << std::endl);
CGAL_SL_PRINT_TEXT("Found an intersection point");
CGAL_SL_PRINT_EOL();
_create_intersection_point(xp, multiplicity, c1, c2);
}
else {
icv = object_cast<X_monotone_curve_2>(&(*vi));
CGAL_assertion(icv != NULL);
CGAL_PRINT("found an overlap: " << *icv << std::endl);
CGAL_SL_PRINT_TEXT("Found an overlap");
CGAL_SL_PRINT_EOL();
// TODO EBEB: This code does not work with overlaps that reach the boundary
Point_2 left_xp = this->m_traits->construct_min_vertex_2_object()(*icv);
xp = this->m_traits->construct_max_vertex_2_object()(*icv);
sub_cv1 = *icv;
_create_intersection_point(xp, 0 , c1 , c2);
_create_intersection_point(left_xp, 0 , c1 ,c2, true);
}
}
}
CGAL_SL_PRINT_END_EOL("computing intersection");
}
//-----------------------------------------------------------------------------
@ -522,31 +588,38 @@ _create_intersection_point(const Point_2& xp,
Subcurve*& c1, Subcurve*& c2,
bool is_overlap)
{
// insert the event and check if an event at this point already exists.
const std::pair<Event*, bool>& pair_res =
CGAL_SL_PRINT_START_EOL("createing an intersection point netween");
CGAL_SL_PRINT_CURVE(c1);
CGAL_SL_PRINT_EOL();
CGAL_SL_PRINT_CURVE(c2);
CGAL_SL_PRINT_EOL();
// insert the event and check if an event at this point already exists.
const std::pair<Event*, bool>& pair_res =
this->_push_event(xp, Base_event::DEFAULT, ARR_INTERIOR, ARR_INTERIOR);
Event* e = pair_res.first;
if (pair_res.second) {
CGAL_PRINT("A new event is created .. (" << xp << std::endl);
// a new event is creatd , which inidicates
// that the intersection point cannot be one
//of the end-points of two curves
if (pair_res.second) {
// a new event is creatd , which inidicates that the intersection point
// cannot be one of the end-points of two curves
CGAL_SL_PRINT_TEXT("A new event is created .. (");
CGAL_SL_PRINT(xp);
CGAL_SL_PRINT_TEXT(")");
CGAL_SL_PRINT_EOL();
e->set_intersection();
this->m_visitor ->update_event(e, c1, c2, true);
this->m_visitor->update_event(e, c1, c2, true);
e->push_back_curve_to_left(c1);
e->push_back_curve_to_left(c2);
// Act according to the multiplicity:
if (multiplicity == 0) {
// The multiplicity of the intersection point is unkown or undefined:
_add_curve_to_right(e, c1, is_overlap);
_add_curve_to_right(e, c2, is_overlap);
if (! is_overlap) {
if (e->is_right_curve_bigger(c1, c2))
std::swap(c1, c2);
if (e->is_right_curve_bigger(c1, c2)) std::swap(c1, c2);
}
}
else {
@ -563,45 +636,49 @@ _create_intersection_point(const Point_2& xp,
e->add_curve_pair_to_right(c1, c2);
}
}
}
else // the event already exists, so we need to update it accordingly
{
CGAL_PRINT("Event already exists, updating.. (" << xp << std::endl);
}
else {
// The event already exists, so we need to update it accordingly
CGAL_SL_PRINT_TEXT("Event already exists, updating.. (");
CGAL_SL_PRINT(xp);
CGAL_SL_PRINT_TEXT(")");
CGAL_SL_PRINT_EOL();
if (e == this->m_currentEvent) {
// This can happen when c1 starts at the interior of c2 (or vice versa).
return;
}
e->add_curve_to_left(c1);
e->add_curve_to_left(c2);
e->add_curve_to_left(c2);
if (!c1->is_end_point(e) && !c2->is_end_point(e)) {
_add_curve_to_right(e, c1, is_overlap);
_add_curve_to_right(e, c2, is_overlap);
e->set_intersection();
this->m_visitor ->update_event(e, c1, c2, false);
this->m_visitor->update_event(e, c1, c2, false);
}
else {
if (!c1->is_end_point(e) && c2->is_end_point(e)) {
_add_curve_to_right(e, c1, is_overlap);
e->set_weak_intersection();
this->m_visitor ->update_event(e, c1);
this->m_visitor->update_event(e, c1);
}
else {
if (c1->is_end_point(e) && !c2->is_end_point(e)) {
_add_curve_to_right(e, c2, is_overlap);
e->set_weak_intersection();
this->m_visitor ->update_event(e, c2);
this->m_visitor->update_event(e, c2);
}
}
}
if (! is_overlap) {
if (e->is_right_curve_bigger(c1, c2))
std::swap(c1, c2);
if (e->is_right_curve_bigger(c1, c2)) std::swap(c1, c2);
}
CGAL_SL_PRINT_EVENT_INFO(e);
}
CGAL_SL_DEBUG(e->Print());
CGAL_SL_PRINT_END_EOL("Createing an intersection point");
}
//-----------------------------------------------------------------------------
@ -611,15 +688,16 @@ template <typename Tr, typename Vis, typename Subcv, typename Evnt,
typename Alloc>
void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_fix_overlap_subcurves()
{
CGAL_SL_PRINT_START_EOL("fixing overlap subcurves");
CGAL_assertion(this->m_currentEvent->has_left_curves());
Event_subcurve_iterator leftCurveIter =
this->m_currentEvent->left_curves_begin();
Event_subcurve_iterator iter = this->m_currentEvent->left_curves_begin();
//special treatment for Subcuves that store overlaps
while (leftCurveIter != this->m_currentEvent->left_curves_end()) {
Subcurve* leftCurve = *leftCurveIter;
while (iter != this->m_currentEvent->left_curves_end()) {
Subcurve* leftCurve = *iter;
// we check if the subcurve store overlap and current event is its
// right end point.
if ((Event*)leftCurve->right_event() == this->m_currentEvent) {
@ -630,42 +708,45 @@ void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_fix_overlap_subcurves()
_fix_finished_overlap_subcurve(orig_sc_1);
_fix_finished_overlap_subcurve(orig_sc_2);
}
}
++leftCurveIter;
}
++iter;
}
CGAL_SL_PRINT_END_EOL("Fixing overlap subcurves");
}
//-----------------------------------------------------------------------------
// Handle overlap at right insertion to event.
// event - the event where that overlap starts (the left
// end point of the overlap).
// curve - the subcurve that its insertion to the list of right subcurves of
// 'event' causes the overlap (with *iter).
// iter - the existing subcurve at the right subcurves of 'event'
// overlap_exist - a flag indicates if the overlap X_monotone_curve_2 was
// computed already (is true than its stored at sub_cv1 data member).
/*! Handle overlap at right insertion to event.
* \param event the event where that overlap starts (the left end point of the
* overlap).
* \param curve the subcurve that its insertion to the list of right subcurves of
* 'event' causes the overlap (with *iter).
* \param iter the existing subcurve at the right subcurves of 'event'
* \param overlap_exist a flag indicates if the overlap X_monotone_curve_2 was
* computed already (is true than its stored at sub_cv1 data member).
*/
template <typename Tr, typename Vis, typename Subcv, typename Evnt,
typename Alloc>
void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::
_handle_overlap(Event* event,
Subcurve* curve,
Event_subcurve_iterator iter,
_handle_overlap(Event* event, Subcurve* curve, Event_subcurve_iterator iter,
bool overlap_exist)
{
// An overlap occurs:
CGAL_PRINT("Overlap detected at right insertion...\n");
CGAL_SL_PRINT_START_EOL("handling overlap at right insertion");
X_monotone_curve_2 overlap_cv;
if (overlap_exist) overlap_cv = sub_cv1;
else {
// compute the overlap.
std::vector<Object> obj_vec;
std::vector<Object> obj_vec;
vector_inserter vit(obj_vec);
this->m_traits->intersect_2_object()(curve->last_curve(),
(*iter)->last_curve(),
vit);
if (obj_vec.empty()) return;
if (obj_vec.empty()) {
CGAL_SL_PRINT_END_EOL("handling overlap");
return;
}
overlap_cv = object_cast<X_monotone_curve_2>(obj_vec.front());
}
@ -704,7 +785,7 @@ _handle_overlap(Event* event,
this->m_traits->parameter_space_in_x_2_object()(overlap_cv, ARR_MIN_END);
Arr_parameter_space ps_y_l =
this->m_traits->parameter_space_in_y_2_object()(overlap_cv, ARR_MIN_END);
CGAL_assertion(ps_x_l != ARR_RIGHT_BOUNDARY);
if ((ps_x_l == ARR_INTERIOR) && (ps_y_l == ARR_INTERIOR)) {
// The left end of the overlapping subcurve is regular point, so in case
@ -717,7 +798,7 @@ _handle_overlap(Event* event,
// the event point.
const Point_2& begin_overlap =
this->m_traits->construct_min_vertex_2_object()(overlap_cv);
Comparison_result res =
Comparison_result res =
this->m_traits->compare_xy_2_object()(event->point(), begin_overlap);
CGAL_assertion(res != SMALLER);
@ -743,53 +824,67 @@ _handle_overlap(Event* event,
// Alocate a new Subcure for the overlap
Subcurve* overlap_sc = this->m_subCurveAlloc.allocate(1);
this->m_subCurveAlloc.construct(overlap_sc, this->m_masterSubcurve);
overlap_sc->set_hint(this->m_statusLine.end());
overlap_sc->init(overlap_cv);
overlap_sc->set_left_event(event);
overlap_sc->set_right_event(right_end);
m_overlap_subCurves.push_back(overlap_sc);
CGAL_PRINT(curve << " + " << *iter << " => " << overlap_sc << std::endl);
// Set the two events' attribute to overlap.
event -> set_overlap();
//right_end -> set_overlap();
event->set_overlap();
//right_end->set_overlap();
// sets the two originating subcurves of overlap_sc
overlap_sc->set_originating_subcurve1(*iter);
overlap_sc->set_originating_subcurve2(curve);
CGAL_SL_PRINT_CURVE(curve);
CGAL_SL_PRINT_TEXT(" + ");
CGAL_SL_PRINT_CURVE(*iter);
CGAL_SL_PRINT_TEXT(" => ");
CGAL_SL_PRINT_EOL();
CGAL_SL_PRINT_TEXT(" ");
CGAL_SL_PRINT_CURVE(overlap_sc);
CGAL_SL_PRINT_EOL();
// Remove curve, *iter from the left curves of end_overlap event
right_end->remove_curve_from_left(curve);
right_end->remove_curve_from_left(*iter);
// Add overlap_sc to the left curves
right_end->add_curve_to_left(overlap_sc);
// sets the two originating subcurves of overlap_sc
overlap_sc -> set_originating_subcurve1(*iter);
overlap_sc -> set_originating_subcurve2(curve);
// If one of the originating subcurves (or both), does not end
// at the right end of the overlap, add them to the right subcurves
// of the event associated with the right end of the overlap.
if ((Event*)curve->right_event() != right_end)
_add_curve_to_right(right_end, curve);
if ((Event*)(*iter)->right_event() != right_end)
_add_curve_to_right(right_end, (*iter));
this->m_visitor->found_overlap(curve, *iter, overlap_sc);
// Replace current sub-curve (*iter) with the new sub-curve
(*iter) = overlap_sc;
CGAL_SL_PRINT_END_EOL("handling overlap");
}
//-----------------------------------------------------------------------------
// Fix a subcurve that represents an overlap.
// sc - some originating subcurve of a aubcurve that stores an overlap
// notice thah this function is recursive since an originating subcurve of
// notice thah this function is recursive since an originating subcurve of
// an overlap can be itself a subcurve that stores overlap and so on.
template <typename Tr, typename Vis, typename Subcv, typename Evnt,
typename Alloc>
void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::
_fix_finished_overlap_subcurve(Subcurve* sc)
{
//
CGAL_SL_PRINT_START("fixing finished overlap subcurve ");
CGAL_SL_PRINT_CURVE(sc);
CGAL_SL_PRINT_EOL();
CGAL_assertion(sc != NULL);
// split 'sc' if necessary and update to event as weak intersection
@ -798,23 +893,29 @@ _fix_finished_overlap_subcurve(Subcurve* sc)
this->m_currentEvent->point(),
sub_cv1, sub_cv2);
sc->set_last_curve(sub_cv2);
this->m_currentEvent->set_weak_intersection();
this->m_visitor ->update_event(this->m_currentEvent,(Subcurve*)sc);
this->m_visitor->update_event(this->m_currentEvent,(Subcurve*)sc);
CGAL_SL_PRINT_END_EOL("Fixing finished overlap subcurve");
return;
}
if (!sc->originating_subcurve1())
if (!sc->originating_subcurve1()) {
// sc does not store an overlap, we are done
CGAL_SL_PRINT_END_EOL("fixing finished overlap subcurve");
return;
}
// sc is a subcurve that stores overlap, we have to continue with the
// sc is a subcurve that stores overlap, we have to continue with the
// recursion and deal with his two originating subcurves recursively.
Subcurve* orig_sc_1 = (Subcurve*)sc->originating_subcurve1();
Subcurve* orig_sc_2 = (Subcurve*)sc->originating_subcurve2();
_fix_finished_overlap_subcurve(orig_sc_1);
_fix_finished_overlap_subcurve(orig_sc_2);
CGAL_SL_PRINT_END_EOL("fixing finished overlap subcurve");
}
} //namespace CGAL

View File

@ -12,14 +12,10 @@
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Tali Zvi <talizvi@post.tau.ac.il>,
// Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s) : Tali Zvi <talizvi@post.tau.ac.il>,
// Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@gmail.com>
#ifndef CGAL_SWEEP_LINE_EVENT_H
#define CGAL_SWEEP_LINE_EVENT_H
@ -29,6 +25,7 @@
*/
#include <list>
#include <CGAL/Sweep_line_2/Sweep_line_subcurve.h>
namespace CGAL {
@ -71,6 +68,7 @@ public:
//struct SC_container { typedef std::list<SC> other; };
typedef std::list<Subcurve*> Subcurve_container;
typedef typename Subcurve_container::iterator Subcurve_iterator;
typedef typename Subcurve_container::const_iterator Subcurve_const_iterator;
typedef typename Subcurve_container::reverse_iterator
Subcurve_reverse_iterator;
@ -107,7 +105,7 @@ protected:
public:
/*! Default constructor. */
Sweep_line_event() :
m_type (0),
m_type(0),
m_ps_x(static_cast<char>(ARR_INTERIOR)),
m_ps_y(static_cast<char>(ARR_INTERIOR)),
m_closed(1)
@ -156,7 +154,7 @@ public:
// Replace the existing curve in case of overlap.
// EBEB 2011-10-27: Fixed to detect overlaps correctly
if (curve != *iter && curve->has_common_leaf(*iter)) {
if ((curve != *iter) && (curve->has_common_leaf(*iter))) {
//std::cout << "add_curve_to_left, curve overlaps" << std::endl;
*iter = curve;
return;
@ -232,7 +230,7 @@ public:
{
Subcurve_iterator iter;
for (iter = m_leftCurves.begin(); iter!= m_leftCurves.end(); ++iter) {
if (curve->has_common_leaf (*iter)) {
if (curve->has_common_leaf(*iter)) {
m_leftCurves.erase(iter);
return;
}
@ -253,25 +251,43 @@ public:
of the event. */
Subcurve_iterator right_curves_end() { return (m_rightCurves.end()); }
/*! Returns a const iterator to the first curve to the left of the event. */
Subcurve_const_iterator left_curves_begin() const
{ return m_leftCurves.begin(); }
/*! Returns a const iterator to the past the end curve to the left
of the event. */
Subcurve_const_iterator left_curves_end() const
{ return m_leftCurves.end(); }
/*! Returns a const iterator to the first curve to the right of the event. */
Subcurve_const_iterator right_curves_begin() const
{ return m_rightCurves.begin(); }
/*! Returns a const iterator to the past the end curve to the right
of the event. */
Subcurve_const_iterator right_curves_end() const
{ return m_rightCurves.end(); }
/*! Returns a reverse_iterator to the first curve of the reversed list
of the right curves of the event. */
Subcurve_reverse_iterator right_curves_rbegin()
{ return (m_rightCurves.rbegin()); }
{ return m_rightCurves.rbegin(); }
/*! Returns a reverse_iterator to the past-end curve of the reversed list
of the right curves of the event. */
Subcurve_reverse_iterator right_curves_rend()
{ return (m_rightCurves.rend()); }
{ return m_rightCurves.rend(); }
/*! Returns a reverse_iterator to the first curve of the reversed list
of the left curves of the event. */
Subcurve_reverse_iterator left_curves_rbegin()
{ return (m_leftCurves.rbegin()); }
{ return m_leftCurves.rbegin(); }
/*! Returns a reverse_iterator to the past-end curve of the reversed list
of the left curves of the event. */
Subcurve_reverse_iterator left_curves_rend()
{ return (m_leftCurves.rend()); }
{ return m_leftCurves.rend(); }
/*! Returns the number of curves defined to the left of the event. */
size_t number_of_left_curves() { return m_leftCurves.size(); }
@ -301,8 +317,8 @@ public:
*/
Point_2& point()
{
CGAL_precondition (is_closed());
return (m_point);
CGAL_precondition(is_closed());
return m_point;
}
/*!
@ -377,13 +393,12 @@ public:
/*! Replace the set of left subcurves. */
template <typename InputIterator>
void replace_left_curves (InputIterator begin, InputIterator end)
void replace_left_curves(InputIterator begin, InputIterator end)
{
Subcurve_iterator left_iter = m_leftCurves.begin();
InputIterator iter;
for (iter = begin; iter != end; ++iter, ++left_iter)
for (InputIterator iter = begin; iter != end; ++iter, ++left_iter)
*left_iter = static_cast<Subcurve*>(*iter);
m_leftCurves.erase (left_iter, m_leftCurves.end());
m_leftCurves.erase(left_iter, m_leftCurves.end());
}
bool is_right_curve_bigger(Subcurve* c1, Subcurve* c2)

View File

@ -12,13 +12,10 @@
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Tali Zvi <talizvi@post.tau.ac.il>,
// Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Author(s) : Tali Zvi <talizvi@post.tau.ac.il>,
// Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_SWEEP_LINE_SUBCURVE_H
#define CGAL_SWEEP_LINE_SUBCURVE_H
@ -48,34 +45,31 @@ namespace CGAL {
* - an iterator that points to the location of the subcurve at the status line.
* - two pointers to subcurves that are the originating subcurves in case of
* an overlap, otherwise thay are both NULL.
*
*/
template <typename Traits_>
class Sweep_line_subcurve {
public:
typedef Traits_ Traits_2;
typedef typename Traits_2::Point_2 Point_2;
typedef typename Traits_2::X_monotone_curve_2 X_monotone_curve_2;
typedef Traits_ Traits_2;
typedef typename Traits_2::Point_2 Point_2;
typedef typename Traits_2::X_monotone_curve_2 X_monotone_curve_2;
typedef Sweep_line_subcurve<Traits_2> Self;
typedef Curve_comparer<Traits_2, Self> Compare_curves;
typedef Multiset<Self*, Compare_curves, CGAL_ALLOCATOR(int)>
Status_line;
typedef typename Status_line::iterator Status_line_iterator;
typedef Sweep_line_subcurve<Traits_2> Self;
typedef Curve_comparer<Traits_2, Self> Compare_curves;
typedef Multiset<Self*,
Compare_curves,
CGAL_ALLOCATOR(int)> Status_line;
typedef typename Status_line::iterator Status_line_iterator;
typedef Sweep_line_event<Traits_2, Self> Event;
typedef Sweep_line_event<Traits_2, Self> Event;
protected:
// Data members:
X_monotone_curve_2 m_lastCurve; // The portion of the curve that lies to
// the right of the last event point
// the right of the last event point
// that occured on the curve.
Event* m_left_event; // The event associated with the left end.
Event* m_right_event; // The event associated with the right end
Status_line_iterator m_hint; // The location of the subcurve in the
// status line (the Y-structure).
@ -84,13 +78,15 @@ protected:
public:
/*! Default constructor. */
/*! Construct default.
*/
Sweep_line_subcurve() :
m_orig_subcurve1(NULL),
m_orig_subcurve2(NULL)
{}
/*! Constructor given a curve. */
/*! Construct from a curve.
*/
Sweep_line_subcurve(const X_monotone_curve_2& curve) :
m_lastCurve(curve),
m_orig_subcurve1(NULL),
@ -112,11 +108,11 @@ public:
/*! Set the last intersecing curve so far. */
void set_last_curve(const X_monotone_curve_2& cv) { m_lastCurve = cv; }
/*! Check if the given event is the matches the right-end event. */
/*! Check if the given event is the matches the right-end event. */
template <typename SweepEvent>
bool is_end_point(const SweepEvent* event) const
{ return (m_right_event == (Event*)event); }
/*! Get the event that corresponds to the left end of the subcurve. */
Event* left_event() const { return m_left_event; }
@ -154,8 +150,7 @@ public:
OutputIterator all_leaves(OutputIterator oi)
{
if (m_orig_subcurve1 == NULL) {
*oi = this;
++oi;
*oi++ = this;
return oi;
}
@ -177,20 +172,19 @@ public:
bool is_leaf(Self* s)
{
if (m_orig_subcurve1 == NULL) return (this == s);
return (m_orig_subcurve1->is_leaf(s) ||
m_orig_subcurve2->is_leaf(s));
return (m_orig_subcurve1->is_leaf(s) || m_orig_subcurve2->is_leaf(s));
}
/*! Check if the two hierarchies contain the same leaf nodes. */
bool has_same_leaves(Self *s)
bool has_same_leaves(Self* s)
{
std::list<Self*> my_leaves;
std::list<Self*> other_leaves;
this->all_leaves (std::back_inserter(my_leaves));
s->all_leaves (std::back_inserter(other_leaves));
typename std::list<Self*>::iterator iter;
this->all_leaves(std::back_inserter(my_leaves));
s->all_leaves(std::back_inserter(other_leaves));
typename std::list<Self*>::iterator iter;
for (iter = my_leaves.begin(); iter != my_leaves.end(); ++iter) {
if (std::find(other_leaves.begin(), other_leaves.end(), *iter) ==
other_leaves.end())
@ -211,7 +205,7 @@ public:
{
std::list<Self*> my_leaves;
std::list<Self*> other_leaves;
this->all_leaves(std::back_inserter(my_leaves));
s->all_leaves(std::back_inserter(other_leaves));
@ -225,32 +219,19 @@ public:
}
/*! Get all distinct nodes from the two hierarchies. */
template <class OutputIterator>
template <typename OutputIterator>
OutputIterator distinct_nodes(Self* s, OutputIterator oi)
{
if (m_orig_subcurve1 == NULL) {
if (s->is_leaf(this)) {
*oi = this;
++oi;
}
if (s->is_leaf(this)) *oi++ = this;
return oi;
}
if (! s->is_inner_node (m_orig_subcurve1)) {
*oi = m_orig_subcurve1;
++oi;
}
else {
oi = m_orig_subcurve1->distinct_nodes(s, oi);
}
if (! s->is_inner_node (m_orig_subcurve1)) *oi++ = m_orig_subcurve1;
else oi++ = m_orig_subcurve1->distinct_nodes(s, oi);
if (! s->is_inner_node (m_orig_subcurve2)) {
*oi = m_orig_subcurve2;
++oi;
}
else {
oi = m_orig_subcurve2->distinct_nodes(s, oi);
}
if (! s->is_inner_node (m_orig_subcurve2)) *oi++ = m_orig_subcurve2;
else oi++ = m_orig_subcurve2->distinct_nodes(s, oi);
return oi;
}
@ -265,7 +246,7 @@ public:
if (depth1 > depth2) return (depth1 + 1);
else return (depth2 + 1);
}
#ifdef CGAL_SL_VERBOSE
void Print() const;
#endif
@ -275,11 +256,10 @@ public:
template<class Traits>
void Sweep_line_subcurve<Traits>::Print() const
{
std::cout << "Curve " << this
<< " (" << m_lastCurve << ") "
std::cout << "Curve " << this
<< " (" << m_lastCurve << ") "
<< " [sc1: " << m_orig_subcurve1
<< ", sc2: " << m_orig_subcurve2 << "]"
<< std::endl;
<< ", sc2: " << m_orig_subcurve2 << "]";
}
#endif