Loading [MathJax]/extensions/tex2jax.js

Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
GeometricDrawing.h
Go to the documentation of this file.
1
31#pragma once
32
33#ifdef OGDF_INCLUDE_CGAL
34
35# include <ogdf/basic/EdgeArray.h>
48
49# include <map>
50# include <tuple>
51# include <vector>
52
53namespace ogdf {
54namespace internal {
55namespace gcm {
56namespace graph {
57
61template<typename Kernel_, typename Graph_>
62class GeometricDrawing : public Drawing<Kernel_, Graph_> {
63public:
64 using Kernel = Kernel_;
65 using Graph = Graph_;
66 using Node = typename Graph::Node;
67 using Edge = typename Graph::Edge;
68
69 using Point = geometry::Point_t<Kernel>;
70 using LineSegment = geometry::LineSegment_t<Kernel>;
71
72private:
73 Graph& g;
74
75 using PointToNodeMap = std::map<Point, Node>;
76 using PointToNodeMapIterator = typename PointToNodeMap::iterator;
77
78 std::vector<Edge> visited_edges;
79
81
82 datastructure::NodeVector<Point, Graph> node_to_point;
83
85 bool outer_face_initialized {false};
86
87public:
88 explicit GeometricDrawing(Graph& _g) : Drawing<Kernel_, Graph>(_g), g(_g), node_to_point(g) {
89 /*nothing to do*/
90 }
91
92 inline void set_outer_face(OGDFFaceWrapper ef) {
95 }
96
97 inline OGDFFaceWrapper& outer_face() {
99 return m_outer_face;
100 }
101
102 inline const OGDFFaceWrapper& outer_face() const {
104 return m_outer_face;
105 }
106
107 inline void clear() {
108 point_to_node.clear();
109 node_to_point.clear();
111 }
112
113 size_t number_of_points() const { return node_to_point.size(); }
114
115 const std::vector<Point>& points() const { return node_to_point; }
116
117 // does not keep the consitency with add node!
118 inline void set_point(const Node& v, const Point& p) {
119 OGDF_ASSERT((size_t)v->index() <= g.max_node_index());
120 if (g.max_node_index() >= node_to_point.size()) {
121 node_to_point.resize(g.max_node_index() + 1);
122 }
123 node_to_point[v] = p;
124 }
125
126 inline Point get_point(const Node& v) const {
127 OGDF_ASSERT((size_t)v->index() < node_to_point.size());
128 return node_to_point[v];
129 }
130
131 inline Point& operator[](const Node& v) {
132 OGDF_ASSERT((size_t)v->index() < node_to_point.size());
133 return node_to_point[v];
134 }
135
136 inline Point operator[](const Node& v) const { return get_point(v); }
137
138 inline LineSegment get_segment(const Edge& e) const {
139 return {get_point(e->source()), get_point(e->target())};
140 }
141
142 inline geometry::Bbox bbox() const {
143 double xmin = std::numeric_limits<double>::infinity();
144 double ymin = std::numeric_limits<double>::infinity();
145 double xmax = -xmin;
146 double ymax = -ymin;
147
148 geometry::Bbox bb(xmin, ymin, xmax, ymax);
149 for (Node v : g.nodes()) {
150 bb += get_point(v).bbox();
151 }
152 return bb;
153 }
154};
155
156template<typename Kernel, typename Graph, typename EdgeList>
157void generate_graph_from_list(const std::vector<geometry::Point_t<Kernel>>& nodes,
158 const EdgeList& edge_list, std::vector<typename Graph::Edge>& map_edge,
160 using Node = typename Graph::Node;
161 using Edge = typename Graph::Edge;
162 using Point = typename geometry::Point_t<Kernel>;
163
164 std::vector<Node> node_map;
165 std::vector<Point> map;
166 Graph& g = d.get_graph();
167 for (const Point& p : nodes) {
168 node_map.push_back(g.add_node());
169 d.set_point(node_map.back(), p); //TODO check ?
170 }
171 for (const std::tuple<unsigned int, unsigned int, unsigned int>& edge : edge_list) {
172 if (node_map[std::get<0>(edge)] != node_map[std::get<1>(edge)]) {
173 const Edge e = g.add_edge(node_map[std::get<0>(edge)], node_map[std::get<1>(edge)]);
174 map_edge.push_back(e);
175 } else {
176 map_edge.push_back(nullptr);
177 }
178 }
179# ifdef OGDF_DEBUG
180 for (const auto e : map_edge) {
181 OGDF_ASSERT(!e || e->graphOf() == &g.get_ogdf_graph());
182 }
183# endif
184}
185
186template<typename Kernel, typename Graph, typename EdgeList>
187void generate_graph_from_list(std::map<unsigned int, geometry::Point_t<Kernel>>& nodes,
188 const EdgeList& edge_list, std::vector<typename Graph::Edge>& map_edge,
189 std::map<unsigned int, typename Graph::Node>& node_map, GeometricDrawing<Kernel, Graph>& d) {
190 using Edge = typename Graph::Edge;
191
192 Graph& g = d.get_graph();
193 for (const std::tuple<unsigned int, unsigned int, unsigned int>& edge : edge_list) {
194 unsigned int source = std::get<0>(edge);
195 unsigned int target = std::get<1>(edge);
196
197
198 if (node_map.find(source) == node_map.end()) {
199 auto u = g.add_node();
200 d.set_point(u, nodes[source]);
201 node_map.insert(std::make_pair(source, u));
202 }
203 if (node_map.find(target) == node_map.end()) {
204 auto u = g.add_node();
205 d.set_point(u, nodes[target]);
206 node_map.insert(std::make_pair(target, u));
207 }
208 }
209
210 for (const std::tuple<unsigned int, unsigned int, unsigned int>& edge : edge_list) {
211 if (node_map[std::get<0>(edge)] != node_map[std::get<1>(edge)]) {
212 const Edge e = g.add_edge(node_map[std::get<0>(edge)], node_map[std::get<1>(edge)]);
213 OGDF_ASSERT(e != nullptr);
214 map_edge.push_back(e);
215 } else {
216 map_edge.push_back(nullptr);
217 }
218 }
219
220# ifdef OGDF_DEBUG
221 for (const auto e : map_edge) {
222 OGDF_ASSERT(!e || e->graphOf() == &g.get_ogdf_graph());
223 }
224# endif
225}
226
227template<typename Kernel, typename Graph, typename EdgeList>
228void generate_graph_from_list(std::map<unsigned int, geometry::Point_t<Kernel>>& nodes,
229 const EdgeList& edge_list, std::vector<typename Graph::Edge>& map_edge,
231 std::map<unsigned int, typename Graph::Node> node_map;
233}
234
235template<typename Kernel, typename Graph>
236std::tuple<datastructure::NodeVector<typename Graph::Node, Graph>,
237 datastructure::EdgeVector<typename Graph::Edge, Graph>>
239 using Node = typename Graph::Node;
240 using Edge = typename Graph::Edge;
241
242 datastructure::NodeVector<Node, Graph> node_map(original);
243 datastructure::EdgeVector<Edge, Graph> edge_map(original);
244
245 for (auto v : original.nodes()) {
246 node_map[v] = copy.add_node(original.get_point(v));
247 }
248
249 for (auto e : original.edges()) {
250 edge_map[e] = copy.add_edge(node_map[e->source()], node_map[e->target()]);
251 }
252
253 return std::make_tuple(node_map, edge_map);
254}
255
256template<typename Kernel, typename Graph>
257void ogdf_attributes_to_geometric_drawing(const GraphAttributes& ga,
259 OGDF_ASSERT(&d.get_graph().get_ogdf_graph() == &ga.constGraph());
260 for (auto v : d.get_graph().nodes()) {
261 geometry::Point_t<Kernel> p(ga.x(v), ga.y(v));
262 d.set_point(v, p);
263 }
264}
265
266template<typename Kernel, typename Graph>
268 GraphAttributes& ga) {
269 OGDF_ASSERT(&d.get_graph().get_ogdf_graph() == &ga.constGraph());
270 for (auto v : d.get_graph().nodes()) {
271 auto p = d.get_point(v);
272 ga.x(v) = CGAL::to_double(p.x());
273 ga.y(v) = CGAL::to_double(p.y());
274 }
275}
276
277}
278}
279}
280}
281
282#endif
Declaration and implementation of EdgeArray class.
Declaration of class GraphAttributes which extends a Graph by additional attributes.
Declares class GraphIO which provides access to all graph read and write functionality.
Generator for visualizing graphs using the XML-based SVG format.
EdgeElement * edge
The type of edges.
Definition Graph_d.h:68
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:41
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.