take into account Jane's review

This commit is contained in:
Andreas Fabri 2014-11-04 12:24:12 +01:00
parent 42b954e224
commit 42d04ea13f
22 changed files with 215 additions and 266 deletions

View File

@ -298,7 +298,7 @@ void MainWindow::on_actionSimplify_triggered()
// wait cursor
QApplication::setOverrideCursor(Qt::WaitCursor);
PS2::mark_vertices_unremovable(m_pct);
try
{
switch( getSimplificationMode() )

View File

@ -199,7 +199,7 @@ PolylineSimplificationGraphicsItem<PCT>::paintVertices(QPainter *painter)
it != this->t->vertices_in_constraint_end(*cit);
it++){
QPointF point = matrix.map(convert((*it)->point()));
if ( (*it)->removable() )
if ( (*it)->is_removable() )
painter->setPen(this->verticesPen());
else
painter->setPen(this->unremovableVerticesPen());

View File

@ -22,22 +22,18 @@ public:
/*!
Given three consecutive polyline vertices `*vip, *viq, *vir`, calculates the cost of removing vertex `*viq`, replacing edges `(*vip,*viq)` and `(*viq,*vir)` with edge `(*vip,*vir)`.
Given a vertex in constraint iterator `viq` computes `vip= std::prev(viq)` and vir = std::next(vir)`, and the cost of removing vertex `*viq`, replacing edges `(*vip,*viq)` and `(*viq,*vir)` with edge `(*vip,*vir)`.
\param ct The underlying constrained Delaunay triangulation with constraint hierarchy which embeds the polyline constraints
\param vip The first vertex
\param viq The second vertex
\param vir The third vertex
\param viq The vertex in constraint iterator of the vertex to remove
\returns The cost for removing `*viq`. A result of `boost::none` can be used to indicate an infinite or uncomputable cost.
\tparam Tr must be `CGAL::Constrained_Delaunay_triangulation_2` with a vertex type that
is model of `PolylineSimplificationVertexBase_2`. `Tr::Geom_traits` must provide a functor `Compute_squared_distance` with an operator `Tr::Geom_traits::FT operator()(Tr::Point, Tr::Point)`.
\tparam CDT must be `CGAL::Constrained_Delaunay_triangulation_2` with a vertex type that
is model of `PolylineSimplificationVertexBase_2`. `CDT::Geom_traits` must provide a functor `Compute_squared_distance` with an operator `CDT::Geom_traits::FT operator()(CDT::Geom_traits::Point_2, CDT::Geom_traits::Point_2)`.
*/
boost::optional<CGAL::Constrained_triangulation_plus_2<Tr>::Geom_traits::FT>
operator()(CGAL::Constrained_triangulation_plus_2<Tr> const& ct,
CGAL::Constrained_triangulation_plus_2<Tr>::Vertices_in_constraint_iterator vip,
CGAL::Constrained_triangulation_plus_2<Tr>::Vertices_in_constraint_iterator viq,
CGAL::Constrained_triangulation_plus_2<Tr>::Vertices_in_constraint_iterator vir) const;}
boost::optional<CGAL::Constrained_triangulation_plus_2<CDT>::Geom_traits::FT>
operator()(CGAL::Constrained_triangulation_plus_2<CDT> const& ct,
CGAL::Constrained_triangulation_plus_2<CDT>::Vertices_in_constraint_iterator viq) const;}
}; /* end TriangulationVertexBase_2 */

View File

@ -22,12 +22,12 @@ public :
\param initial_count The initial number of vertices in the entire polyline set (including intersection vertices not in any source polyline)
\param current_count The current number of vertices
\return `true` if the algorithm should stop, `false` if it should continue.
\tparam Tr must be `CGAL::Constrained_Delaunay_triangulation_2` with a vertex type that
\tparam CDT must be `CGAL::Constrained_Delaunay_triangulation_2` with a vertex type that
is model of `PolylineSimplificationVertexBase_2`.
*/
template<class Tr>
bool operator()( const CGAL::Constrained_triangulation_plus_2<Tr>& ct
, CGAL::Constrained_triangulation_plus_2<Tr>::Vertex_handle q
template<class CDT>
bool operator()( const CGAL::Constrained_triangulation_plus_2<CDT>& ct
, CGAL::Constrained_triangulation_plus_2<CDT>::Vertex_handle q
, double cost
, std::size_t initial_count
, std::size_t current_count

View File

@ -29,12 +29,15 @@ public:
/*! The Boolean that indicates whether the vertex can be removed.
*/
bool& removable();
bool is_removable() const;
void set_removable(bool b);
/*! The cost if the vertex got removed.
*/
FT& cost();
void set_cost(const FT& ft);
/// @}

View File

@ -43,7 +43,6 @@
## Global Functions ##
- `CGAL::Polyline_simplification_2::simplify()`
- `CGAL::Polyline_simplification_2::mark_vertices_unremovable()`
*/

View File

@ -83,7 +83,7 @@ The maximum squared distance is the maximum of the squared Euclidean
distances between each point on the original polyline between `p` and
`r` and the line segment `(p,r)`. Let \f$s_0,...,s_n\f$ be the points
strictly between `p` and `r` on the original polyline. The cost of
removing vertex `q` is: \f$ v_1 = \max \{ sdist((p,r), s_i) |
removing vertex `q` is: \f$ v_1 = \max \{ squared_distance((p,r), s_i) |
i=0,..,n\} \f$
\cgalFigureBegin{figure_maxDist,maxDist.png}
@ -101,9 +101,9 @@ the candidate vertex `q` and all its adjacent vertices (except `p` and
regions of the same polyline.
Let \f$t_0,...,t_m\f$ be the points of the vertices adjacent to vertex
`q`, different from `p` and `r` and let \f$ v_2 = \min \{ sdist((p,r),
`q`, different from `p` and `r` and let \f$ v_2 = \min \{ squared_distance((p,r),
t_i) | i=0,..,n\}\f$. The cost of removing vertex `q` is
\f$v_1/v_2\f$.
\f$v_1/v_2\f$. See also Figure \ref figure_scaledAndHybrid.
This distance measure gives lower priority to vertices with close
neighboring polylines.
@ -157,16 +157,7 @@ In the second example we insert several polygons in a
type we have to use `CGAL::Polyline_simplification_2::Vertex_base_2`
as vertices may be marked as non-removable. The simplification
algorithm marks the first and last vertex of polyline constraints
as well as intersections.
In the example we mark further polyline vertices as not removable.
This package provides a convenience function
`Polyline_simplification_2::mark_vertices_unremovable()` that marks
the vertices with smallest and largest `x` and `y` coordinates of each
polyline constraint as non-removable. This is rather simplistic, and
in a real world application one would mark vertices as unremovable
because they are important.
Finally, we iterate
as well as intersections. Finally, we iterate
over all vertices of all polyline constraints.
\cgalExample{Polyline_simplification_2/simplify.cpp}

View File

@ -57,7 +57,6 @@ int main( )
}
}
PS::mark_vertices_unremovable(ct,cid);
PS::simplify(ct, cid, Cost(), Stop(0.5), keep_points);
print(ct, cid);
PS::simplify(ct, cid, Cost(), Stop(0.5), keep_points);

View File

@ -29,7 +29,6 @@ int main( )
while(std::cin >> P){
ct.insert_constraint(P);
}
PS::mark_vertices_unremovable(ct);
PS::simplify(ct, Cost(), Stop(0.5));
for(Constraint_iterator cit = ct.constraints_begin();

View File

@ -20,6 +20,7 @@
#ifndef CGAL_POLYLINE_SIMPLIFICATION_2_HYBRID_SQUARED_DISTANCE_COST_H
#define CGAL_POLYLINE_SIMPLIFICATION_2_HYBRID_SQUARED_DISTANCE_COST_H
#include <CGAL/algorithm.h>
namespace CGAL {
@ -40,22 +41,23 @@ public:
/// Initializes the cost function with the specified `ratio`
Hybrid_squared_distance_cost( FT ratio ) : mSquaredRatio(ratio*ratio) {}
/// Returns the maximal square distance between each point along the original subpolyline,
/// between `p` and `r`,
/// and the straight line segment `p->r` divided by the smallest of
/// Given a vertex in constraint iterator `vicq` computes `vicp= std::prev(vicq)` and vicr = std::next(vicr)`,
/// returns the maximal square distance between each point along the original subpolyline,
/// between `vicp` and `vicr`,
/// and the straight line segment from `*vicp->point() to *vicr->point()` divicded by the smallest of
/// - the square of the ratio given to the constructor of the cost function,
/// - and the shortest squared distance between that segment and each of the vertices adjacent to `q`.
template<class Tr>
boost::optional<typename Constrained_triangulation_plus_2<Tr>::Geom_traits::FT>
operator()( const Constrained_triangulation_plus_2<Tr>& pct
, typename Constrained_triangulation_plus_2<Tr>::Vertices_in_constraint_iterator p
, typename Constrained_triangulation_plus_2<Tr>::Vertices_in_constraint_iterator q
, typename Constrained_triangulation_plus_2<Tr>::Vertices_in_constraint_iterator r) const
/// - and the shortest squared distance between that segment and each of the vertices adjacent to `vicq`.
/// \tparam CDT must be `CGAL::Constrained_Delaunay_triangulation_2` with a vertex type that
/// is model of `PolylineSimplificationVertexBase_2`.
template<class CDT>
boost::optional<typename Constrained_triangulation_plus_2<CDT>::Geom_traits::FT>
operator()( const Constrained_triangulation_plus_2<CDT>& pct
, typename Constrained_triangulation_plus_2<CDT>::Vertices_in_constraint_iterator vicq) const
{
typedef typename Constrained_triangulation_plus_2<Tr>::Points_in_constraint_iterator Points_in_constraint_iterator;
typedef typename Constrained_triangulation_plus_2<Tr>::Vertex_handle Vertex_handle;
typedef typename Constrained_triangulation_plus_2<Tr>::Vertex_circulator Vertex_circulator;
typedef typename Constrained_triangulation_plus_2<Tr>::Geom_traits Geom_traits ;
typedef typename Constrained_triangulation_plus_2<CDT>::Points_in_constraint_iterator Points_in_constraint_iterator;
typedef typename Constrained_triangulation_plus_2<CDT>::Vertex_handle Vertex_handle;
typedef typename Constrained_triangulation_plus_2<CDT>::Vertex_circulator Vertex_circulator;
typedef typename Constrained_triangulation_plus_2<CDT>::Geom_traits Geom_traits ;
typedef typename Geom_traits::Compute_squared_distance_2 Compute_squared_distance;
typedef typename Geom_traits::Construct_segment_2 Construct_segment;
typedef typename Geom_traits::Segment_2 Segment;
@ -63,15 +65,19 @@ public:
Compute_squared_distance compute_squared_distance = pct.geom_traits().compute_squared_distance_2_object() ;
Construct_segment construct_segment = pct.geom_traits().construct_segment_2_object() ;
typedef typename Constrained_triangulation_plus_2<CDT>::Vertices_in_constraint_iterator Vertices_in_constraint_iterator;
Point const& lP = (*p)->point();
Point const& lQ = (*q)->point();
Point const& lR = (*r)->point();
Vertices_in_constraint_iterator vicp = boost::prior(vicq);
Vertices_in_constraint_iterator vicr = boost::next(vicq);
Point const& lP = (*vicp)->point();
Point const& lQ = (*vicq)->point();
Point const& lR = (*vicr)->point();
Segment lP_R = construct_segment(lP, lR) ;
FT d1 = 0.0;
Points_in_constraint_iterator pp(p), rr(r);
Points_in_constraint_iterator pp(vicp), rr(vicr);
++pp;
for ( ;pp != rr; ++pp )
@ -79,10 +85,10 @@ public:
FT d2 = (std::numeric_limits<double>::max)() ;
Vertex_circulator vc = (*q)->incident_vertices(), done(vc);
Vertex_circulator vc = (*vicq)->incident_vertices(), done(vc);
do {
if((vc != pct.infinite_vertex()) && (vc != *p) && (vc != *r)){
d2 = (std::min)(d2, compute_squared_distance(vc->point(), (*q)->point()));
if((vc != pct.infinite_vertex()) && (vc != *vicp) && (vc != *vicr)){
d2 = (std::min)(d2, compute_squared_distance(vc->point(), (*vicq)->point()));
}
++vc;
}while(vc != done);

View File

@ -20,6 +20,7 @@
#ifndef CGAL_POLYLINE_SIMPLIFICATION_2_SCALED_SQUARED_DISTANCE_COST_H
#define CGAL_POLYLINE_SIMPLIFICATION_2_SCALED_SQUARED_DISTANCE_COST_H
#include <CGAL/algorithm.h>
namespace CGAL {
@ -39,21 +40,22 @@ public:
/// Initializes the cost function.
Scaled_squared_distance_cost() {}
/// Returns the maximum of the square distances between each point along the original subpolyline
/// between `p` and `r`,
/// and the straight line segment `p->r` divided by the shortest squared distance between
/// that segment and each of the vertices adjacent to `q`.
template<class Tr>
boost::optional<typename Constrained_triangulation_plus_2<Tr>::Geom_traits::FT>
operator()(const Constrained_triangulation_plus_2<Tr>& pct
, typename Constrained_triangulation_plus_2<Tr>::Vertices_in_constraint_iterator p
, typename Constrained_triangulation_plus_2<Tr>::Vertices_in_constraint_iterator q
, typename Constrained_triangulation_plus_2<Tr>::Vertices_in_constraint_iterator r) const
/// Given a vertex in constraint iterator `vicq` computes `vicp= std::prev(vicq)` and vicr = std::next(vicr)`,
/// returns the maximum of the square distances between each point along the original subpolyline
/// between `vicp` and `vicr`,
/// and the straight line segment from `*vicp->point() to *vicr->point()` divided by the shortest squared distance between
/// that segment and each of the vertices adjacent to `vicq`.
/// \tparam CDT must be `CGAL::Constrained_Delaunay_triangulation_2` with a vertex type that
/// is model of `PolylineSimplificationVertexBase_2`.
template<class CDT>
boost::optional<typename Constrained_triangulation_plus_2<CDT>::Geom_traits::FT>
operator()(const Constrained_triangulation_plus_2<CDT>& pct
, typename Constrained_triangulation_plus_2<CDT>::Vertices_in_constraint_iterator vicq) const
{
typedef typename Constrained_triangulation_plus_2<Tr>::Points_in_constraint_iterator Points_in_constraint_iterator;
typedef typename Constrained_triangulation_plus_2<Tr>::Vertex_handle Vertex_handle;
typedef typename Constrained_triangulation_plus_2<Tr>::Vertex_circulator Vertex_circulator;
typedef typename Constrained_triangulation_plus_2<Tr>::Geom_traits Geom_traits ;
typedef typename Constrained_triangulation_plus_2<CDT>::Points_in_constraint_iterator Points_in_constraint_iterator;
typedef typename Constrained_triangulation_plus_2<CDT>::Vertex_handle Vertex_handle;
typedef typename Constrained_triangulation_plus_2<CDT>::Vertex_circulator Vertex_circulator;
typedef typename Constrained_triangulation_plus_2<CDT>::Geom_traits Geom_traits ;
typedef typename Geom_traits::FT FT;
typedef typename Geom_traits::Compute_squared_distance_2 Compute_squared_distance;
typedef typename Geom_traits::Construct_segment_2 Construct_segment;
@ -62,14 +64,18 @@ public:
Compute_squared_distance compute_squared_distance = pct.geom_traits().compute_squared_distance_2_object() ;
Construct_segment construct_segment = pct.geom_traits().construct_segment_2_object() ;
Point const& lP = (*p)->point();
Point const& lR = (*r)->point();
typedef typename Constrained_triangulation_plus_2<CDT>::Vertices_in_constraint_iterator Vertices_in_constraint_iterator;
Vertices_in_constraint_iterator vicp = boost::prior(vicq);
Vertices_in_constraint_iterator vicr = boost::next(vicq);
Point const& lP = (*vicp)->point();
Point const& lR = (*vicr)->point();
Segment lP_R = construct_segment(lP, lR) ;
FT d1 = 0.0;
Points_in_constraint_iterator pp(p), rr(r);
Points_in_constraint_iterator pp(vicp), rr(vicr);
++pp;
for ( ;pp != rr; ++pp )
@ -77,10 +83,10 @@ public:
double d2 = (std::numeric_limits<double>::max)() ;
Vertex_circulator vc = (*q)->incident_vertices(), done(vc);
Vertex_circulator vc = (*vicq)->incident_vertices(), done(vc);
do {
if((vc != pct.infinite_vertex()) && (vc != *p) && (vc != *r)){
d2 = (std::min)(d2, compute_squared_distance(vc->point(), (*q)->point()));
if((vc != pct.infinite_vertex()) && (vc != *vicp) && (vc != *vicr)){
d2 = (std::min)(d2, compute_squared_distance(vc->point(), (*vicq)->point()));
}
++vc;
}while(vc != done);

View File

@ -20,6 +20,7 @@
#ifndef CGAL_POLYLINE_SIMPLIFICATION_2_SQUARED_DISTANCE_COST_H
#define CGAL_POLYLINE_SIMPLIFICATION_2_SQUARED_DISTANCE_COST_H
#include <CGAL/algorithm.h>
namespace CGAL {
@ -45,19 +46,20 @@ public:
/// Initializes the cost function
Squared_distance_cost() {}
/// Returns the maximum of the square distances between each point along the original subpolyline,
/// between `p` and `r`, and the straight line segment `p->r`.
template<class Tr>
boost::optional<typename Constrained_triangulation_plus_2<Tr>::Geom_traits::FT>
operator()(const Constrained_triangulation_plus_2<Tr>& pct
, typename Constrained_triangulation_plus_2<Tr>::Vertices_in_constraint_iterator p
, typename Constrained_triangulation_plus_2<Tr>::Vertices_in_constraint_iterator q
, typename Constrained_triangulation_plus_2<Tr>::Vertices_in_constraint_iterator r) const
/// Given a vertex in constraint iterator `vicq` computes `vicp = std::prev(vicq)` and vicr = std::next(vicr)`,
/// returns the maximum of the square distances between each point along the original subpolyline,
/// between `vicp` and `vicr`, and the straight line segment from `*vicp->point() to *vicr->point()`.
/// \tparam CDT must be `CGAL::Constrained_Delaunay_triangulation_2` with a vertex type that
/// is model of `PolylineSimplificationVertexBase_2`.
template<class CDT>
boost::optional<typename Constrained_triangulation_plus_2<CDT>::Geom_traits::FT>
operator()(const Constrained_triangulation_plus_2<CDT>& pct
, typename Constrained_triangulation_plus_2<CDT>::Vertices_in_constraint_iterator vicq)const
{
typedef typename Constrained_triangulation_plus_2<Tr>::Points_in_constraint_iterator Points_in_constraint_iterator;
typedef typename Constrained_triangulation_plus_2<Tr>::Geom_traits Geom_traits ;
typedef typename Constrained_triangulation_plus_2<CDT>::Points_in_constraint_iterator Points_in_constraint_iterator;
typedef typename Constrained_triangulation_plus_2<CDT>::Geom_traits Geom_traits ;
typedef typename Geom_traits::FT FT;
typedef typename Geom_traits::Compute_squared_distance_2 Compute_squared_distance ;
typedef typename Geom_traits::Construct_segment_2 Construct_segment ;
@ -66,14 +68,18 @@ public:
Compute_squared_distance compute_squared_distance = pct.geom_traits().compute_squared_distance_2_object() ;
Construct_segment construct_segment = pct.geom_traits().construct_segment_2_object() ;
Point const& lP = (*p)->point();
Point const& lR = (*r)->point();
typedef typename Constrained_triangulation_plus_2<CDT>::Vertices_in_constraint_iterator Vertices_in_constraint_iterator;
Vertices_in_constraint_iterator vicp = boost::prior(vicq);
Vertices_in_constraint_iterator vicr = boost::next(vicq);
Point const& lP = (*vicp)->point();
Point const& lR = (*vicr)->point();
Segment lP_R = construct_segment(lP, lR) ;
FT d1 = 0.0;
Points_in_constraint_iterator pp(p), rr(r);
Points_in_constraint_iterator pp(vicp), rr(vicr);
++pp;
for ( ;pp != rr; ++pp )

View File

@ -41,9 +41,12 @@ public :
Stop_above_cost_threshold( double aThreshold ) : mThres(aThreshold) {}
/// Returns `true` when `cost` is smaller or equal than the threshold.
template<class Tr>
bool operator()(const Constrained_triangulation_plus_2<Tr>& ct
, typename Constrained_triangulation_plus_2<Tr>::Vertex_handle q
/// \tparam CDT must be `CGAL::Constrained_Delaunay_triangulation_2` with a vertex type that
/// is model of `PolylineSimplificationVertexBase_2`.
template<class CDT>
bool operator()(const Constrained_triangulation_plus_2<CDT>& ct
, typename Constrained_triangulation_plus_2<CDT>::Vertex_handle q
, double cost
, std::size_t initial_count
, std::size_t current_count

View File

@ -20,6 +20,7 @@
#ifndef CGAL_POLYLINE_SIMPLIFICATION_2_STOP_BELOW_COUNT_RATIO_THRESHOLD_H
#define CGAL_POLYLINE_SIMPLIFICATION_2_STOP_BELOW_COUNT_RATIO_THRESHOLD_H
#include <CGAL/Constrained_triangulation_plus_2.h>
namespace CGAL {
@ -40,9 +41,12 @@ public :
Stop_below_count_ratio_threshold( double threshold ) : mThres(threshold) {}
/// Returns `true` when `( current_count / initial_count )` is smaller or equal than the threshold.
template<class ConstrainedDelaunayTriangulation> // , class VertexHandle>
bool operator()(const ConstrainedDelaunayTriangulation &
, typename ConstrainedDelaunayTriangulation::Vertex_handle
/// \tparam CDT must be `CGAL::Constrained_Delaunay_triangulation_2` with a vertex type that
/// is model of `PolylineSimplificationVertexBase_2`.
template<class CDT>
bool operator()(const Constrained_triangulation_plus_2<CDT> &
, typename Constrained_triangulation_plus_2<CDT>::Vertex_handle
, double
, std::size_t initial_count
, std::size_t current_count

View File

@ -39,9 +39,12 @@ public :
Stop_below_count_threshold( std::size_t threshold ) : mThres(threshold) {}
/// Returns `true` when `current_count` is smaller or equal than the threshold.
template<class Tr>
bool operator()(const Constrained_triangulation_plus_2<Tr>& ct
, typename Constrained_triangulation_plus_2<Tr>::Vertex_handle & q
/// \tparam CDT must be `CGAL::Constrained_Delaunay_triangulation_2` with a vertex type that
/// is model of `PolylineSimplificationVertexBase_2`.
template<class CDT>
bool operator()(const Constrained_triangulation_plus_2<CDT>& ct
, typename Constrained_triangulation_plus_2<CDT>::Vertex_handle & q
, double cost
, std::size_t initial_count
, std::size_t current_count

View File

@ -39,6 +39,10 @@ class Vertex_base_2
typedef typename K::FT FT;
typedef Vb Base;
typedef typename Base::Triangulation_data_structure Tds;
bool m_removable;
FT m_cost;
public:
template < typename TDS2 >
struct Rebind_TDS {
@ -50,18 +54,26 @@ public:
: Base(), m_removable(true), m_cost(-1.0)
{}
bool m_removable;
FT m_cost;
bool& removable()
bool is_removable() const
{
return m_removable;
}
FT& cost()
void set_removable(bool b)
{
m_removable = b;
}
FT cost() const
{
return m_cost;
}
void set_cost(const FT& ft)
{
m_cost = ft;
}
};

View File

@ -1,81 +0,0 @@
// Copyright (c) 2012 Geometry Factory. All rights reserved.
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
// Author(s) : Andreas Fabri
//
#ifndef CGAL_POLYLINE_SIMPLIFICATION_2_MARK_VERTICES_UNREMOVBLE_H
#define CGAL_POLYLINE_SIMPLIFICATION_2_MARK_VERTICES_UNREMOVBLE_H
namespace CGAL {
#ifndef DOXYGEN_RUNNING
template < class Tr >
class Constrained_triangulation_plus_2;
#endif
namespace Polyline_simplification_2 {
/*!
\ingroup PkgPolylineSimplification2Functions
Fix the leftmost, rightmost, topmost and bottommost vertex of a polyline.
*/
template <typename Tr>
void
mark_vertices_unremovable(CGAL::Constrained_triangulation_plus_2<Tr>& pct,
typename CGAL::Constrained_triangulation_plus_2<Tr>::Constraint_id cid)
{
typedef typename CGAL::Constrained_triangulation_plus_2<Tr> PCT;
typedef typename PCT::Vertices_in_constraint_iterator Vertices_in_constraint_iterator;
typename PCT::Vertex_handle l,r,b,t;
l = r = b = t = *(pct.vertices_in_constraint_begin(cid));
for(Vertices_in_constraint_iterator it = pct.vertices_in_constraint_begin(cid);
it != pct.vertices_in_constraint_end(cid);
it++){
if((*it)->point().x() < l->point().x()) l = *it;
if((*it)->point().x() > r->point().x()) r = *it;
if((*it)->point().y() < b->point().y()) b = *it;
if((*it)->point().y() > t->point().y()) t = *it;
}
l->removable() = r->removable() = t->removable() = b->removable() = false;
}
/// Fix the leftmost, rightmost, topmost and bottommost vertex of each polyline.
template <typename Tr>
void
mark_vertices_unremovable(CGAL::Constrained_triangulation_plus_2<Tr>& pct)
{
typedef typename CGAL::Constrained_triangulation_plus_2<Tr> PCT;
typedef typename PCT::Constraint_iterator Constraint_iterator;
typedef typename PCT::Constraint_id Constraint_id;
Constraint_iterator cit = pct.constraints_begin(), e = pct.constraints_end();
for(; cit!=e; ++cit){
Constraint_id cid = *cit;
mark_vertices_unremovable(pct,cid);
}
}
} // namespace polyline_simplification_2
} // namespace CGAL
#endif

View File

@ -20,6 +20,8 @@
#ifndef CGAL_POLYLINE_SIMPLIFICATION_2_SIMPLIFY_H
#define CGAL_POLYLINE_SIMPLIFICATION_2_SIMPLIFY_H
#include <list>
#include <CGAL/Polyline_simplification_2/Vertex_base_2.h>
#include <CGAL/Polyline_simplification_2/Squared_distance_cost.h>
#include <CGAL/Polyline_simplification_2/Scaled_squared_distance_cost.h>
@ -27,12 +29,8 @@
#include <CGAL/Polyline_simplification_2/Stop_below_count_ratio_threshold.h>
#include <CGAL/Polyline_simplification_2/Stop_below_count_threshold.h>
#include <CGAL/Polyline_simplification_2/Stop_above_cost_threshold.h>
#include <CGAL/Polyline_simplification_2/mark_vertices_unremovable.h>
#include <CGAL/Modifiable_priority_queue.h>
#include <list>
#include <boost/next_prior.hpp>
#include <CGAL/algorithm.h>
// Needed for Polygon_2
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
@ -45,7 +43,7 @@ namespace CGAL {
#ifndef DOXYGEN_RUNNING
template < class Tr >
template < class CDT >
class Constrained_triangulation_plus_2;
@ -134,16 +132,16 @@ public:
for(; cit!=e; ++cit){
Constraint_id cid = *cit;
Vertices_in_constraint_iterator it = pct.vertices_in_constraint_begin(cid);
(*it)->removable() = false;
(*it)->set_removable(false);
for(; it != pct.vertices_in_constraint_end(cid); ++it){
if(vertices.find(*it) != vertices.end()){
(*it)->removable() = false;
(*it)->set_removable(false);
} else {
vertices.insert(*it);
}
}
it = boost::prior(it);
(*it)->removable() = false;
(*it)->set_removable(false);
}
}
@ -155,17 +153,14 @@ public:
for(Vertices_in_constraint_iterator it = pct.vertices_in_constraint_begin(cid);
it != pct.vertices_in_constraint_end(cid);
++it){
if((*it)->removable()){
Vertices_in_constraint_iterator u = boost::prior(it);
Vertices_in_constraint_iterator w = boost::next(it);
boost::optional<double> dist = cost(pct, u, it, w);
if((*it)->is_removable()){
boost::optional<double> dist = cost(pct, it);
if(dist){
(*it)->cost() = *dist;
(*it)->set_cost(*dist);
(*mpq).push(it);
++n;
} else {
(*it)->cost() = (std::numeric_limits<double>::max)();
(*it)->set_cost((std::numeric_limits<double>::max)());
std::cerr << "could not compute a cost" << std::endl;
}
}
@ -187,7 +182,7 @@ public:
is_removable(Vertices_in_constraint_iterator it)
{
typedef typename PCT::Geom_traits Geom_traits;
if(! (*it)->removable()) {
if(! (*it)->is_removable()) {
return false;
}
@ -266,28 +261,28 @@ operator()()
}
if(is_removable(v)){
Vertices_in_constraint_iterator u = boost::prior(v), w = boost::next(v);
pct.simplify(u,v,w);
pct.simplify(v);
if((*u)->removable()){
if((*u)->is_removable()){
Vertices_in_constraint_iterator uu = boost::prior(u);
boost::optional<double> dist = cost(pct, uu,u,w);
boost::optional<double> dist = cost(pct, u);
if(! dist){
std::cerr << "undefined cost not handled yet" << std::endl;
} else {
(*u)->cost() = *dist;
(*u)->set_cost(*dist);
if((*mpq).contains(u)){
(*mpq).update(u, true);
}
}
}
if((*w)->removable()){
if((*w)->is_removable()){
Vertices_in_constraint_iterator ww = boost::next(w);
boost::optional<double> dist = cost(pct, u,w,ww);
boost::optional<double> dist = cost(pct, w);
if(! dist){
std::cerr << "undefined cost not handled yet" << std::endl;
} else {
(*w)->cost() = *dist;
(*w)->set_cost(*dist);
if((*mpq).contains(w)){
(*mpq).update(w, true);
}
@ -409,20 +404,20 @@ Simplifies a single polyline in a triangulation with polylines as constraints.
\param ct The underlying constrained Delaunay triangulation with constraint hierarchy which embeds the polyline constraints
\returns the number of removed vertices
\tparam Tr must be `CGAL::Constrained_Delaunay_triangulation_2` with a vertex type that
\tparam CDT must be `CGAL::Constrained_Delaunay_triangulation_2` with a vertex type that
is model of `PolylineSimplificationVertexBase_2`.
\tparam CostFunction must be a model of `PolylineSimplificationCostFunction`
\tparam StopFunction must be a model of `PolylineSimplificationStopPredicate`
*/
template <class Tr, class CostFunction, class StopFunction>
template <class CDT, class CostFunction, class StopFunction>
std::size_t
simplify(CGAL::Constrained_triangulation_plus_2<Tr>& ct,
typename CGAL::Constrained_triangulation_plus_2<Tr>::Constraint_id cid,
simplify(CGAL::Constrained_triangulation_plus_2<CDT>& ct,
typename CGAL::Constrained_triangulation_plus_2<CDT>::Constraint_id cid,
CostFunction cost,
StopFunction stop,
bool keep_points = false)
{
typedef CGAL::Constrained_triangulation_plus_2<Tr> PCT;
typedef CGAL::Constrained_triangulation_plus_2<CDT> PCT;
Polyline_simplification_2<PCT, CostFunction, StopFunction> simplifier(ct, cid, cost, stop);
while(simplifier()){}
@ -437,20 +432,20 @@ simplify(CGAL::Constrained_triangulation_plus_2<Tr>& ct,
Simplifies all polylines in a triangulation with polylines as constraints.
\param ct The underlying constrained Delaunay triangulation with constraint hierarchy which embeds the polyline constraints
\returns the number of removed vertices
\tparam Tr must be `CGAL::Constrained_Delaunay_triangulation_2` with a vertex type that
\tparam CDT must be `CGAL::Constrained_Delaunay_triangulation_2` with a vertex type that
is model of `PolylineSimplificationVertexBase_2`.
\tparam CostFunction must be a model of `PolylineSimplificationCostFunction`
\tparam StopFunction must be a model of `PolylineSimplificationStopPredicate`
*/
template <class Tr, class CostFunction, class StopFunction>
template <class CDT, class CostFunction, class StopFunction>
std::size_t
simplify(CGAL::Constrained_triangulation_plus_2<Tr>& ct,
simplify(CGAL::Constrained_triangulation_plus_2<CDT>& ct,
CostFunction cost,
StopFunction stop,
bool keep_points = false)
{
typedef CGAL::Constrained_triangulation_plus_2<Tr> PCT;
typedef CGAL::Constrained_triangulation_plus_2<CDT> PCT;
Polyline_simplification_2<PCT, CostFunction, StopFunction> simplifier(ct, cost, stop);
while(simplifier()){}

View File

@ -315,7 +315,7 @@ Context context(Vertex_handle va, Vertex_handle vb) const;
/*!
Returns an iterator pointing on the first `Context`
of the sequence of contexts
corresponding to the constraints enclosing the subconstraint`(va,vb)`.
corresponding to the constraints enclosing the subconstraint `(va,vb)`.
\pre `va` and `vb` refer to the vertices of a constrained edge of the triangulation.
*/
Context_iterator contexts_begin(Vertex_handle va,
@ -375,20 +375,19 @@ typedef unspecified_type Points_in_constraint_iterator;
/*!
\cgalAdvancedBegin
Removes the vertex at `vicq` from the constraint and the triangulation.
Only the vertex but not the point is removed from the constraint.
\pre The vertices `vicp`, `vicq`, and `vicr` must be three successive
vertices in a constraint.
Let `vip` and `viq` be defined as `vip = std::prev(vicq)` and vir = std::next(vicr)`,
\pre `vicq` must neither be the first, nor the last vertex on a constraint.
\pre No other constraint must pass through `vicq`.
\pre The line segment between `vicp` and `vicr` must not intersect any constraint.
\pre The line segment between `*vicp->point()` and `*vicr->point()` must not intersect any constraint.
\pre All vertices of the triangulation must be a vertex of a constaint.
\cgalAdvancedEnd
*/
void
simplify(Vertices_in_constraint_iterator vicp,
Vertices_in_constraint_iterator vicq,
Vertices_in_constraint_iterator vicr);
simplify(Vertices_in_constraint_iterator vicq);
/*!
\cgalAdvancedBegin

View File

@ -1015,28 +1015,67 @@ introducing new vertices at each proper intersection
point.
The data structure maintains for each input constraint
The constraint hierarchy maintains for each input constraint
the sequence of vertices on this constraint. These vertices are
either vertices of the input constraint or intersection points.
Two consecutive vertices of an input constraint form a *subconstraint*.
A subconstraint is a pair of vertex handles and corresponds to a constrained edge of the
triangulation, which is a pair of a face handle and an index.
The constraint hierarchy also allows to retrieve the set
The constraint hierarchy allows to retrieve the set
of subconstraints of the triangulation (not ordered along constraints).
It further allows to retrieve for a subconstraint, the set of input constraints that overlap it.
As it is straightforward to obtain a subconstraint from a constrained edge `e`,
one can obtain the input constraints which overlap `e`.
\subsection Subsection_Edges_and_Constraints Edges, Constrained Edges, Constraints, and Subconstraints
All triangulation classes define the type `Edge` as `typedef std::pair<Face_handle>, int> Edge`.
For a pair `(fh,i)` it is the edge of the face `*fh`,which is opposite to the `i`'th vertex.
A <em>constrained edge</em> `e` as an edge of a constrained triangulation `ct`, for which `ct.is_constrained(e) == true`.
A <em>constraint</em> is a polyline which is given as input (in the simplest case just a segment), and
which is split into constrained edges in the triangulation.
The type `Subconstraint` is defined as `typedef std::pair<Vertex_handle,Vertex_handle> Subconstraint`. The two vertex handles must
be the vertices of a constrained edge.
The type `Constraint_id` allows to identify a constraint.
All constrained triangulation classes of \cgal allow to insert constraints, have the notion of constrained edges,
and offer a `Constrained_edges_iterator`.
Only the class `Constrained_triangulation_plus_2` allows
- to enumerate the constraints with a `Constraint_iterator` with value type `Constraint_id`,
- to obtain all constraints that overlap with a constrained edge or a subconstraint,
- to traverse the sequence of vertices of a constraint with a `Vertices_in_constraint_iterator`,
- to enumerate the subconstraints in the triangulation with a `Subconstraint_iterator`, with value type `Subconstraint`.
This iterator is similar to the `Constrained_edges_iterator`.
\subsection Subsection_Constrained_plus_avoids_cascacding The Intersection Tag
The class `Constrained_triangulation_plus_2<Tr>`
is especially useful when the base constrained triangulation class
handles intersections of constraints and uses an exact number type,
i.e.\ when its intersection tag is `Exact_intersections_tag`.
In this case, the `Constrained_triangulation_plus_2<Tr>`
avoids cascading in the computations of intersection points:
The intersection of a segment as part of an input constraint and a constrained edge`e` is
computed with a segment of a previously inserted input constraint overlapping the constrained edge `e`, instead of the segment defined by the two vertices of the constrained edge.
avoids cascading in the computations of intersection points.
This is best explained with an example.
\cgalFigureBegin{figuretri_avoidcascading,CDTplusAvoidCascading.png}
Computation of an intersection with an input constraint instead of with an edge.
\cgalFigureEnd
When inserting a constraint, say a segment `s` in the triangulation, this segment may intersect a constrained edge `e`
with the vertices `p` and `q`.
The algorithm could compute the intersection point `i` of `s` with the segment `(p,q)`. Because these points may be previously constructed
intersection points, as `q` in the figure above, it is better to obtain an input constraint `c` that overlaps the edge. If `c` is a segment
the algorithm intersects `s` with `c`. If `c` is a polyline, the algorithm finds two vertices on the input constraint that
define a segment that overlaps `e`.
@ -1138,35 +1177,6 @@ a triangulation hierarchy in conjunction with a constrained triangulation with a
\cgalExample{Triangulation_2/constrained_hierarchy_plus.cpp}
\section Triangulation_2_Edges_Constraints Edges, Constrained Edges, Constraints, and Subconstraints
This section recalls the definition of edges, constrained edges, constraints and subconstraint.
`Edge` is defined as `typedef std::pair<Face_handle>, int> Edge`. For a pair `(fh,i)` it is the edge of the face `*fh`,
which is opposite to the `i`'th vertex.
A <em>constrained edge</em> `e` is an edge of a constrained triangulation `ct`, for which `ct.is_constrained(e) == true`.
All constrained triangulations offer a `Constrained_edges_iterator` which allows to
enumerate the constrained edges.
A <em>constraint</em> is a polyline, and hence potentially a segment, which is given as input and
which is split into constrained edges in the triangulation.
`Subconstraint` is defined as `typedef std::pair<Vertex_handle,Vertex_handle> Subconstraint`. The two vertex handles must
be vertices of the same face, that is a subconstraint corresponds to an edge.
A `Constraint_id` is a type that allows to identify a constraint.
All constrained triangulation classes allow to insert constraints, have the notion of constrained edges,
and offer a `Contrained_edges_iterator`.
Only the class `Constrained_triangulation_plus_2` allows
- to enumerate the constraints with a `Constraint_iterator` with value type `Constraint_id`,
- to obtain all constraints that overlap with a constrained edge or a subconstraint,
- to traverse the sequence of vertices of a constraint with a `Vertices_in_constraint_iterator`,
- to enumerate the subconstraints in the triangulation with a `Subconstraint_iterator`, with value type `Subconstraint`.
This iterator is similar to the `Contrained_edges_iterator`.
\section Section_2D_Triangulations_Flexibility Flexibility

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -610,11 +610,10 @@ public:
hierarchy.remove_constraint(va,vb);
}
void simplify(Vertices_in_constraint_iterator u,
Vertices_in_constraint_iterator v,
Vertices_in_constraint_iterator w)
void simplify(Vertices_in_constraint_iterator v)
{
Vertices_in_constraint_iterator u = boost::prior(v);
Vertices_in_constraint_iterator w = boost::next(v);
hierarchy.simplify(u,v,w);
Triangulation::remove_incident_constraints(*v);