diff DEPENDENCIES/generic/include/boost/graph/chrobak_payne_drawing.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/graph/chrobak_payne_drawing.hpp	Tue Aug 05 11:11:38 2014 +0100
@@ -0,0 +1,279 @@
+//=======================================================================
+// Copyright (c) Aaron Windsor 2007
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef __CHROBAK_PAYNE_DRAWING_HPP__
+#define __CHROBAK_PAYNE_DRAWING_HPP__
+
+#include <vector>
+#include <list>
+#include <stack>
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/property_map/property_map.hpp>
+
+
+namespace boost
+{
+
+  namespace graph { namespace detail
+  {
+
+    template<typename Graph, 
+             typename VertexToVertexMap, 
+             typename VertexTo1DCoordMap>
+    void accumulate_offsets(typename graph_traits<Graph>::vertex_descriptor v,
+                            std::size_t offset,
+                            const Graph& g,
+                            VertexTo1DCoordMap x,
+                            VertexTo1DCoordMap delta_x,
+                            VertexToVertexMap left,
+                            VertexToVertexMap right)
+    {
+      typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
+      // Suggestion of explicit stack from Aaron Windsor to avoid system stack
+      // overflows.
+      typedef std::pair<vertex_descriptor, std::size_t> stack_entry;
+      std::stack<stack_entry> st;
+      st.push(stack_entry(v, offset));
+      while (!st.empty()) {
+        vertex_descriptor v = st.top().first;
+        std::size_t offset = st.top().second;
+        st.pop();
+        if (v != graph_traits<Graph>::null_vertex()) {
+          x[v] += delta_x[v] + offset;
+          st.push(stack_entry(left[v], x[v]));
+          st.push(stack_entry(right[v], x[v]));
+        }
+      }
+    }
+
+  } /*namespace detail*/ } /*namespace graph*/
+
+
+
+
+
+  template<typename Graph, 
+           typename PlanarEmbedding, 
+           typename ForwardIterator, 
+           typename GridPositionMap,
+           typename VertexIndexMap>
+  void chrobak_payne_straight_line_drawing(const Graph& g, 
+                                           PlanarEmbedding embedding, 
+                                           ForwardIterator ordering_begin,
+                                           ForwardIterator ordering_end,
+                                           GridPositionMap drawing,
+                                           VertexIndexMap vm
+                                           )
+  {
+
+    typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+    typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
+    typedef typename PlanarEmbedding::value_type::const_iterator 
+      edge_permutation_iterator_t;
+    typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
+    typedef std::vector<vertex_t> vertex_vector_t;
+    typedef std::vector<v_size_t> vsize_vector_t;
+    typedef std::vector<bool> bool_vector_t;
+    typedef boost::iterator_property_map
+      <typename vertex_vector_t::iterator, VertexIndexMap> 
+      vertex_to_vertex_map_t;
+    typedef boost::iterator_property_map
+      <typename vsize_vector_t::iterator, VertexIndexMap> 
+      vertex_to_vsize_map_t;
+    typedef boost::iterator_property_map
+      <typename bool_vector_t::iterator, VertexIndexMap> 
+      vertex_to_bool_map_t;
+
+    vertex_vector_t left_vector(num_vertices(g), 
+                                graph_traits<Graph>::null_vertex()
+                                );
+    vertex_vector_t right_vector(num_vertices(g), 
+                                 graph_traits<Graph>::null_vertex()
+                                 );
+    vsize_vector_t seen_as_right_vector(num_vertices(g), 0);
+    vsize_vector_t seen_vector(num_vertices(g), 0);
+    vsize_vector_t delta_x_vector(num_vertices(g),0);
+    vsize_vector_t y_vector(num_vertices(g));
+    vsize_vector_t x_vector(num_vertices(g),0);
+    bool_vector_t installed_vector(num_vertices(g),false);
+
+    vertex_to_vertex_map_t left(left_vector.begin(), vm);
+    vertex_to_vertex_map_t right(right_vector.begin(), vm);
+    vertex_to_vsize_map_t seen_as_right(seen_as_right_vector.begin(), vm);
+    vertex_to_vsize_map_t seen(seen_vector.begin(), vm);
+    vertex_to_vsize_map_t delta_x(delta_x_vector.begin(), vm);
+    vertex_to_vsize_map_t y(y_vector.begin(), vm);
+    vertex_to_vsize_map_t x(x_vector.begin(), vm);
+    vertex_to_bool_map_t installed(installed_vector.begin(), vm);
+
+    v_size_t timestamp = 1;
+    vertex_vector_t installed_neighbors;
+
+    ForwardIterator itr = ordering_begin;
+    vertex_t v1 = *itr; ++itr;
+    vertex_t v2 = *itr; ++itr;
+    vertex_t v3 = *itr; ++itr;
+
+    delta_x[v2] = 1; 
+    delta_x[v3] = 1;
+    
+    y[v1] = 0;
+    y[v2] = 0;
+    y[v3] = 1;
+
+    right[v1] = v3;
+    right[v3] = v2;
+
+    installed[v1] = installed[v2] = installed[v3] = true;
+
+    for(ForwardIterator itr_end = ordering_end; itr != itr_end; ++itr)
+      {
+        vertex_t v = *itr;
+
+        // First, find the leftmost and rightmost neighbor of v on the outer 
+        // cycle of the embedding. 
+        // Note: since we're moving clockwise through the edges adjacent to v, 
+        // we're actually moving from right to left among v's neighbors on the
+        // outer face (since v will be installed above them all) looking for 
+        // the leftmost and rightmost installed neigbhors
+
+        vertex_t leftmost = graph_traits<Graph>::null_vertex();
+        vertex_t rightmost = graph_traits<Graph>::null_vertex();
+
+        installed_neighbors.clear();
+
+        vertex_t prev_vertex = graph_traits<Graph>::null_vertex();
+        edge_permutation_iterator_t pi, pi_end;
+        pi_end = embedding[v].end();
+        for(pi = embedding[v].begin(); pi != pi_end; ++pi)
+          {
+            vertex_t curr_vertex = source(*pi,g) == v ? 
+              target(*pi,g) : source(*pi,g);
+            
+            // Skip any self-loops or parallel edges
+            if (curr_vertex == v || curr_vertex == prev_vertex)
+                continue;
+
+            if (installed[curr_vertex])
+              {
+                seen[curr_vertex] = timestamp;
+
+                if (right[curr_vertex] != graph_traits<Graph>::null_vertex())
+                  {
+                    seen_as_right[right[curr_vertex]] = timestamp;
+                  }
+                installed_neighbors.push_back(curr_vertex);
+              }
+
+            prev_vertex = curr_vertex;
+          }
+
+        typename vertex_vector_t::iterator vi, vi_end;
+        vi_end = installed_neighbors.end();
+        for(vi = installed_neighbors.begin(); vi != vi_end; ++vi)
+          {
+            if (right[*vi] == graph_traits<Graph>::null_vertex() || 
+                seen[right[*vi]] != timestamp
+                )
+              rightmost = *vi;
+            if (seen_as_right[*vi] != timestamp)
+              leftmost = *vi;
+          }
+
+        ++timestamp;
+
+        //stretch gaps
+        ++delta_x[right[leftmost]];
+        ++delta_x[rightmost];
+
+        //adjust offsets
+        std::size_t delta_p_q = 0;
+        vertex_t stopping_vertex = right[rightmost];
+        for(vertex_t temp = right[leftmost]; temp != stopping_vertex; 
+            temp = right[temp]
+            )
+          {
+            delta_p_q += delta_x[temp];
+          }
+
+        delta_x[v] = ((y[rightmost] + delta_p_q) - y[leftmost])/2;
+        y[v] = y[leftmost] + delta_x[v];
+        delta_x[rightmost] = delta_p_q - delta_x[v];
+        
+        bool leftmost_and_rightmost_adjacent = right[leftmost] == rightmost;
+        if (!leftmost_and_rightmost_adjacent)
+          delta_x[right[leftmost]] -= delta_x[v];
+
+        //install v
+        if (!leftmost_and_rightmost_adjacent)
+          {
+            left[v] = right[leftmost];
+            vertex_t next_to_rightmost;
+            for(vertex_t temp = leftmost; temp != rightmost; 
+                temp = right[temp]
+                )
+              {
+                next_to_rightmost = temp;
+              }
+
+            right[next_to_rightmost] = graph_traits<Graph>::null_vertex();
+          }
+        else
+          {
+            left[v] = graph_traits<Graph>::null_vertex();
+          }
+
+        right[leftmost] = v;
+        right[v] = rightmost;
+        installed[v] = true;
+
+      }
+
+    graph::detail::accumulate_offsets
+      (*ordering_begin,0,g,x,delta_x,left,right);
+
+    vertex_iterator_t vi, vi_end;
+    for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+      {
+        vertex_t v(*vi);
+        drawing[v].x = x[v];
+        drawing[v].y = y[v];
+      }
+
+  }
+
+
+
+
+  template<typename Graph, 
+           typename PlanarEmbedding, 
+           typename ForwardIterator, 
+           typename GridPositionMap>
+  inline void chrobak_payne_straight_line_drawing(const Graph& g, 
+                                                  PlanarEmbedding embedding, 
+                                                  ForwardIterator ord_begin,
+                                                  ForwardIterator ord_end,
+                                                  GridPositionMap drawing
+                                                  )
+  {
+    chrobak_payne_straight_line_drawing(g, 
+                                        embedding, 
+                                        ord_begin, 
+                                        ord_end, 
+                                        drawing, 
+                                        get(vertex_index,g)
+                                        );
+  }
+
+
+  
+
+} // namespace boost
+
+#endif //__CHROBAK_PAYNE_DRAWING_HPP__