Common/Util/GraphAlg.h

Go to the documentation of this file.
00001 //-------------------------------------------------------------------
00004 //  Copyright (c) 2005 Evan Sherbrooke
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License, or (at your option) any later version.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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       // Pick an initial edge
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       // Now follow each edge we can in a CCW way
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          // Look for the sharpest right turn. Right turns are negative, left turns positive
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

Generated on Tue Jan 29 21:37:56 2008 for VoluMill Universal Client by  doxygen 1.4.6