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
CollinearTriple.h
Go to the documentation of this file.
1
31#pragma once
32
33#ifdef OGDF_INCLUDE_CGAL
34
38
39# include <vector>
40
41namespace ogdf {
42namespace internal {
43namespace gcm {
44namespace geometry {
45
46template<typename Kernel>
47bool has_collinear_pair(const std::vector<Point_t<Kernel>>& points, const unsigned int v) {
48 std::vector<typename Kernel::FT> angles;
49 geometry::Vector_t<Kernel> x(1, 0);
50 auto p_v = points[v];
51 for (unsigned int w = 0; w < points.size(); w++) {
52 if (w != v) {
53 auto p_w = points[w];
54 if (p_w == p_v) {
55 return true;
56 }
57 for (unsigned int u = w + 1; u < points.size(); u++) {
58 if (u != v) {
59 auto p_u = points[u];
60 if (CGAL::collinear(p_u, p_v, p_w) || p_u == p_v) {
61 return true;
62 }
63 }
64 }
65 }
66 }
67 return false;
68}
69
70template<typename Kernel, typename Graph>
71bool has_collinear_pair(const graph::GeometricDrawing<Kernel, Graph>& d,
72 const typename Graph::Node v) {
73 std::vector<typename Kernel::FT> angles;
74 geometry::Vector_t<Kernel> x(1, 0);
75 auto p_v = d.get_point(v);
76 for (auto w : d.get_graph().nodes()) {
77 if (w != v) {
78 auto p_w = d.get_point(w);
79 if (p_w == p_v) {
80 return true;
81 }
82 for (auto u : d.get_graph().nodes()) {
83 if (u != v && u != w) {
84 auto p_u = d.get_point(u);
85 if (CGAL::collinear(p_u, p_v, p_w) || p_u == p_v) {
86 return true;
87 }
88 }
89 }
90 }
91 }
92 return false;
93}
94
95template<typename Kernel, typename Graph>
96bool has_collinear_triple(const graph::GeometricDrawing<Kernel, Graph>& d) {
97 for (auto v : d.get_graph().nodes()) {
98 if (has_collinear_pair(d, v)) {
99 return true;
100 }
101 }
102 return false;
103}
104
105template<typename Kernel>
106bool has_collinear_triple(const std::vector<Point_t<Kernel>>& points) {
107 for (unsigned int v = 0; v < points.size(); ++v) {
108 if (has_collinear_pair(points, v)) {
109 return true;
110 }
111 }
112 return false;
113}
114
115template<typename Kernel>
116void resolve_collinearity(std::vector<Point_t<Kernel>>& points) {
117 if (!geometry::has_collinear_triple(points)) {
118 return;
119 }
120
121 std::mt19937_64 gen(ogdf::randomSeed());
122
123 std::uniform_real_distribution<double> distr(-1, 1);
124
125 for (unsigned int v = 0; v < points.size(); ++v) {
126 bool col = geometry::has_collinear_pair(points, v);
127 while (col) {
128 auto prev = points[v];
129 auto x = prev.x() + distr(gen);
130 auto y = prev.y() + distr(gen);
131 points[v] = Point_t<Kernel>(x, y);
132 col = geometry::has_collinear_pair(points, v);
133 if (col) {
134 points[v] = prev;
135 }
136 }
137 if (col) {
138 break;
139 }
140 }
141}
142
143}
144}
145}
146}
147
148#endif
long unsigned int randomSeed()
Returns a random value suitable as initial seed for a random number engine.
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.