Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
CrossingMinimalPositionRnd.h
Go to the documentation of this file.
1
31#pragma once
32
33#ifdef OGDF_INCLUDE_CGAL
34
39
40namespace ogdf {
41namespace internal {
42namespace gcm {
43namespace graph {
44
45template<typename Kernel, typename Graph, typename CRegion = CrossingMinimalRegion<Kernel, Graph>>
47private:
48 using Point = geometry::Point_t<Kernel>;
49 using Segment = geometry::LineSegment_t<Kernel>;
50 using Polygon = geometry::Polygon_t<Kernel>;
51 using Drawing = graph::GeometricDrawing<Kernel, Graph>;
52 using Node = typename Graph::Node;
53 using Edge = typename Graph::Edge;
54
55public:
56 static Point compute(const Drawing& d, const Node& v, const std::vector<Edge>& sample,
57 const unsigned int random_draws, const unsigned int neighbor_threshold,
58 geometry::Rectangle_t<Kernel>& rect_box,
59 bool use_min_region //otherwise select with probability to cr. number
60 ,
61 std::mt19937_64& rnd) {
62 unsigned int dump_a, dump_b;
63
64 std::vector<Node> neighbors;
65 for (Node u : d.get_graph().neighbors(v)) {
66 neighbors.push_back(u);
67 }
68
69 std::shuffle(neighbors.begin(), neighbors.end(), rnd);
70
71 std::vector<Node> current;
72
73
74 Point p = d.get_point(v);
75 auto count = [&](Point p_v) {
76 unsigned int n_cr = 0;
77 for (auto edge : d.get_graph().edges()) {
78 if (!edge->isIncident(v)) {
79 Segment s = d.get_segment(edge);
80 for (auto u : d.get_graph().neighbors(v)) {
81 if (!edge->isIncident(u)) {
82 Segment s_f(p_v, d.get_point(u));
83 n_cr += CGAL::do_intersect(s, s_f);
84 }
85 }
86 }
87 }
88 return n_cr;
89 };
90
91 unsigned int min_cr = count(p);
92
93 for (size_t i = 0; i < neighbors.size(); i = i + neighbor_threshold) {
94 current.clear();
95 std::copy(neighbors.begin() + i,
96 neighbors.begin() + std::min(i + neighbor_threshold, neighbors.size()),
97 std::back_inserter(current));
98 if (use_min_region) {
99 CRegion cr;
100
101 auto region = cr.compute(d, v, current, sample, rect_box, dump_a, dump_b);
102
103 OGDF_ASSERT(!CGAL::is_zero(CGAL::abs(region.area())));
104
105 if (geometry::is_clockwise(region)) {
106 region = geometry::reverse(region);
107 }
108
109 if (region.size() > 2) {
110 for (unsigned int x = 0; x < random_draws; ++x) {
111 Point p_v = geometry::random_point_in_polygon(region, rnd);
112 unsigned int n_cr = count(p_v);
113 if (n_cr < min_cr) {
114 min_cr = n_cr;
115 p = p_v;
116 }
117 }
118 }
119 } else {
120 CRegion cr;
121
122 cr.build_bd(d, v, current, sample, rect_box, dump_a, dump_b);
123
124 auto rnd_points = RandomPointsInCell<Kernel>::compute(cr.bd, cr.left_to_right_cost,
125 d.get_point(v), random_draws, rnd);
126
127 for (auto p_v : rnd_points) {
128 unsigned int n_cr = count(p_v);
129 if (n_cr < min_cr) {
130 min_cr = n_cr;
131 p = p_v;
132 }
133 }
134 }
135 }
136
137 //round
138 OGDF_ASSERT(rect_box.has_on_bounded_side(p));
139 p = Point(CGAL::to_double(p.x()), CGAL::to_double(p.y()));
140 OGDF_ASSERT(rect_box.has_on_bounded_side(p));
141 return p;
142 }
143};
144
145}
146}
147}
148}
149
150#endif
bool isIncident(node v) const
Returns true iff v is incident to the edge.
Definition Graph_d.h:381
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.