Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

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.