00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #pragma once
00023 #ifndef UTIL_GRAPHUTIL_H
00024 #define UTIL_GRAPHUTIL_H
00025
00026 namespace util
00027 {
00028 template<class Graph>
00029 typename boost::graph_traits<Graph>::out_edge_iterator findEdge (
00030 typename boost::graph_traits<Graph>::vertex_descriptor start,
00031 typename boost::graph_traits<Graph>::vertex_descriptor end,
00032 const Graph& g)
00033 {
00034 typename boost::graph_traits<Graph>::out_edge_iterator eIt, eEnd;
00035 boost::tie (eIt, eEnd) = boost::out_edges (start, g);
00036 for (; !OUT_EDGE_ITERATORS_EQUAL (eIt, eEnd) && boost::target (*eIt, g) != end; ++eIt);
00037 return eIt;
00038 }
00039
00040 template<
00041 class Graph, class Vertex, class Visitor,
00042 class VertexMap, class VertexColorMap, class EdgeColorMap>
00043 void ccwVisit (Graph& g, Vertex u, Visitor vis, VertexMap vmap, VertexColorMap vcmap, EdgeColorMap ecmap)
00044 {
00045 typedef typename boost::property_traits<EdgeColorMap>::value_type ColorValue;
00046 boost::function_requires< boost::ColorValueConcept<ColorValue> >();
00047 typedef boost::color_traits<ColorValue> Color;
00048
00049 vis.start_vertex (u, g);
00050 boost::put (vcmap, u, Color::gray());
00051
00052 boost::graph_traits<Graph>::out_edge_iterator eIt, eEnd;
00053 boost::tie (eIt, eEnd) = boost::out_edges (u, g);
00054 for (; eIt != eEnd && boost::get (ecmap, *eIt) != Color::white(); ++eIt);
00055 if (eIt == eEnd)
00056 return;
00057 Vertex v = boost::target (*eIt, g);
00058
00059
00060 for (;;)
00061 {
00062 boost::put (ecmap, *eIt, Color::black());
00063 boost::put (vcmap, v, Color::gray());
00064 vis.examine_edge (*eIt, g);
00065 const geom::Point2d& pu = boost::get (vmap, u).getLocation();
00066 const geom::Point2d& pv = boost::get (vmap, v).getLocation();
00067
00068
00069 double minAngle = 1e30;
00070 boost::tie (eIt, eEnd) = boost::out_edges (v, g);
00071 boost::graph_traits<Graph>::out_edge_iterator besteIt = eEnd;
00072 for (; eIt != eEnd; ++eIt)
00073 {
00074 if (boost::get (ecmap, *eIt) == Color::white())
00075 {
00076 Vertex w = boost::target (*eIt, g);
00077 const geom::Point2d& pw = boost::get (vmap, w).getLocation();
00078 double turningAngle = w == u ? util::pi : angle (geom::Vec2d (pv-pu), geom::Vec2d (pw-pv));
00079 if (turningAngle < minAngle)
00080 {
00081 minAngle = turningAngle;
00082 besteIt = eIt;
00083 }
00084 }
00085 }
00086 if (besteIt == eEnd)
00087 return;
00088 eIt = besteIt;
00089 u = v;
00090 v = boost::target (*eIt, g);
00091 }
00092 }
00093 }
00094
00095 #endif