Files
cgal/BGL/examples/BGL_arrangement_2/primal.cpp
T
Mael Rouxel-Labbé 590ddf8015 Various fixes for pmaps:
- Use `value_type` when the returned type is not a reference
- Enforce `reference = value_type` if the returned type is not
  a reference (to avoid `typename PM::reference r = get(m, k)`,
  which will take a ref to a temporary if the `reference`
  typedef is an actualy reference)
- Do not use `put_get_helper` if the property map is not a `lvalue`
  **mutable** property map: the `put()` is `map[k] = v`, which
  is broken if `operator[]` does not return a reference
- The concept `boost::lvalue_property_map_tag` requires `operator[](key)`,
  not a reference in `get(map, key)`. You can have a readable property map
  returning a reference through its `get(map, key)`, but if there is
  no `operator[]`, it's just a `boost::readable_property_map_tag`
- Some const correctness to avoid copying maps with state
  or heavy keys in `get(map, key)` / `put(map, key, value)`
- Base the category of a wrapping pmap on what it offers instead
  of just forwarding the base property map's category
- Tried to do something like mutable lvalue pmap:
  * `value_type& operator[](key&)`
  * `ref get(map, const key&)`
  * `put(map, const key&, const value_type&)`
  and non-mutable lvalue pmap:
  * `const value_type& operator[](const key&)`
  * `ref get(map, const key&)`
  but not everything fits properly...
2021-10-08 15:38:47 +02:00

90 lines
3.4 KiB
C++

//! \file examples/Arrangement_on_surface_2/bgl_primal_adapter.cpp
// Adapting an arrangement to a BGL graph.
#include "arr_rational_nt.h"
#include <CGAL/Cartesian.h>
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/graph_traits_Arrangement_2.h>
#include <CGAL/Arr_vertex_index_map.h>
#include <CGAL/boost/graph/dijkstra_shortest_paths.h>
#include <CGAL/property_map.h>
typedef CGAL::Cartesian<Number_type> Kernel;
typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
typedef Traits_2::Point_2 Point_2;
typedef Traits_2::X_monotone_curve_2 Segment_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
// A functor used to compute the length of an edge.
class Edge_length_func
{
public:
// Boost property type definitions:
typedef boost::readable_property_map_tag category;
typedef double value_type;
typedef value_type reference;
typedef Arrangement_2::Halfedge_handle key_type;
double operator()(Arrangement_2::Halfedge_handle e) const
{
const double x1 = CGAL::to_double (e->source()->point().x());
const double y1 = CGAL::to_double (e->source()->point().y());
const double x2 = CGAL::to_double (e->target()->point().x());
const double y2 = CGAL::to_double (e->target()->point().y());
const double diff_x = x2 - x1;
const double diff_y = y2 - y1;
return std::sqrt(diff_x*diff_x + diff_y*diff_y);
}
};
double get(const Edge_length_func& edge_length, Arrangement_2::Halfedge_handle e)
{
return edge_length(e);
}
int main()
{
Arrangement_2 arr;
// Construct an arrangement of seven intersecting line segments.
// We keep a handle for the vertex v_0 that corresponds to the point (1,1).
Arrangement_2::Halfedge_handle e =
insert_non_intersecting_curve (arr, Segment_2 (Point_2 (1, 1),
Point_2 (7, 1)));
Arrangement_2::Vertex_handle v0 = e->source();
insert (arr, Segment_2 (Point_2 (1, 1), Point_2 (3, 7)));
insert (arr, Segment_2 (Point_2 (1, 4), Point_2 (7, 1)));
insert (arr, Segment_2 (Point_2 (2, 2), Point_2 (9, 3)));
insert (arr, Segment_2 (Point_2 (2, 2), Point_2 (4, 4)));
insert (arr, Segment_2 (Point_2 (7, 1), Point_2 (9, 3)));
insert (arr, Segment_2 (Point_2 (3, 7), Point_2 (9, 3)));
// Create a mapping of the arrangement vertices to indices.
CGAL::Arr_vertex_index_map<Arrangement_2> index_map(arr);
// Perform Dijkstra's algorithm from the vertex v0.
Edge_length_func edge_length;
boost::vector_property_map<double, CGAL::Arr_vertex_index_map<Arrangement_2> > dist_map(static_cast<unsigned int>(arr.number_of_vertices()), index_map);
boost::dijkstra_shortest_paths(arr, v0,
boost::vertex_index_map(index_map).
weight_map(edge_length).
distance_map(dist_map));
// Print the results:
Arrangement_2::Vertex_iterator vit;
std::cout << "The distances of the arrangement vertices from ("
<< v0->point() << ") :" << std::endl;
for (vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit)
std::cout << "(" << vit->point() << ") at distance "
<< dist_map[vit] << std::endl;
return 0;
}