annotate DEPENDENCIES/generic/include/boost/graph/chrobak_payne_drawing.hpp @ 133:4acb5d8d80b6 tip

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