diff --git a/Polyline_simplification_2/demo/Polyline_simplification_2/Polyline_simplification_2.cpp b/Polyline_simplification_2/demo/Polyline_simplification_2/Polyline_simplification_2.cpp index 6fc0870923e..49ffcfd1b0a 100644 --- a/Polyline_simplification_2/demo/Polyline_simplification_2/Polyline_simplification_2.cpp +++ b/Polyline_simplification_2/demo/Polyline_simplification_2/Polyline_simplification_2.cpp @@ -298,7 +298,7 @@ void MainWindow::on_actionSimplify_triggered() // wait cursor QApplication::setOverrideCursor(Qt::WaitCursor); - PS2::mark_vertices_unremovable(m_pct); + try { switch( getSimplificationMode() ) diff --git a/Polyline_simplification_2/demo/Polyline_simplification_2/include/CGAL/Qt/Polyline_simplification_2_graphics_item.h b/Polyline_simplification_2/demo/Polyline_simplification_2/include/CGAL/Qt/Polyline_simplification_2_graphics_item.h index 95c41a5f512..bcc3cc66ec0 100644 --- a/Polyline_simplification_2/demo/Polyline_simplification_2/include/CGAL/Qt/Polyline_simplification_2_graphics_item.h +++ b/Polyline_simplification_2/demo/Polyline_simplification_2/include/CGAL/Qt/Polyline_simplification_2_graphics_item.h @@ -199,7 +199,7 @@ PolylineSimplificationGraphicsItem::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()); diff --git a/Polyline_simplification_2/doc/Polyline_simplification_2/Concepts/PolylineSimplificationCostFunction.h b/Polyline_simplification_2/doc/Polyline_simplification_2/Concepts/PolylineSimplificationCostFunction.h index 8deee27cc1c..f768192fcd1 100644 --- a/Polyline_simplification_2/doc/Polyline_simplification_2/Concepts/PolylineSimplificationCostFunction.h +++ b/Polyline_simplification_2/doc/Polyline_simplification_2/Concepts/PolylineSimplificationCostFunction.h @@ -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::Geom_traits::FT> - operator()(CGAL::Constrained_triangulation_plus_2 const& ct, - CGAL::Constrained_triangulation_plus_2::Vertices_in_constraint_iterator vip, - CGAL::Constrained_triangulation_plus_2::Vertices_in_constraint_iterator viq, - CGAL::Constrained_triangulation_plus_2::Vertices_in_constraint_iterator vir) const;} + boost::optional::Geom_traits::FT> + operator()(CGAL::Constrained_triangulation_plus_2 const& ct, + CGAL::Constrained_triangulation_plus_2::Vertices_in_constraint_iterator viq) const;} }; /* end TriangulationVertexBase_2 */ diff --git a/Polyline_simplification_2/doc/Polyline_simplification_2/Concepts/PolylineSimplificationStopPredicate.h b/Polyline_simplification_2/doc/Polyline_simplification_2/Concepts/PolylineSimplificationStopPredicate.h index c818fc83e8e..2087a85637c 100644 --- a/Polyline_simplification_2/doc/Polyline_simplification_2/Concepts/PolylineSimplificationStopPredicate.h +++ b/Polyline_simplification_2/doc/Polyline_simplification_2/Concepts/PolylineSimplificationStopPredicate.h @@ -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 - bool operator()( const CGAL::Constrained_triangulation_plus_2& ct - , CGAL::Constrained_triangulation_plus_2::Vertex_handle q + template + bool operator()( const CGAL::Constrained_triangulation_plus_2& ct + , CGAL::Constrained_triangulation_plus_2::Vertex_handle q , double cost , std::size_t initial_count , std::size_t current_count diff --git a/Polyline_simplification_2/doc/Polyline_simplification_2/Concepts/PolylineSimplificationVertexBase_2.h b/Polyline_simplification_2/doc/Polyline_simplification_2/Concepts/PolylineSimplificationVertexBase_2.h index 2be7388284a..2ac4c4741b6 100644 --- a/Polyline_simplification_2/doc/Polyline_simplification_2/Concepts/PolylineSimplificationVertexBase_2.h +++ b/Polyline_simplification_2/doc/Polyline_simplification_2/Concepts/PolylineSimplificationVertexBase_2.h @@ -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); /// @} diff --git a/Polyline_simplification_2/doc/Polyline_simplification_2/PackageDescription.txt b/Polyline_simplification_2/doc/Polyline_simplification_2/PackageDescription.txt index 16734386b2e..c154fdaccc3 100644 --- a/Polyline_simplification_2/doc/Polyline_simplification_2/PackageDescription.txt +++ b/Polyline_simplification_2/doc/Polyline_simplification_2/PackageDescription.txt @@ -43,7 +43,6 @@ ## Global Functions ## - `CGAL::Polyline_simplification_2::simplify()` -- `CGAL::Polyline_simplification_2::mark_vertices_unremovable()` */ diff --git a/Polyline_simplification_2/doc/Polyline_simplification_2/Polyline_simplification_2.txt b/Polyline_simplification_2/doc/Polyline_simplification_2/Polyline_simplification_2.txt index fd53a255cb3..aec051c8d61 100644 --- a/Polyline_simplification_2/doc/Polyline_simplification_2/Polyline_simplification_2.txt +++ b/Polyline_simplification_2/doc/Polyline_simplification_2/Polyline_simplification_2.txt @@ -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} diff --git a/Polyline_simplification_2/examples/Polyline_simplification_2/points_and_vertices.cpp b/Polyline_simplification_2/examples/Polyline_simplification_2/points_and_vertices.cpp index 518f79a8dc2..34397eb1ddd 100644 --- a/Polyline_simplification_2/examples/Polyline_simplification_2/points_and_vertices.cpp +++ b/Polyline_simplification_2/examples/Polyline_simplification_2/points_and_vertices.cpp @@ -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); diff --git a/Polyline_simplification_2/examples/Polyline_simplification_2/simplify.cpp b/Polyline_simplification_2/examples/Polyline_simplification_2/simplify.cpp index bf145c2da5d..acbea64afa2 100644 --- a/Polyline_simplification_2/examples/Polyline_simplification_2/simplify.cpp +++ b/Polyline_simplification_2/examples/Polyline_simplification_2/simplify.cpp @@ -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(); diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Hybrid_squared_distance_cost.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Hybrid_squared_distance_cost.h index e986317d82d..22b868eb040 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Hybrid_squared_distance_cost.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Hybrid_squared_distance_cost.h @@ -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 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 - boost::optional::Geom_traits::FT> - operator()( const Constrained_triangulation_plus_2& pct - , typename Constrained_triangulation_plus_2::Vertices_in_constraint_iterator p - , typename Constrained_triangulation_plus_2::Vertices_in_constraint_iterator q - , typename Constrained_triangulation_plus_2::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 + boost::optional::Geom_traits::FT> + operator()( const Constrained_triangulation_plus_2& pct + , typename Constrained_triangulation_plus_2::Vertices_in_constraint_iterator vicq) const { - typedef typename Constrained_triangulation_plus_2::Points_in_constraint_iterator Points_in_constraint_iterator; - typedef typename Constrained_triangulation_plus_2::Vertex_handle Vertex_handle; - typedef typename Constrained_triangulation_plus_2::Vertex_circulator Vertex_circulator; - typedef typename Constrained_triangulation_plus_2::Geom_traits Geom_traits ; + typedef typename Constrained_triangulation_plus_2::Points_in_constraint_iterator Points_in_constraint_iterator; + typedef typename Constrained_triangulation_plus_2::Vertex_handle Vertex_handle; + typedef typename Constrained_triangulation_plus_2::Vertex_circulator Vertex_circulator; + typedef typename Constrained_triangulation_plus_2::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::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::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); diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Scaled_squared_distance_cost.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Scaled_squared_distance_cost.h index eedc63f92c2..19ba8f8bc87 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Scaled_squared_distance_cost.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Scaled_squared_distance_cost.h @@ -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 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 - boost::optional::Geom_traits::FT> - operator()(const Constrained_triangulation_plus_2& pct - , typename Constrained_triangulation_plus_2::Vertices_in_constraint_iterator p - , typename Constrained_triangulation_plus_2::Vertices_in_constraint_iterator q - , typename Constrained_triangulation_plus_2::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 + boost::optional::Geom_traits::FT> + operator()(const Constrained_triangulation_plus_2& pct + , typename Constrained_triangulation_plus_2::Vertices_in_constraint_iterator vicq) const { - typedef typename Constrained_triangulation_plus_2::Points_in_constraint_iterator Points_in_constraint_iterator; - typedef typename Constrained_triangulation_plus_2::Vertex_handle Vertex_handle; - typedef typename Constrained_triangulation_plus_2::Vertex_circulator Vertex_circulator; - typedef typename Constrained_triangulation_plus_2::Geom_traits Geom_traits ; + typedef typename Constrained_triangulation_plus_2::Points_in_constraint_iterator Points_in_constraint_iterator; + typedef typename Constrained_triangulation_plus_2::Vertex_handle Vertex_handle; + typedef typename Constrained_triangulation_plus_2::Vertex_circulator Vertex_circulator; + typedef typename Constrained_triangulation_plus_2::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::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::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); diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Squared_distance_cost.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Squared_distance_cost.h index ec68997b345..fb695a5021f 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Squared_distance_cost.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Squared_distance_cost.h @@ -20,6 +20,7 @@ #ifndef CGAL_POLYLINE_SIMPLIFICATION_2_SQUARED_DISTANCE_COST_H #define CGAL_POLYLINE_SIMPLIFICATION_2_SQUARED_DISTANCE_COST_H +#include 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 - boost::optional::Geom_traits::FT> - operator()(const Constrained_triangulation_plus_2& pct - , typename Constrained_triangulation_plus_2::Vertices_in_constraint_iterator p - , typename Constrained_triangulation_plus_2::Vertices_in_constraint_iterator q - , typename Constrained_triangulation_plus_2::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 + boost::optional::Geom_traits::FT> + operator()(const Constrained_triangulation_plus_2& pct + , typename Constrained_triangulation_plus_2::Vertices_in_constraint_iterator vicq)const { - typedef typename Constrained_triangulation_plus_2::Points_in_constraint_iterator Points_in_constraint_iterator; - typedef typename Constrained_triangulation_plus_2::Geom_traits Geom_traits ; + typedef typename Constrained_triangulation_plus_2::Points_in_constraint_iterator Points_in_constraint_iterator; + typedef typename Constrained_triangulation_plus_2::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::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 ) diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Stop_above_cost_threshold.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Stop_above_cost_threshold.h index 402d0554e43..755488a0807 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Stop_above_cost_threshold.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Stop_above_cost_threshold.h @@ -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 - bool operator()(const Constrained_triangulation_plus_2& ct - , typename Constrained_triangulation_plus_2::Vertex_handle q + /// \tparam CDT must be `CGAL::Constrained_Delaunay_triangulation_2` with a vertex type that + /// is model of `PolylineSimplificationVertexBase_2`. + + template + bool operator()(const Constrained_triangulation_plus_2& ct + , typename Constrained_triangulation_plus_2::Vertex_handle q , double cost , std::size_t initial_count , std::size_t current_count diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Stop_below_count_ratio_threshold.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Stop_below_count_ratio_threshold.h index 8e19893acbd..36c65f28a41 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Stop_below_count_ratio_threshold.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Stop_below_count_ratio_threshold.h @@ -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 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 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 + bool operator()(const Constrained_triangulation_plus_2 & + , typename Constrained_triangulation_plus_2::Vertex_handle , double , std::size_t initial_count , std::size_t current_count diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Stop_below_count_threshold.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Stop_below_count_threshold.h index 76b5bf6cfa3..954c426361b 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Stop_below_count_threshold.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Stop_below_count_threshold.h @@ -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 - bool operator()(const Constrained_triangulation_plus_2& ct - , typename Constrained_triangulation_plus_2::Vertex_handle & q + /// \tparam CDT must be `CGAL::Constrained_Delaunay_triangulation_2` with a vertex type that + /// is model of `PolylineSimplificationVertexBase_2`. + + template + bool operator()(const Constrained_triangulation_plus_2& ct + , typename Constrained_triangulation_plus_2::Vertex_handle & q , double cost , std::size_t initial_count , std::size_t current_count diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Vertex_base_2.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Vertex_base_2.h index 677557214fc..315abc8f8b6 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Vertex_base_2.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Vertex_base_2.h @@ -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; + } }; diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/mark_vertices_unremovable.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/mark_vertices_unremovable.h deleted file mode 100644 index 4d32cd5dbce..00000000000 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/mark_vertices_unremovable.h +++ /dev/null @@ -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 -void -mark_vertices_unremovable(CGAL::Constrained_triangulation_plus_2& pct, - typename CGAL::Constrained_triangulation_plus_2::Constraint_id cid) -{ - typedef typename CGAL::Constrained_triangulation_plus_2 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 -void -mark_vertices_unremovable(CGAL::Constrained_triangulation_plus_2& pct) -{ - typedef typename CGAL::Constrained_triangulation_plus_2 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 - diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h index ab1a8e1418f..dc3bb6559c9 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h @@ -20,6 +20,8 @@ #ifndef CGAL_POLYLINE_SIMPLIFICATION_2_SIMPLIFY_H #define CGAL_POLYLINE_SIMPLIFICATION_2_SIMPLIFY_H +#include + #include #include #include @@ -27,12 +29,8 @@ #include #include #include -#include #include -#include - -#include - +#include // Needed for Polygon_2 #include @@ -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 dist = cost(pct, u, it, w); + if((*it)->is_removable()){ + boost::optional dist = cost(pct, it); if(dist){ - (*it)->cost() = *dist; + (*it)->set_cost(*dist); (*mpq).push(it); ++n; } else { - (*it)->cost() = (std::numeric_limits::max)(); + (*it)->set_cost((std::numeric_limits::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 dist = cost(pct, uu,u,w); + boost::optional 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 dist = cost(pct, u,w,ww); + boost::optional 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 +template std::size_t -simplify(CGAL::Constrained_triangulation_plus_2& ct, - typename CGAL::Constrained_triangulation_plus_2::Constraint_id cid, +simplify(CGAL::Constrained_triangulation_plus_2& ct, + typename CGAL::Constrained_triangulation_plus_2::Constraint_id cid, CostFunction cost, StopFunction stop, bool keep_points = false) { - typedef CGAL::Constrained_triangulation_plus_2 PCT; + typedef CGAL::Constrained_triangulation_plus_2 PCT; Polyline_simplification_2 simplifier(ct, cid, cost, stop); while(simplifier()){} @@ -437,20 +432,20 @@ simplify(CGAL::Constrained_triangulation_plus_2& 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 +template std::size_t -simplify(CGAL::Constrained_triangulation_plus_2& ct, +simplify(CGAL::Constrained_triangulation_plus_2& ct, CostFunction cost, StopFunction stop, bool keep_points = false) { - typedef CGAL::Constrained_triangulation_plus_2 PCT; + typedef CGAL::Constrained_triangulation_plus_2 PCT; Polyline_simplification_2 simplifier(ct, cost, stop); while(simplifier()){} diff --git a/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h b/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h index 889a3cca12f..7ac80dd5295 100644 --- a/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h +++ b/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h @@ -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 diff --git a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt index 6659a689faa..f3795162ed4 100644 --- a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt +++ b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt @@ -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, int> Edge`. +For a pair `(fh,i)` it is the edge of the face `*fh`,which is opposite to the `i`'th vertex. + +A constrained edge `e` as an edge of a constrained triangulation `ct`, for which `ct.is_constrained(e) == true`. + +A constraint 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 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` 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` -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, int> Edge`. For a pair `(fh,i)` it is the edge of the face `*fh`, -which is opposite to the `i`'th vertex. - -A constrained edge `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 constraint 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 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 diff --git a/Triangulation_2/doc/Triangulation_2/fig/CDTplusAvoidCascading.png b/Triangulation_2/doc/Triangulation_2/fig/CDTplusAvoidCascading.png new file mode 100755 index 00000000000..afbfcdbcaf2 Binary files /dev/null and b/Triangulation_2/doc/Triangulation_2/fig/CDTplusAvoidCascading.png differ diff --git a/Triangulation_2/include/CGAL/Polyline_constrained_triangulation_2.h b/Triangulation_2/include/CGAL/Polyline_constrained_triangulation_2.h index ae99fea1812..c73e7dcf86f 100644 --- a/Triangulation_2/include/CGAL/Polyline_constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Polyline_constrained_triangulation_2.h @@ -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);