Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

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.