chrobak_payne_drawing.hpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. //=======================================================================
  2. // Copyright (c) Aaron Windsor 2007
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //=======================================================================
  8. #ifndef __CHROBAK_PAYNE_DRAWING_HPP__
  9. #define __CHROBAK_PAYNE_DRAWING_HPP__
  10. #include <vector>
  11. #include <list>
  12. #include <stack>
  13. #include <boost/config.hpp>
  14. #include <boost/graph/graph_traits.hpp>
  15. #include <boost/graph/properties.hpp>
  16. #include <boost/property_map/property_map.hpp>
  17. namespace boost
  18. {
  19. namespace graph
  20. {
  21. namespace detail
  22. {
  23. template < typename Graph, typename VertexToVertexMap,
  24. typename VertexTo1DCoordMap >
  25. void accumulate_offsets(
  26. typename graph_traits< Graph >::vertex_descriptor v,
  27. std::size_t offset, const Graph& g, VertexTo1DCoordMap x,
  28. VertexTo1DCoordMap delta_x, VertexToVertexMap left,
  29. VertexToVertexMap right)
  30. {
  31. typedef typename graph_traits< Graph >::vertex_descriptor
  32. vertex_descriptor;
  33. // Suggestion of explicit stack from Aaron Windsor to avoid system
  34. // stack overflows.
  35. typedef std::pair< vertex_descriptor, std::size_t > stack_entry;
  36. std::stack< stack_entry > st;
  37. st.push(stack_entry(v, offset));
  38. while (!st.empty())
  39. {
  40. vertex_descriptor v = st.top().first;
  41. std::size_t offset = st.top().second;
  42. st.pop();
  43. if (v != graph_traits< Graph >::null_vertex())
  44. {
  45. x[v] += delta_x[v] + offset;
  46. st.push(stack_entry(left[v], x[v]));
  47. st.push(stack_entry(right[v], x[v]));
  48. }
  49. }
  50. }
  51. } /*namespace detail*/
  52. } /*namespace graph*/
  53. template < typename Graph, typename PlanarEmbedding, typename ForwardIterator,
  54. typename GridPositionMap, typename VertexIndexMap >
  55. void chrobak_payne_straight_line_drawing(const Graph& g,
  56. PlanarEmbedding embedding, ForwardIterator ordering_begin,
  57. ForwardIterator ordering_end, GridPositionMap drawing, VertexIndexMap vm)
  58. {
  59. typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
  60. typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
  61. typedef typename PlanarEmbedding::value_type::const_iterator
  62. edge_permutation_iterator_t;
  63. typedef typename graph_traits< Graph >::vertices_size_type v_size_t;
  64. typedef std::vector< vertex_t > vertex_vector_t;
  65. typedef std::vector< v_size_t > vsize_vector_t;
  66. typedef std::vector< bool > bool_vector_t;
  67. typedef boost::iterator_property_map< typename vertex_vector_t::iterator,
  68. VertexIndexMap >
  69. vertex_to_vertex_map_t;
  70. typedef boost::iterator_property_map< typename vsize_vector_t::iterator,
  71. VertexIndexMap >
  72. vertex_to_vsize_map_t;
  73. typedef boost::iterator_property_map< typename bool_vector_t::iterator,
  74. VertexIndexMap >
  75. vertex_to_bool_map_t;
  76. vertex_vector_t left_vector(
  77. num_vertices(g), graph_traits< Graph >::null_vertex());
  78. vertex_vector_t right_vector(
  79. num_vertices(g), graph_traits< Graph >::null_vertex());
  80. vsize_vector_t seen_as_right_vector(num_vertices(g), 0);
  81. vsize_vector_t seen_vector(num_vertices(g), 0);
  82. vsize_vector_t delta_x_vector(num_vertices(g), 0);
  83. vsize_vector_t y_vector(num_vertices(g));
  84. vsize_vector_t x_vector(num_vertices(g), 0);
  85. bool_vector_t installed_vector(num_vertices(g), false);
  86. vertex_to_vertex_map_t left(left_vector.begin(), vm);
  87. vertex_to_vertex_map_t right(right_vector.begin(), vm);
  88. vertex_to_vsize_map_t seen_as_right(seen_as_right_vector.begin(), vm);
  89. vertex_to_vsize_map_t seen(seen_vector.begin(), vm);
  90. vertex_to_vsize_map_t delta_x(delta_x_vector.begin(), vm);
  91. vertex_to_vsize_map_t y(y_vector.begin(), vm);
  92. vertex_to_vsize_map_t x(x_vector.begin(), vm);
  93. vertex_to_bool_map_t installed(installed_vector.begin(), vm);
  94. v_size_t timestamp = 1;
  95. vertex_vector_t installed_neighbors;
  96. ForwardIterator itr = ordering_begin;
  97. vertex_t v1 = *itr;
  98. ++itr;
  99. vertex_t v2 = *itr;
  100. ++itr;
  101. vertex_t v3 = *itr;
  102. ++itr;
  103. delta_x[v2] = 1;
  104. delta_x[v3] = 1;
  105. y[v1] = 0;
  106. y[v2] = 0;
  107. y[v3] = 1;
  108. right[v1] = v3;
  109. right[v3] = v2;
  110. installed[v1] = installed[v2] = installed[v3] = true;
  111. for (ForwardIterator itr_end = ordering_end; itr != itr_end; ++itr)
  112. {
  113. vertex_t v = *itr;
  114. // First, find the leftmost and rightmost neighbor of v on the outer
  115. // cycle of the embedding.
  116. // Note: since we're moving clockwise through the edges adjacent to v,
  117. // we're actually moving from right to left among v's neighbors on the
  118. // outer face (since v will be installed above them all) looking for
  119. // the leftmost and rightmost installed neigbhors
  120. vertex_t leftmost = graph_traits< Graph >::null_vertex();
  121. vertex_t rightmost = graph_traits< Graph >::null_vertex();
  122. installed_neighbors.clear();
  123. vertex_t prev_vertex = graph_traits< Graph >::null_vertex();
  124. edge_permutation_iterator_t pi, pi_end;
  125. pi_end = embedding[v].end();
  126. for (pi = embedding[v].begin(); pi != pi_end; ++pi)
  127. {
  128. vertex_t curr_vertex
  129. = source(*pi, g) == v ? target(*pi, g) : source(*pi, g);
  130. // Skip any self-loops or parallel edges
  131. if (curr_vertex == v || curr_vertex == prev_vertex)
  132. continue;
  133. if (installed[curr_vertex])
  134. {
  135. seen[curr_vertex] = timestamp;
  136. if (right[curr_vertex] != graph_traits< Graph >::null_vertex())
  137. {
  138. seen_as_right[right[curr_vertex]] = timestamp;
  139. }
  140. installed_neighbors.push_back(curr_vertex);
  141. }
  142. prev_vertex = curr_vertex;
  143. }
  144. typename vertex_vector_t::iterator vi, vi_end;
  145. vi_end = installed_neighbors.end();
  146. for (vi = installed_neighbors.begin(); vi != vi_end; ++vi)
  147. {
  148. if (right[*vi] == graph_traits< Graph >::null_vertex()
  149. || seen[right[*vi]] != timestamp)
  150. rightmost = *vi;
  151. if (seen_as_right[*vi] != timestamp)
  152. leftmost = *vi;
  153. }
  154. ++timestamp;
  155. // stretch gaps
  156. ++delta_x[right[leftmost]];
  157. ++delta_x[rightmost];
  158. // adjust offsets
  159. std::size_t delta_p_q = 0;
  160. vertex_t stopping_vertex = right[rightmost];
  161. for (vertex_t temp = right[leftmost]; temp != stopping_vertex;
  162. temp = right[temp])
  163. {
  164. delta_p_q += delta_x[temp];
  165. }
  166. delta_x[v] = ((y[rightmost] + delta_p_q) - y[leftmost]) / 2;
  167. y[v] = y[leftmost] + delta_x[v];
  168. delta_x[rightmost] = delta_p_q - delta_x[v];
  169. bool leftmost_and_rightmost_adjacent = right[leftmost] == rightmost;
  170. if (!leftmost_and_rightmost_adjacent)
  171. delta_x[right[leftmost]] -= delta_x[v];
  172. // install v
  173. if (!leftmost_and_rightmost_adjacent)
  174. {
  175. left[v] = right[leftmost];
  176. vertex_t next_to_rightmost;
  177. for (vertex_t temp = leftmost; temp != rightmost;
  178. temp = right[temp])
  179. {
  180. next_to_rightmost = temp;
  181. }
  182. right[next_to_rightmost] = graph_traits< Graph >::null_vertex();
  183. }
  184. else
  185. {
  186. left[v] = graph_traits< Graph >::null_vertex();
  187. }
  188. right[leftmost] = v;
  189. right[v] = rightmost;
  190. installed[v] = true;
  191. }
  192. graph::detail::accumulate_offsets(
  193. *ordering_begin, 0, g, x, delta_x, left, right);
  194. vertex_iterator_t vi, vi_end;
  195. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  196. {
  197. vertex_t v(*vi);
  198. drawing[v].x = x[v];
  199. drawing[v].y = y[v];
  200. }
  201. }
  202. template < typename Graph, typename PlanarEmbedding, typename ForwardIterator,
  203. typename GridPositionMap >
  204. inline void chrobak_payne_straight_line_drawing(const Graph& g,
  205. PlanarEmbedding embedding, ForwardIterator ord_begin,
  206. ForwardIterator ord_end, GridPositionMap drawing)
  207. {
  208. chrobak_payne_straight_line_drawing(
  209. g, embedding, ord_begin, ord_end, drawing, get(vertex_index, g));
  210. }
  211. } // namespace boost
  212. #endif //__CHROBAK_PAYNE_DRAWING_HPP__