Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

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 
41 namespace ogdf {
42 namespace internal {
43 namespace gcm {
44 namespace geometry {
45 
46 template<typename Kernel>
47 bool 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 
70 template<typename Kernel, typename Graph>
71 bool 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 
95 template<typename Kernel, typename Graph>
96 bool 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 
105 template<typename Kernel>
106 bool 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 
115 template<typename Kernel>
116 void 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
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
Point.h
Vector.h
ogdf::randomSeed
long unsigned int randomSeed()
Returns a random value suitable as initial seed for a random number engine.
GeometricDrawing.h