33 #ifdef OGDF_INCLUDE_CGAL
45 template<
typename Kernel>
46 class RandomPointsInCell {
48 using BD = BloatedDualGraph<Kernel>;
50 using Point = geometry::Point_t<Kernel>;
51 using Segment = geometry::LineSegment_t<Kernel>;
52 using Polygon = geometry::Polygon_t<Kernel>;
54 static std::vector<int> vertex_weights(
const BD& bd,
const Point& p,
55 const std::vector<int>& left_to_right_cost, std::vector<bool>& visited,
56 datastructure::UnionFind& uf) {
57 typename BD::Node min_node = bd.segm_to_node_range[left_to_right_cost.size() - 4];
59 auto rep = geometry::find_representative_node(bd, p);
65 std::vector<typename BD::Node> parent(bd.number_of_nodes());
66 std::vector<typename BD::Edge> parent_edge(bd.number_of_nodes());
68 auto f_weight = [&](
typename BD::Node v,
typename BD::Edge e) {
69 if (bd.is_face_edge(e) || bd.degree(v) == 2) {
71 }
else if (bd.is_left(v)) {
72 return left_to_right_cost[bd.node_to_segment[v]];
74 return -left_to_right_cost[bd.node_to_segment[v]];
78 auto expand = [&](
typename BD::Node w,
typename BD::Edge e) {
79 bool bad_edge = w >= min_node && bd.edges[e] >= min_node;
85 std::vector<typename BD::Node> queue;
86 std::vector<int> weight(bd.number_of_nodes(), 0);
93 auto handle_edge = [&](
typename BD::Node v,
typename BD::Edge e) {
94 typename BD::Node w = bd.edges[e];
95 OGDF_ASSERT(!visited[w] || v == w || weight[w] == weight[v] + f_weight(v, e));
97 if (!visited[w] && expand(v, e) && v != w) {
98 weight[w] = weight[v] + f_weight(v, e);
103 if (bd.is_face_edge(e)) {
109 while (!queue.empty()) {
110 typename BD::Node current = queue.back();
112 min_weight = std::min(min_weight, weight[current]);
113 max_weight = std::max(max_weight, weight[current]);
115 handle_edge(current, 3 * current);
116 handle_edge(current, 3 * current + 1);
117 handle_edge(current, 3 * current + 2);
120 for (
auto& w : weight) {
121 w = max_weight - w + 1;
128 static std::vector<Point> compute(
const BD& bd,
const std::vector<int>& left_to_right_cost,
129 const Point& reference,
unsigned int nof_points, std::mt19937_64& gen) {
130 datastructure::UnionFind uf(bd.number_of_nodes());
131 uf.all_to_singletons();
133 std::vector<bool> visited(bd.number_of_nodes(),
false);
134 std::vector<int> weights = vertex_weights(bd, reference, left_to_right_cost, visited, uf);
136 std::vector<unsigned int> repr;
137 for (
unsigned int u = 0; u < bd.number_of_nodes(); ++u) {
138 if (uf.find(u) == u && visited[u]) {
144 std::vector<double> repr_weights(repr.size(), 0);
145 std::vector<unsigned int> interval;
147 for (
unsigned int i = 0; i < repr.size(); ++i) {
148 repr_weights[i] = std::pow(2, weights[repr[i]]);
150 interval.push_back(i);
153 interval.push_back(repr.size());
155 std::piecewise_constant_distribution<double> dist(interval.begin(), interval.end(),
156 repr_weights.begin());
158 std::vector<Point> point_set;
160 for (
unsigned int r = 0;
r < nof_points; ++
r) {
162 unsigned int v_id = std::floor(dist(gen));
164 unsigned int v = repr[v_id];
167 auto seq = geometry::extract_cell(bd, v);
168 auto region = geometry::extract_polygon(bd.segments, seq);
169 if (CGAL::abs(region.area()) > 1e-5) {
170 auto p = geometry::random_point_in_polygon(region, gen);
171 point_set.push_back(p);