Implemented linear traits tab.

* Supports basic operations on unbounded arrangement with linear curves.
* Also fixed a bug in conic point-curve distance computation.
This commit is contained in:
Alex Tsui 2012-07-21 23:24:33 +00:00
parent aaa591be04
commit 765232f21f
19 changed files with 1121 additions and 74 deletions

View File

@ -62,10 +62,11 @@ public:
typedef ArrangementDemoTabBase Superclass;
typedef Arr_ Arrangement;
ArrangementDemoTab( Arrangement* arrangement_, QWidget* parent ):
ArrangementDemoTab( Arrangement* arrangement_, QWidget* parent = 0 ):
Superclass( parent ),
arrangement( arrangement_ )
{
std::cout << this->scene->views( ).size( ) << std::endl;
// set up demo components
this->arrangementGraphicsItem = new CGAL::Qt::ArrangementGraphicsItem< Arrangement >( this->arrangement );
this->curveInputCallback = new ArrangementCurveInputCallback< Arrangement >( this->arrangement, this );

View File

@ -15,7 +15,6 @@
#include <CGAL/IO/Arr_text_formatter.h>
#include <CGAL/IO/Arr_with_history_text_formatter.h>
ArrangementDemoWindow::
ArrangementDemoWindow(QWidget* parent) :
CGAL::Qt::DemosMainWindow( parent ),
@ -57,6 +56,7 @@ makeTab( TraitsType tt )
Seg_arr* seg_arr;
Pol_arr* pol_arr;
Conic_arr* conic_arr;
Lin_arr* lin_arr;
CGAL::Object arr;
switch ( tt )
@ -80,6 +80,12 @@ makeTab( TraitsType tt )
arr = CGAL::make_object( conic_arr );
tabLabel = QString( "%1 - Conic" ).arg( tabLabelCounter++ );
break;
case LINEAR_TRAITS:
lin_arr = new Lin_arr;
demoTab = new ArrangementDemoTab< Lin_arr >( lin_arr, 0 );
arr = CGAL::make_object( lin_arr );
tabLabel = QString( "%1 - Linear" ).arg( tabLabelCounter++ );
break;
}
this->arrangements.push_back( arr );
@ -177,6 +183,8 @@ setupUi( )
this->conicTypeGroup->addAction( this->ui->actionConicEllipse );
this->conicTypeGroup->addAction( this->ui->actionConicThreePoint );
this->conicTypeGroup->addAction( this->ui->actionConicFivePoint );
this->conicTypeGroup->addAction( this->ui->actionCurveRay );
this->conicTypeGroup->addAction( this->ui->actionCurveLine );
}
void
@ -394,7 +402,9 @@ updateConicType( QAction* newType )
QGraphicsScene* activeScene = activeTab->getScene( );
ArrangementDemoGraphicsView* activeView = activeTab->getView( );
Conic_arr* conic_arr;
Lin_arr* lin_arr;
bool isConicArr = CGAL::assign( conic_arr, this->arrangements[ this->ui->tabWidget->currentIndex( ) ] );
bool isLinearArr = CGAL::assign( lin_arr, this->arrangements[ this->ui->tabWidget->currentIndex( ) ] );
if ( isConicArr )
{
std::cout << "do something conic arr related" << std::endl;
@ -421,8 +431,22 @@ updateConicType( QAction* newType )
curveInputCallback->setConicType( ConicCurveInputCallback::CONIC_FIVE_POINT );
}
}
else
else if ( isLinearArr )
{
typedef CGAL::Qt::GraphicsViewCurveInput< typename Lin_arr::Geometry_traits_2 > LinearCurveInputCallback;
LinearCurveInputCallback* curveInputCallback = ( LinearCurveInputCallback* ) activeTab->getCurveInputCallback( );
if ( newType == this->ui->actionConicSegment )
{
curveInputCallback->setCurveType( LinearCurveInputCallback::SEGMENT );
}
else if ( newType == this->ui->actionCurveRay )
{
curveInputCallback->setCurveType( LinearCurveInputCallback::RAY );
}
else if ( newType == this->ui->actionCurveLine )
{
curveInputCallback->setCurveType( LinearCurveInputCallback::LINE );
}
//std::cout << "do nothing" << std::endl;
}
}
@ -614,6 +638,10 @@ on_actionNewTab_triggered( )
{
this->makeTab( CONIC_TRAITS );
}
else if ( id == LINEAR_TRAITS )
{
this->makeTab( LINEAR_TRAITS );
}
else
{
std::cout << "Sorry, this trait is not yet supported" << std::endl;
@ -637,16 +665,52 @@ on_tabWidget_currentChanged( )
CGAL::Object arr;
if ( this->ui->tabWidget->currentIndex( ) != -1 )
arr = this->arrangements[ this->ui->tabWidget->currentIndex( ) ];
Seg_arr* seg;
Pol_arr* pol;
Conic_arr* conic;
Lin_arr* lin;
if ( CGAL::assign( conic, arr ) )
{
this->ui->actionConicSegment->setChecked( true );
this->ui->actionCurveRay->setVisible( false );
this->ui->actionCurveLine->setVisible( false );
this->ui->actionConicCircle->setVisible( true );
this->ui->actionConicEllipse->setVisible( true );
this->ui->actionConicThreePoint->setVisible( true );
this->ui->actionConicFivePoint->setVisible( true );
this->conicTypeGroup->setEnabled( true );
}
else if ( CGAL::assign( lin, arr ) )
{
this->ui->actionConicSegment->setChecked( true );
this->ui->actionCurveRay->setVisible( true );
this->ui->actionCurveLine->setVisible( true );
this->ui->actionConicCircle->setVisible( false );
this->ui->actionConicEllipse->setVisible( false );
this->ui->actionConicThreePoint->setVisible( false );
this->ui->actionConicFivePoint->setVisible( false );
this->conicTypeGroup->setEnabled( true );
}
else
{
this->conicTypeGroup->setEnabled( false );
{ // segment or polyline
this->ui->actionConicSegment->setChecked( true );
this->ui->actionCurveRay->setVisible( false );
this->ui->actionCurveLine->setVisible( false );
this->ui->actionConicCircle->setVisible( false );
this->ui->actionConicEllipse->setVisible( false );
this->ui->actionConicThreePoint->setVisible( false );
this->ui->actionConicFivePoint->setVisible( false );
this->conicTypeGroup->setEnabled( true );
}
}

View File

@ -43,7 +43,8 @@ public:
typedef enum TraitsType {
SEGMENT_TRAITS,
POLYLINE_TRAITS,
CONIC_TRAITS
CONIC_TRAITS,
LINEAR_TRAITS
} TraitsType;
ArrangementDemoWindow(QWidget* parent = 0);

View File

@ -1,5 +1,6 @@
<RCC>
<qresource>
<file>icons/demo_conic_line.xpm</file>
<file>icons/demo_zoomin.xpm</file>
<file>icons/demo_zoomout.xpm</file>
<file>icons/yellow_icon.xpm</file>
@ -11,6 +12,7 @@
<file>icons/demo_conic_segment.xpm</file>
<file>icons/demo_conic_3points.xpm</file>
<file>icons/demo_snapvertex.xpm</file>
<file>icons/demo_conic_ray.xpm</file>
<file>icons/lower_env_xpm.xpm</file>
<file>icons/upper_env_xpm.xpm</file>
<file>icons/demo_snapgrid.xpm</file>

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<width>829</width>
<height>600</height>
</rect>
</property>
@ -29,7 +29,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<width>829</width>
<height>25</height>
</rect>
</property>
@ -127,6 +127,8 @@
<addaction name="actionUpperEnvelope"/>
<addaction name="separator"/>
<addaction name="actionConicSegment"/>
<addaction name="actionCurveRay"/>
<addaction name="actionCurveLine"/>
<addaction name="actionConicCircle"/>
<addaction name="actionConicEllipse"/>
<addaction name="actionConicThreePoint"/>
@ -437,6 +439,30 @@
<string>Zoom Out</string>
</property>
</action>
<action name="actionCurveRay">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="ArrangementDemoWindow.qrc">
<normaloff>:/icons/demo_conic_ray.xpm</normaloff>:/icons/demo_conic_ray.xpm</iconset>
</property>
<property name="text">
<string>Ray</string>
</property>
</action>
<action name="actionCurveLine">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="ArrangementDemoWindow.qrc">
<normaloff>:/icons/demo_conic_line.xpm</normaloff>:/icons/demo_conic_line.xpm</iconset>
</property>
<property name="text">
<string>Line</string>
</property>
</action>
</widget>
<resources>
<include location="ArrangementDemoWindow.qrc"/>

View File

@ -83,5 +83,23 @@ setScene( QGraphicsScene* scene_ )
this->scene = scene_;
}
QRectF
ArrangementGraphicsItemBase::
getViewportRect( ) const
{
QRectF clipRect;
if ( this->scene == NULL || this->scene->views( ).size( ) == 0 )
{
return clipRect;
}
QGraphicsView* view = this->scene->views( ).first( );
QPointF p1 = view->mapToScene( 0, 0 );
QPointF p2 = view->mapToScene( view->width( ), view->height( ) );
clipRect = QRectF( p1, p2 );
return clipRect;
}
} // namespace Qt
} // namespace CGAL

View File

@ -51,6 +51,8 @@ public:
void setScene( QGraphicsScene* scene_ );
protected:
QRectF getViewportRect( ) const;
CGAL::Bbox_2 bb;
bool bb_initialized;
@ -63,7 +65,7 @@ protected:
}; // class ArrangementGraphicsItemBase
template < class Arr_ >
template < class Arr_, class ArrTraits = typename Arr_::Geometry_traits_2 >
class ArrangementGraphicsItem : public ArrangementGraphicsItemBase
{
typedef Arr_ Arrangement;
@ -78,10 +80,9 @@ class ArrangementGraphicsItem : public ArrangementGraphicsItemBase
public:
ArrangementGraphicsItem( Arrangement* t_ );
void modelChanged( );
public:
// QGraphicsItem overrides
void modelChanged( );
QRectF boundingRect( ) const;
virtual void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget );
@ -95,8 +96,8 @@ protected:
std::map< Curve_iterator, CGAL::Bbox_2 > curveBboxMap;
}; // class ArrangementGraphicsItem
template < class Arr_ >
ArrangementGraphicsItem< Arr_ >::
template < class Arr_, class ArrTraits >
ArrangementGraphicsItem< Arr_, ArrTraits >::
ArrangementGraphicsItem( Arrangement* arr_ ):
arr( arr_ ),
painterostream( 0 )
@ -108,32 +109,22 @@ ArrangementGraphicsItem( Arrangement* arr_ ):
this->setZValue( 3 );
}
template < class Arr_ >
template < class Arr_, class ArrTraits >
QRectF
ArrangementGraphicsItem< Arr_ >::
ArrangementGraphicsItem< Arr_, ArrTraits >::
boundingRect( ) const
{
QRectF rect = this->convert( this->bb );
return rect;
}
template < class Arr_ >
template < class Arr_, class ArrTraits >
void
ArrangementGraphicsItem< Arr_ >::paint(QPainter *painter,
ArrangementGraphicsItem< Arr_, ArrTraits >::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget * /*widget*/)
{
//painter->setClipping( true );
//painter->drawRect( this->boundingRect( ) );
#if 0
QTransform transform = painter->worldTransform( );
if ( transform.isScaling( ) )
{
std::cout << "Cool, we're scaling." << std::endl;
std::cout << transform.m11( ) << std::endl;
}
#endif
painter->setPen( this->verticesPen );
this->painterostream = ArrangementPainterOstream< Traits >( painter, this->boundingRect( ) );
this->painterostream.setScene( this->scene );
@ -146,12 +137,6 @@ ArrangementGraphicsItem< Arr_ >::paint(QPainter *painter,
painter->setPen( this->edgesPen );
for ( Edge_iterator it = this->arr->edges_begin( ); it != this->arr->edges_end( ); ++it )
{
#if 0
Point_2 p1 = it->source( )->point( );
Point_2 p2 = it->target( )->point( );
Segment_2 edge( p1, p2 );
this->painterostream << edge;
#endif
X_monotone_curve_2 curve = it->curve( );
this->painterostream << curve;
}
@ -159,9 +144,9 @@ ArrangementGraphicsItem< Arr_ >::paint(QPainter *painter,
// We let the bounding box only grow, so that when vertices get removed
// the maximal bbox gets refreshed in the GraphicsView
template < class Arr_ >
template < class Arr_, class ArrTraits >
void
ArrangementGraphicsItem< Arr_ >::updateBoundingBox( )
ArrangementGraphicsItem< Arr_, ArrTraits >::updateBoundingBox( )
{
this->prepareGeometryChange( );
if ( this->arr->number_of_vertices( ) == 0 )
@ -188,9 +173,9 @@ ArrangementGraphicsItem< Arr_ >::updateBoundingBox( )
}
}
template < class Arr_ >
template < class Arr_, class ArrTraits >
void
ArrangementGraphicsItem< Arr_ >::modelChanged( )
ArrangementGraphicsItem< Arr_, ArrTraits >::modelChanged( )
{
if ( this->arr->is_empty( ) )
{
@ -204,6 +189,129 @@ ArrangementGraphicsItem< Arr_ >::modelChanged( )
this->update( );
}
/**
* Why is this not being used?
Specialized methods:
updateBoundingBox
*/
template < class Arr_, class Kernel_ >
class ArrangementGraphicsItem< Arr_, CGAL::Arr_linear_traits_2< Kernel_ > > : public ArrangementGraphicsItemBase
{
typedef Arr_ Arrangement;
typedef ArrangementGraphicsItemBase Superclass;
typedef typename Arrangement::Geometry_traits_2 Traits;
typedef typename Arrangement::Vertex_iterator Vertex_iterator;
typedef typename Arrangement::Curve_iterator Curve_iterator;
typedef typename Arrangement::Edge_iterator Edge_iterator;
typedef typename ArrTraitsAdaptor< Traits >::Kernel Kernel;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Segment_2 Segment_2;
public:
ArrangementGraphicsItem( Arrangement* arr_ ):
arr( arr_ ),
painterostream( 0 )
{
if ( this->arr->number_of_vertices( ) == 0 ) {
this->hide( );
}
this->updateBoundingBox( );
this->setZValue( 3 );
}
void modelChanged( )
{
if ( this->arr->is_empty( ) )
{
this->hide( );
}
else
{
this->show( );
}
this->updateBoundingBox( );
this->update( );
}
public: // methods
// @override QGraphicsItem::boundingRect
QRectF boundingRect( ) const
{
QRectF rect = this->convert( this->bb );
return rect;
}
// @override QGraphicsItem::paint
virtual void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
{
this->updateBoundingBox( );
painter->setPen( this->verticesPen );
this->painterostream = ArrangementPainterOstream< Traits >( painter, this->boundingRect( ) );
this->painterostream.setScene( this->scene );
for ( Vertex_iterator it = this->arr->vertices_begin( ); it != this->arr->vertices_end( ); ++it )
{
Point_2 pt = it->point( );
this->painterostream << pt;
}
painter->setPen( this->edgesPen );
for ( Edge_iterator it = this->arr->edges_begin( ); it != this->arr->edges_end( ); ++it )
{
X_monotone_curve_2 curve = it->curve( );
this->painterostream << curve;
}
}
protected: // methods
void updateBoundingBox( )
{
this->prepareGeometryChange( );
QRectF clipRect = this->getViewportRect( );
this->convert = Converter<Kernel>( clipRect );
if ( ! clipRect.isValid( ) /*|| this->arr->number_of_vertices( ) == 0*/ )
{
this->bb = Bbox_2( 0, 0, 0, 0 );
this->bb_initialized = false;
return;
}
else
{
this->bb = this->convert( clipRect ).bbox( );
this->bb_initialized = true;
}
for ( Curve_iterator it = this->arr->curves_begin( );
it != this->arr->curves_end( );
++it )
{
if ( it->is_segment( ) )
{
this->bb = this->bb + it->segment( ).bbox( );
}
else if ( it->is_ray( ) )
{
QLineF qclippedRay = this->convert( it->ray( ) );
Segment_2 clippedRay = this->convert( qclippedRay );
this->bb = this->bb + clippedRay.bbox( );
}
else // ( it->is_line( ) )
{
QLineF qclippedLine = this->convert( it->line( ) );
Segment_2 clippedLine = this->convert( qclippedLine );
this->bb = this->bb + clippedLine.bbox( );
}
}
}
protected: // fields
Arrangement* arr;
ArrangementPainterOstream< Traits > painterostream;
CGAL::Qt::Converter< Kernel > convert;
}; // class ArrangementGraphicsItem
} // namespace Qt
} // namespace CGAL

View File

@ -8,6 +8,7 @@
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arr_polyline_traits_2.h>
#include <CGAL/Arr_conic_traits_2.h>
#include <CGAL/Arr_linear_traits_2.h>
#include "Utils.h"
#include <vector>
@ -74,18 +75,6 @@ protected: // methods
QPointF p1 = view->mapToScene( 0, 0 );
QPointF p2 = view->mapToScene( view->width( ), view->height( ) );
QRectF clipRect = QRectF( p1, p2 );
#if 0
std::cout << "("
<< p1.x( )
<< " "
<< p1.y( )
<< " "
<< p2.x( )
<< " "
<< p2.y( )
<< ")"
<< std::endl;
#endif
return clipRect;
}
@ -608,6 +597,101 @@ protected: // members
Construct_x_monotone_curve_2 construct_x_monotone_curve_2;
};
template < class Kernel_ >
class ArrangementPainterOstream< CGAL::Arr_linear_traits_2< Kernel_ > >:
public ArrangementPainterOstreamBase< CGAL::Arr_linear_traits_2< Kernel_ > >
{
public: // typedefs
typedef Kernel_ Kernel;
typedef CGAL::Arr_linear_traits_2< Kernel > Traits;
typedef ArrangementPainterOstreamBase< Traits > Superclass;
typedef typename Superclass::Point_2 Point_2;
typedef typename Superclass::Segment_2 Segment_2;
typedef typename Superclass::Ray_2 Ray_2;
typedef typename Superclass::Line_2 Line_2;
typedef typename Superclass::Triangle_2 Triangle_2;
typedef typename Superclass::Iso_rectangle_2 Iso_rectangle_2;
typedef typename Superclass::Circle_2 Circle_2;
typedef typename Traits::Curve_2 Curve_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
public: // constructors
ArrangementPainterOstream( QPainter* p, QRectF clippingRectangle = QRectF( ) ):
Superclass( p, clippingRectangle )
{ }
public: // methods
ArrangementPainterOstream& operator<<( const X_monotone_curve_2& curve )
{
if ( curve.is_segment( ) )
{
Segment_2 seg = curve.segment( );
// skip segments outside our view
QRectF seg_bb = this->convert( seg.bbox( ) );
if ( this->clippingRect.isValid( ) &&
! this->clippingRect.intersects( seg_bb ) )
{
return *this;
}
this->painterOstream << seg;
}
else if ( curve.is_ray( ) )
{
Ray_2 ray = curve.ray( );
QLineF qseg = this->convert( ray );
if ( qseg.isNull( ) )
{ // it's out of view
return *this;
}
Segment_2 seg = this->convert( qseg );
this-> painterOstream << seg;
}
else // curve.is_line( )
{
Line_2 line = curve.line( );
QLineF qseg = this->convert( line );
if ( qseg.isNull( ) )
{ // it's out of view
return *this;
}
Segment_2 seg = this->convert( qseg );
this-> painterOstream << seg;
}
return *this;
}
ArrangementPainterOstream& operator<<( const Point_2& p )
{
QPointF qpt = this->convert( p );
// clip the point if possible
if ( this->clippingRect.isValid( ) &&
! this->clippingRect.contains( qpt ) )
{
return *this;
}
QPen savePen = this->qp->pen( );
this->qp->setBrush( QBrush( savePen.color( ) ) );
double radius = savePen.width( ) / 2.0;
radius /= this->scale;
this->qp->drawEllipse( qpt, radius, radius );
this->qp->setBrush( QBrush( ) );
this->qp->setPen( savePen );
return *this;
}
template < class T >
ArrangementPainterOstream& operator<<( const T& p )
{
(*(static_cast< Superclass* >(this)) << p);
return *this;
}
};
} // namespace Qt
} // namespace CGAL
#endif // CGAL_QT_ARRANGEMENT_PAINTER_OSTREAM_H

View File

@ -33,6 +33,7 @@
#include <CGAL/Cartesian.h>
#include <CGAL/Arr_default_dcel.h>
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arr_linear_traits_2.h>
#include <CGAL/Arr_consolidated_curve_data_traits_2.h>
#include <CGAL/Arr_polyline_traits_2.h>
#include <CGAL/Arrangement_with_history_2.h>
@ -238,6 +239,35 @@ typedef CGAL::Arr_landmarks_point_location<Conic_arr>
#endif
// Linear:
typedef CGAL::Arr_linear_traits_2<Kernel> Lin_traits;
typedef Lin_traits::Curve_2 Arr_lin_2;
typedef Lin_traits::X_monotone_curve_2 Arr_xlin_2;
typedef Lin_traits::Point_2 Arr_lin_point_2;
typedef Dcel<Lin_traits> Lin_dcel;
typedef CGAL::Arrangement_with_history_2<Lin_traits,
Lin_dcel> Lin_arr;
typedef Lin_arr::Halfedge Lin_halfedge;
typedef Lin_arr::Halfedge_handle Lin_halfedge_handle;
typedef Lin_arr::Face_handle Lin_face_handle;
typedef Lin_arr::Ccb_halfedge_circulator Lin_ccb_halfedge_circulator;
typedef Lin_arr::Hole_iterator Lin_holes_iterator;
typedef Lin_arr::Face_iterator Lin_face_iterator;
typedef std::list<Arr_lin_2*> Arr_lin_list;
typedef Arr_lin_list::const_iterator Arr_lin_const_iter;
typedef Arr_lin_list::iterator Arr_lin_iter;
//point location
typedef CGAL::Arr_trapezoid_ric_point_location<Lin_arr>
Lin_trap_point_location;
typedef CGAL::Arr_simple_point_location<Lin_arr>
Lin_simple_point_location;
typedef CGAL::Arr_walk_along_line_point_location<Lin_arr>
Lin_walk_point_location;
typedef CGAL::Arr_landmarks_point_location<Lin_arr>
Lin_landmarks_point_location;
template <class Arrangement_>

View File

@ -3,6 +3,8 @@
#include "ArrangementPainterOstream.h"
#include <CGAL/Qt/Converter.h>
#include <CGAL/Qt/GraphicsItem.h>
#include <QGraphicsScene>
namespace CGAL {
namespace Qt {
@ -16,23 +18,30 @@ public:
typedef typename Traits::Curve_2 Curve_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
public: // ctors
CurveGraphicsItem( );
public: // methods
virtual void paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget );
void updateBoundingBox( );
virtual QRectF boundingRect( ) const;
void insert( const X_monotone_curve_2& curve );
void clear( );
QRectF boundingRect( ) const;
void setScene( QGraphicsScene* scene_ );
public slots:
void modelChanged( );
protected:
protected: // methods
void updateBoundingBox( );
QRectF viewportRect( ) const;
protected: // fields
CGAL::Qt::Converter< Kernel > convert;
ArrangementPainterOstream< ArrTraits > painterOstream;
ArrangementPainterOstream< Traits > painterOstream;
std::vector< X_monotone_curve_2 > curves;
CGAL::Bbox_2 boundingBox;
bool boundingBoxInitialized;
QGraphicsScene* scene;
}; // class CurveGraphicsItem
template < class ArrTraits >
@ -40,7 +49,8 @@ CurveGraphicsItem< ArrTraits >::
CurveGraphicsItem( ):
painterOstream( 0 ),
boundingBox( 0, 0, 0, 0 ),
boundingBoxInitialized( false )
boundingBoxInitialized( false ),
scene( 0 )
{
this->setZValue( 4 );
}
@ -51,7 +61,8 @@ CurveGraphicsItem< ArrTraits >::
paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget )
{
painter->setPen( QPen( ::Qt::red, 0. ) );
this->painterOstream = ArrangementPainterOstream< ArrTraits >( painter/*, clippingRectangle */ );
QRectF clippingRectangle = this->viewportRect( );
this->painterOstream = ArrangementPainterOstream< Traits >( painter, clippingRectangle );
for ( int i = 0; i < this->curves.size( ); ++i )
{
X_monotone_curve_2 curve = this->curves[ i ];
@ -59,6 +70,15 @@ paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widge
}
}
template < class ArrTraits >
QRectF
CurveGraphicsItem< ArrTraits >::
boundingRect( ) const
{
QRectF boundingRectangle = this->convert( this->boundingBox );
return boundingRectangle;
}
template < class ArrTraits >
void
CurveGraphicsItem< ArrTraits >::
@ -116,15 +136,214 @@ clear( )
this->curves.clear( );
}
template < class ArrTraits >
QRectF
void
CurveGraphicsItem< ArrTraits >::
boundingRect( ) const
setScene( QGraphicsScene* scene_ )
{
QRectF boundingRectangle = this->convert( this->boundingBox );
return boundingRectangle;
this->scene = scene_;
}
template < class ArrTraits >
QRectF
CurveGraphicsItem< ArrTraits >::
viewportRect( ) const
{
QRectF res;
if ( ! this->scene )
return res;
if ( this->scene->views( ).size( ) == 0 )
return res;
QGraphicsView* view = this->scene->views( ).first( );
QPointF p1 = view->mapToScene( 0, 0 );
QPointF p2 = view->mapToScene( view->width( ), view->height( ) );
res = QRectF( p1, p2 );
return res;
}
/**
Specialization of the base template CurveGraphicsItem:
updateBoundingBox
*/
template < class Kernel_ >
class CurveGraphicsItem< CGAL::Arr_linear_traits_2< Kernel_ > > : public GraphicsItem
{
public: // typedefs
// known curve types
typedef CGAL::Arr_linear_traits_2< Kernel_ > Traits;
typedef Kernel_ Kernel;
typedef typename Traits::Curve_2 Curve_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Kernel::Segment_2 Segment_2;
typedef typename Kernel::Line_2 Line_2;
typedef typename Kernel::Ray_2 Ray_2;
public: // ctors
CurveGraphicsItem( ):
painterOstream( 0 ),
boundingBox( 0, 0, 0, 0 ),
boundingBoxInitialized( false ),
scene( 0 )
{
this->setZValue( 4 );
}
public: // methods
virtual void paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget )
{
QRectF clippingRectangle = this->viewportRect( );
painter->setPen( QPen( ::Qt::red, 0. ) );
this->painterOstream = ArrangementPainterOstream< Traits >( painter, clippingRectangle );
for ( int i = 0; i < this->curves.size( ); ++i )
{
X_monotone_curve_2 curve = this->curves[ i ];
this->painterOstream << curve;
}
}
void insert( const X_monotone_curve_2& curve )
{
this->curves.push_back( curve );
}
void clear( )
{
this->curves.clear( );
}
QRectF boundingRect( ) const
{
QRectF res;
if ( ! this->scene )
{
return res;
}
}
void setScene( QGraphicsScene* scene_ )
{
this->scene = scene_;
if ( this->scene )
{
QRectF clipRect = this->viewportRect( );
this->convert = CGAL::Qt::Converter< Kernel >( clipRect );
}
}
public slots:
void modelChanged( )
{
if ( this->curves.size( ) == 0 )
{
this->hide( );
}
else
{
this->show( );
}
this->updateBoundingBox( );
this->update( );
}
protected: // methods
void updateBoundingBox( )
{
this->boundingBoxInitialized = 0;
this->boundingBox = CGAL::Bbox_2( 0, 0, 0, 0 );
QRectF clipRect = this->viewportRect( );
if ( !clipRect.isValid( ) )
{
return;
}
this->convert = CGAL::Qt::Converter< Kernel >( clipRect );
bool first = 1;
for ( int i = 0; i < curves.size( ); ++i )
{
X_monotone_curve_2 curve = curves[ i ];
if ( curve.is_segment( ) )
{
Segment_2 seg = curve.segment( );
CGAL::Bbox_2 seg_bbox = seg.bbox( );
if ( first )
{
first = 0;
this->boundingBoxInitialized = 1;
this->boundingBox = seg_bbox;
}
else
{
this->boundingBox = this->boundingBox + seg_bbox;
}
}
else if ( curve.is_ray( ) )
{
Ray_2 ray = curve.ray( );
QLineF qclippedRay = this->convert( ray );
if ( qclippedRay.isNull( ) )
continue;
Segment_2 clippedRay = this->convert( qclippedRay );
if ( first )
{
first = 0;
this->boundingBoxInitialized = 1;
this->boundingBox = clippedRay.bbox( );
}
else
{
this->boundingBox = this->boundingBox + clippedRay.bbox( );
}
}
else // curve.is_line( )
{
Line_2 line = curve.line( );
QLineF qclippedLine = this->convert( line );
if ( qclippedLine.isNull( ) )
continue;
Segment_2 clippedLine = this->convert( qclippedLine );
if ( first )
{
first = 0;
this->boundingBoxInitialized = 1;
this->boundingBox = clippedLine.bbox( );
}
else
{
this->boundingBox = this->boundingBox + clippedLine.bbox( );
}
}
}
}
QRectF viewportRect( ) const
{
QRectF res;
if ( ! this->scene )
return res;
if ( this->scene->views( ).size( ) == 0 )
return res;
QGraphicsView* view = this->scene->views( ).first( );
QPointF p1 = view->mapToScene( 0, 0 );
QPointF p2 = view->mapToScene( view->width( ), view->height( ) );
res = QRectF( p1, p2 );
return res;
}
protected: // fields
CGAL::Qt::Converter< Kernel > convert;
ArrangementPainterOstream< Traits > painterOstream;
std::vector< X_monotone_curve_2 > curves;
CGAL::Bbox_2 boundingBox;
bool boundingBoxInitialized;
QGraphicsScene* scene;
}; // class CurveGraphicsItem
} // namespace Qt
} // namespace CGAL

View File

@ -70,6 +70,7 @@ DeleteCurveCallback< Arr_ >::
setScene( QGraphicsScene* scene_ )
{
this->scene = scene_;
this->highlightedCurve->setScene( scene_ );
if ( this->scene )
{
this->scene->addItem( this->highlightedCurve );
@ -162,6 +163,7 @@ highlightNearestCurve( QGraphicsSceneMouseEvent* event )
}
#endif
Find_nearest_edge< Arr_ > findNearestEdge( this->arr );
findNearestEdge.setScene( this->scene );
Halfedge_const_handle nearestEdge = findNearestEdge( p );
this->removableHalfedge = this->arr->non_const_handle( nearestEdge );
@ -170,6 +172,7 @@ highlightNearestCurve( QGraphicsSceneMouseEvent* event )
//if ( isFirst )
if ( this->removableHalfedge == Halfedge_handle( ) )
{
std::cout << "no curve found" << std::endl;
return;
}

View File

@ -33,6 +33,9 @@ public:
typedef typename Traits::Construct_x_monotone_curve_2 Construct_x_monotone_curve_2;
typedef typename ArrTraitsAdaptor< Traits >::Kernel Kernel;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Segment_2 Segment_2;
typedef typename Kernel::Ray_2 Ray_2;
typedef typename Kernel::Line_2 Line_2;
typedef CGAL::Envelope_diagram_1< Traits > Diagram_1;
/**
@ -136,6 +139,8 @@ updateEnvelope( bool lower )
typename Diagram_1::Edge_const_handle e = diagram.leftmost( );
typename Diagram_1::Vertex_const_handle v;
QRectF clipRect = this->viewportRect( );
CGAL::Qt::Converter< Kernel > convert( clipRect );
while ( e != diagram.rightmost( ) )
{
if ( ! e->is_empty( ) )
@ -147,8 +152,27 @@ updateEnvelope( bool lower )
// TODO: generate a subcurve instead of just making a segment
Point_2 leftPoint = e->left( )->point( );
Point_2 rightPoint = e->right( )->point( );
Point_2 leftPoint, rightPoint;
if ( e->left( ) != NULL )
{
leftPoint = e->left( )->point( );
}
else
{
std::cout << "handle unbounded curve" << std::endl;
v = e->right( );
e = v->right( );
continue;
}
if ( e->right( ) != NULL )
{
rightPoint = e->right( )->point( );
}
else
{
std::cout << "pRight is null; should never get here..." << std::endl;
}
X_monotone_curve_2 curve =
this->construct_x_monotone_subcurve_2( e->curve( ), leftPoint, rightPoint );
envelopeToUpdate->insert( curve );

View File

@ -3,6 +3,7 @@
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arr_polyline_traits_2.h>
#include <CGAL/Arr_conic_traits_2.h>
#include <CGAL/Arr_linear_traits_2.h>
#include <CGAL/Qt/GraphicsViewInput.h>
#include <CGAL/Qt/Converter.h>
#include <QEvent>
@ -21,7 +22,7 @@ class GraphicsViewCurveInputBase:
{
public:
virtual void setScene( QGraphicsScene* scene_ );
QGraphicsScene* getScene( ) const;
virtual QGraphicsScene* getScene( ) const;
void setSnappingEnabled( bool b );
void setSnapToGridEnabled( bool b );
@ -493,6 +494,142 @@ protected:
ConicType conicType;
}; // class GraphicsViewCurveInput< CGAL::Arr_conic_traits_2< RatKernel, AlgKernel, NtTraits > >
/**
Specialization of GraphicsViewCurveInput for Arr_linear_traits_2; handles
user-guided generation of line segment curves.
*/
template < class Kernel_ >
class GraphicsViewCurveInput< CGAL::Arr_linear_traits_2< Kernel_ > >:
public GraphicsViewCurveInputBase
{
public: // typedefs
typedef Kernel_ Kernel;
typedef GraphicsViewCurveInputBase Superclass;
typedef CGAL::Arr_linear_traits_2< Kernel > Traits;
typedef typename Traits::Curve_2 Curve_2;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Segment_2 Segment_2;
typedef typename Kernel::Ray_2 Ray_2;
typedef typename Kernel::Line_2 Line_2;
enum CurveType
{
SEGMENT, RAY, LINE
};
public: // constructors
GraphicsViewCurveInput( QObject* parent ):
GraphicsViewCurveInputBase( parent ),
second( false ),
curveType( SEGMENT )
{ }
public: // methods
void setCurveType( CurveType type )
{
this->curveType = type;
}
protected: // methods
virtual bool eventFilter( QObject* obj, QEvent* event )
{
// before we do anything, update the clipping rect
// TODO: somehow only update this when the view changes
QRectF clippingRect = this->viewportRect( );
this->convert = Converter< Kernel >( clippingRect );
// now handle the event
return Superclass::eventFilter( obj, event );
}
void mouseMoveEvent( QGraphicsSceneMouseEvent* event )
{
if ( this->second )
{
Point_2 hoverPoint = this->snapPoint( event );
if ( p1 == hoverPoint )
return;
QLineF qSegment;
if ( this->curveType == SEGMENT )
{
Segment_2 segment( this->p1, hoverPoint );
qSegment = this->convert( segment );
}
else if ( this->curveType == RAY )
{
Ray_2 ray( this->p1, hoverPoint );
qSegment = this->convert( ray );
}
else // this->curveType == LINE
{
Line_2 line( this->p1, hoverPoint );
qSegment = this->convert( line );
}
this->segmentGuide.setLine( qSegment );
}
}
void mousePressEvent( QGraphicsSceneMouseEvent* event )
{
if ( !this->second )
{ // fix our first point
this->second = true;
this->p1 = this->snapPoint( event );
QPointF pt = this->convert( this->p1 );
this->segmentGuide.setLine( pt.x( ), pt.y( ), pt.x( ), pt.y( ) );
if ( this->scene != NULL )
{
this->scene->addItem( &( this->segmentGuide ) );
}
}
else // this->second == true
{
this->second = false;
this->p2 = this->snapPoint( event );
// skip if degenerate
if ( this->p1 == this->p2 )
return;
if ( this->scene != NULL )
{
this->scene->removeItem( &( this->segmentGuide ) );
}
Curve_2 res;
if ( this->curveType == SEGMENT )
{
res = Curve_2( Segment_2( this->p1, this->p2 ) );
}
else if ( this->curveType == RAY )
{
res = Curve_2( Ray_2( this->p1, this->p2 ) );
}
else // this->curveType == LINE
{
res = Curve_2( Line_2( this->p1, this->p2 ) );
}
emit generate( CGAL::make_object( res ) );
}
}
// override this to snap to the points you like
virtual Point_2 snapPoint( QGraphicsSceneMouseEvent* event )
{
Point_2 clickedPoint = this->convert( event->scenePos( ) );
return clickedPoint;
}
protected: // fields
Converter< Kernel > convert;
Point_2 p1;
Point_2 p2;
bool second;
QGraphicsLineItem segmentGuide;
CurveType curveType;
}; // class GraphicsViewCurveInput< CGAL::Arr_linear_traits_2< Kernel_ > >
} // namespace Qt
} // namespace CGAL
#endif // CGAL_QT_GRAPHICS_VIEW_SEGMENT_INPUT_H

View File

@ -75,6 +75,8 @@ MergeEdgeCallback< Arr_ >::
setScene( QGraphicsScene* scene_ )
{
this->scene = scene_;
this->highlightedCurve->setScene( scene_ );
this->highlightedCurve2->setScene( scene_ );
if ( this->scene )
{
this->scene->addItem( this->highlightedCurve );

View File

@ -14,6 +14,7 @@ NewTabDialog( QWidget* parent, Qt::WindowFlags f ):
this->buttonGroup->addButton( this->ui->segmentRadioButton, ArrangementDemoWindow::SEGMENT_TRAITS );
this->buttonGroup->addButton( this->ui->polylineRadioButton, ArrangementDemoWindow::POLYLINE_TRAITS );
this->buttonGroup->addButton( this->ui->conicRadioButton, ArrangementDemoWindow::CONIC_TRAITS );
this->buttonGroup->addButton( this->ui->linearRadioButton, ArrangementDemoWindow::LINEAR_TRAITS );
}
int

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>400</width>
<height>133</height>
<height>165</height>
</rect>
</property>
<property name="windowTitle">
@ -19,7 +19,7 @@
<x>10</x>
<y>10</y>
<width>381</width>
<height>113</height>
<height>141</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
@ -50,7 +50,7 @@
</property>
</widget>
</item>
<item row="3" column="0">
<item row="4" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -60,6 +60,13 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QRadioButton" name="linearRadioButton">
<property name="text">
<string>Linear</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>

View File

@ -153,8 +153,8 @@ mousePressEvent( QGraphicsSceneMouseEvent* event )
if ( CGAL::assign( pair, res ) )
{
Point_2 splitPoint = pair.first;
if ( this->areEqual( hei->source( )->point( ), splitPoint ) ||
this->areEqual( hei->target( )->point( ), splitPoint ) )
if ( ( ! hei->source( )->is_at_open_boundary( ) && this->areEqual( hei->source( )->point( ), splitPoint ) ) ||
( ! hei->target( )->is_at_open_boundary( ) && this->areEqual( hei->target( )->point( ), splitPoint ) ) )
{
continue;
}

View File

@ -26,6 +26,15 @@ public:
typedef typename ArrTraits::Point_2 Point_2;
};
template < class Kernel_ >
class ArrTraitsAdaptor< CGAL::Arr_linear_traits_2< Kernel_ > >
{
public:
typedef Kernel_ Kernel;
typedef CGAL::Arr_linear_traits_2< Kernel > ArrTraits;
typedef typename ArrTraits::Point_2 Point_2;
};
template < class SegmentTraits >
class ArrTraitsAdaptor< CGAL::Arr_polyline_traits_2< SegmentTraits > >
{
@ -51,6 +60,12 @@ public:
typedef typename ArrTraitsAdaptor< ArrTraits >::Kernel Kernel;
typedef typename Kernel::FT FT;
public: // ctors
Compute_squared_distance_2_base( ):
scene( 0 )
{ }
public: // methods
template < class T1, class T2 >
FT
operator() ( const T1& t1, const T2& t2 ) const
@ -58,8 +73,36 @@ public:
return this->squared_distance( t1, t2 );
}
protected:
void setScene( QGraphicsScene* scene_ )
{
this->scene = scene_;
}
QRectF viewportRect( ) const
{
QRectF res;
if ( this->scene == NULL )
{
return res;
}
QList< QGraphicsView* > views = this->scene->views( );
if ( views.size( ) == 0 )
{
return res;
}
// assumes the first view is the right one
QGraphicsView* viewport = views.first( );
QPointF p1 = viewport->mapToScene( 0, 0 );
QPointF p2 = viewport->mapToScene( viewport->width( ), viewport->height( ) );
res = QRectF( p1, p2 );
return res;
}
protected: // fields
typename Kernel::Compute_squared_distance_2 squared_distance;
QGraphicsScene* scene;
};
template < class ArrTraits >
@ -89,6 +132,44 @@ public:
}
};
template < class Kernel_ >
class Compute_squared_distance_2< CGAL::Arr_linear_traits_2< Kernel_ > > :
public Compute_squared_distance_2_base< CGAL::Arr_linear_traits_2< Kernel_ > >
{
public:
typedef Kernel_ Kernel;
typedef CGAL::Arr_linear_traits_2< Kernel > Traits;
typedef Compute_squared_distance_2_base< Traits > Superclass;
typedef typename Kernel::FT FT;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Segment_2 Segment_2;
typedef typename Kernel::Ray_2 Ray_2;
typedef typename Kernel::Line_2 Line_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
FT operator() ( const Point_2& p, const X_monotone_curve_2& c ) const
{
Segment_2 seg;
Ray_2 ray;
Line_2 line;
if ( c.is_segment( ) )
{
seg = c.segment( );
return this->squared_distance( p, seg );
}
else if ( c.is_ray( ) )
{
ray = c.ray( );
return this->squared_distance( p, ray );
}
else // ( c.is_line( ) )
{
line = c.line( );
return this->squared_distance( p, line );
}
}
};
template < class Kernel_ >
class Compute_squared_distance_2< CGAL::Arr_polyline_traits_2< Kernel_ > > :
public Compute_squared_distance_2_base< CGAL::Arr_polyline_traits_2< Kernel_ > >
@ -145,6 +226,7 @@ public:
typedef typename Traits::Curve_2 Curve_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
public: // methods
FT operator() ( const Point_2& p, const X_monotone_curve_2& c ) const
{
// Get the co-ordinates of the curve's source and target.
@ -178,7 +260,20 @@ public:
FT min_dist( 100000000 );
AlgKernel ker;
int n = 100; // TODO: get an adaptive approximation
int n = 100;
if ( this->scene != NULL && this->scene->views( ).size( ) != 0 )
{ // use the scene to approximate the resolution of the curve
QGraphicsView* view = this->scene->views( ).first( );
CGAL::Bbox_2 bb = c.bbox( ); // assumes bounded curve
int xmin = view->mapFromScene( bb.xmin( ), bb.ymin( ) ).x( );
int xmax = view->mapFromScene( bb.xmax( ), bb.ymin( ) ).x( );
n = xmax - xmin;
if ( n < 2 )
{
n = 2;
}
}
std::pair< double, double >* app_pts = new std::pair< double, double >[ n + 1 ];
std::pair< double, double >* end_pts = c.polyline_approximation( n, app_pts );
std::pair< double, double >* p_curr = app_pts;
@ -192,7 +287,7 @@ public:
FT dist = CGAL::squared_distance( p, seg );
if ( first || dist < min_dist )
{
first = true;
first = false;
min_dist = dist;
}
@ -249,6 +344,7 @@ public:
if ( this->compare_x_2( pLeft, pMin ) == CGAL::LARGER )
{
// FIXME: handle vertical lines properly
// FIXME: handle unbounded lines properly
CGAL::Bbox_2 c_bbox = curve.bbox( );
FT splitLineYMin( c_bbox.ymin( ) - 1.0 );
FT splitLineYMax( c_bbox.ymax( ) + 1.0 );
@ -346,6 +442,36 @@ public:
}
}; // class Construct_x_monotone_subcurve_2 for Arr_conic_traits_2
template < class Kernel_ >
class Construct_x_monotone_subcurve_2< CGAL::Arr_linear_traits_2< Kernel_ > >
{
public: // typedefs
typedef CGAL::Arr_linear_traits_2< Kernel_ > ArrTraits;
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2;
typedef Kernel_ Kernel;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Segment_2 Segment_2;
public: // methods
// curve can be unbounded. if curve is unbounded to the left, pLeft is a point on the left edge of viewport.
X_monotone_curve_2 operator() ( const X_monotone_curve_2& curve, const Point_2& pLeft, const Point_2& pRight )
{
if ( curve.is_segment( ) )
{
Segment_2 subsegment = this->constructSubsegment( curve.segment( ), pLeft, pRight );
return X_monotone_curve_2( subsegment );
}
else if ( curve.is_ray( ) )
{
}
return curve;
}
protected:
Construct_x_monotone_subcurve_2< CGAL::Arr_segment_traits_2< Kernel_ > > constructSubsegment;
};
template < class K_ >
class SnapStrategy
@ -536,12 +662,51 @@ protected:
CGAL::Qt::Converter< Kernel > convert;
}; // class SnapToArrangementVertexStrategy
template < class Arr_ >
class Find_nearest_edge
class Find_nearest_edge_base
{
public:
Find_nearest_edge_base( ):
scene( 0 )
{ }
public:
virtual void setScene( QGraphicsScene* scene_ )
{
this->scene = scene_;
}
QRectF viewportRect( ) const
{
QRectF res;
if ( this->scene == NULL )
{
return res;
}
QList< QGraphicsView* > views = this->scene->views( );
if ( views.size( ) == 0 )
{
return res;
}
// assumes the first view is the right one
QGraphicsView* viewport = views.first( );
QPointF p1 = viewport->mapToScene( 0, 0 );
QPointF p2 = viewport->mapToScene( viewport->width( ), viewport->height( ) );
res = QRectF( p1, p2 );
return res;
}
protected:
QGraphicsScene* scene;
};
template < class Arr_, class ArrTraits = typename Arr_::Geometry_traits_2 >
class Find_nearest_edge : public Find_nearest_edge_base
{
public: // typedefs
typedef Arr_ Arrangement;
typedef typename Arrangement::Geometry_traits_2 ArrTraits;
//typedef typename Arrangement::Geometry_traits_2 ArrTraits;
typedef Compute_squared_distance_2< ArrTraits > Point_curve_distance;
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2;
typedef CGAL::Arr_walk_along_line_point_location< Arrangement > Point_location_strategy;
@ -557,6 +722,7 @@ public: // typedefs
public: // constructors
Find_nearest_edge( Arrangement* arr_ ):
Find_nearest_edge_base( ),
arr( arr_ ),
pointLocationStrategy( Point_location_strategy( *arr_ ) )
{ }
@ -587,6 +753,159 @@ public: // member methods
}
while ( ++cc != face->outer_ccb( ) );
}
#if 0 // we can't do this with bounded arrangements
else
{
Ccb_halfedge_const_circulator cc = face->outer_ccb( );
do
{
if ( cc->is_fictitious( ) )
{
continue;
}
X_monotone_curve_2 curve = cc->curve( );
FT dist = this->pointCurveDistance( queryPt, curve );
if ( first || dist < minDist )
{
first = 0;
minDist = dist;
closestEdge = cc;
}
}
while ( ++cc != face->outer_ccb( ) );
}
#endif
Hole_const_iterator hit;
Hole_const_iterator eit = face->holes_end( );
int counter = 0;
for ( hit = face->holes_begin( ); hit != eit; ++hit )
{ // check any holes inside this face
Ccb_halfedge_const_circulator cc = *hit;
do
{
X_monotone_curve_2 curve = cc->curve( );
FT dist = this->pointCurveDistance( queryPt, curve );
if ( first || dist < minDist )
{
first = 0;
minDist = dist;
closestEdge = cc;
}
cc++;
}
while ( cc != *hit );
}
return closestEdge;
}
virtual void setScene( QGraphicsScene* scene_ )
{
this->pointCurveDistance.setScene( scene_ );
Find_nearest_edge_base::setScene( scene_ );
}
protected: // member methods
Face_const_handle getFace( const CGAL::Object& obj )
{
Face_const_handle f;
if ( CGAL::assign( f, obj ) )
return f;
Halfedge_const_handle he;
if (CGAL::assign( he, obj ))
return (he->face( ));
Vertex_const_handle v;
CGAL_assertion(CGAL::assign( v, obj ));
CGAL::assign( v, obj );
if ( v->is_isolated( ) )
return v->face( );
Halfedge_around_vertex_const_circulator eit = v->incident_halfedges( );
return (eit->face( ));
}
protected: // member fields
Arrangement* arr;
Point_curve_distance pointCurveDistance;
Point_location_strategy pointLocationStrategy;
}; // class Find_nearest_edge
template < class Arr_, class Kernel_ >
class Find_nearest_edge< Arr_, CGAL::Arr_linear_traits_2< Kernel_ > >: public Find_nearest_edge_base
{
public: // typedefs
typedef Arr_ Arrangement;
typedef typename Arrangement::Geometry_traits_2 ArrTraits;
typedef Compute_squared_distance_2< ArrTraits > Point_curve_distance;
typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2;
typedef CGAL::Arr_walk_along_line_point_location< Arrangement > Point_location_strategy;
typedef typename ArrTraitsAdaptor< ArrTraits >::Kernel Kernel;
typedef typename Kernel::Point_2 Point_2;
typedef typename Arrangement::Face_const_handle Face_const_handle;
typedef typename Arrangement::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement::Ccb_halfedge_const_circulator Ccb_halfedge_const_circulator;
typedef typename Point_curve_distance::FT FT;
typedef typename Arrangement::Hole_const_iterator Hole_const_iterator;
typedef typename Arrangement::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator;
public: // constructors
Find_nearest_edge( Arrangement* arr_ ):
Find_nearest_edge_base( ),
arr( arr_ ),
pointLocationStrategy( Point_location_strategy( *arr_ ) )
{ }
public: // member methods
Halfedge_const_handle operator()( const Point_2& queryPt )
{
CGAL::Object pointLocationResult = this->pointLocationStrategy.locate( queryPt );
Face_const_handle face = this->getFace( pointLocationResult );
bool first = 1;
X_monotone_curve_2 closestCurve;
Halfedge_const_handle closestEdge;
FT minDist( 0 );
if ( ! face->is_unbounded( ) )
{ // it is an interior face so it has a ccb
Ccb_halfedge_const_circulator cc = face->outer_ccb( );
do
{
X_monotone_curve_2 curve = cc->curve( );
FT dist = this->pointCurveDistance( queryPt, curve );
if ( first || dist < minDist )
{
first = 0;
minDist = dist;
closestEdge = cc;
}
}
while ( ++cc != face->outer_ccb( ) );
}
else
{
Ccb_halfedge_const_circulator cc = face->outer_ccb( );
do
{
if ( cc->is_fictitious( ) )
{
continue;
}
X_monotone_curve_2 curve = cc->curve( );
FT dist = this->pointCurveDistance( queryPt, curve );
if ( first || dist < minDist )
{
first = 0;
minDist = dist;
closestEdge = cc;
}
}
while ( ++cc != face->outer_ccb( ) );
}
Hole_const_iterator hit;
Hole_const_iterator eit = face->holes_end( );
for ( hit = face->holes_begin( ); hit != eit; ++hit )
@ -634,7 +953,7 @@ protected: // member fields
Arrangement* arr;
Point_curve_distance pointCurveDistance;
Point_location_strategy pointLocationStrategy;
}; // class Find_nearest_edge
#endif // CGAL_ARRANGEMENTS_DEMO_UTILS_H

View File

@ -115,6 +115,7 @@ VerticalRayShootCallback< Arr_ >::
setScene( QGraphicsScene* scene_ )
{
this->scene = scene_;
this->highlightedCurves->setScene( scene_ );
if ( this->scene )
{
this->scene->addItem( this->highlightedCurves );