33 #ifdef OGDF_INCLUDE_CGAL
48 template<
typename Kernel>
49 typename graph::BloatedDualGraph<Kernel>::Edge forward(
50 const typename graph::BloatedDualGraph<Kernel>::Node prev,
51 const typename graph::BloatedDualGraph<Kernel>::Node cur,
52 const typename graph::BloatedDualGraph<Kernel>& bd) {
55 auto is_good = [&](
const unsigned int e) {
57 return bd.is_face_edge(e) && bd.edges[e] != prev && bd.edges[e] != cur;
60 using Edge =
typename graph::BloatedDualGraph<Kernel>::Edge;
61 const Edge e_1 = 3 * cur;
62 const Edge e_2 = 3 * cur + 1;
63 const Edge e_3 = 3 * cur + 2;
67 }
else if (is_good(e_2)) {
74 template<
typename Kernel>
75 typename graph::BloatedDualGraph<Kernel>::Edge find_start(
76 const typename graph::BloatedDualGraph<Kernel>::Node cur,
77 const graph::BloatedDualGraph<Kernel>& bd) {
78 using Edge =
typename graph::BloatedDualGraph<Kernel>::Edge;
79 const Edge e_1 = 3 * cur;
80 const Edge e_2 = 3 * cur + 1;
81 const Edge e_3 = 3 * cur + 2;
83 if (bd.is_face_edge(e_1) || bd.degree(cur) == 1) {
85 }
else if (bd.is_face_edge(e_2)) {
100 template<
typename Kernel>
101 std::vector<unsigned int> extract_cell(
const graph::BloatedDualGraph<Kernel>& bd,
102 const typename graph::BloatedDualGraph<Kernel>::Node v) {
103 using Graph = graph::BloatedDualGraph<Kernel>;
104 using Node =
typename Graph::Node;
106 std::vector<unsigned int> segments;
108 auto cur_edge = details::find_start(v, bd);
111 if (bd.degree(v) > 1) {
113 segments.push_back(bd.node_to_segment[v]);
114 Node current = bd.edges[cur_edge];
115 while (current != v) {
116 cur_edge = details::forward(prev, current, bd);
119 segments.push_back(bd.node_to_segment[current]);
121 current = bd.edges[cur_edge];
130 template<
typename Kernel>
131 Polygon_t<Kernel> extract_polygon(
const std::vector<LineSegment_t<Kernel>>& segments,
132 const std::vector<unsigned int>& seq) {
133 Polygon_t<Kernel> poly;
136 for (
unsigned int i = 0; i < seq.size(); ++i) {
138 bool common_endpoint =
false;
139 unsigned int seg_a = seq[i];
141 unsigned int seg_b = -1;
142 if (i + 1 < seq.size()) {
148 for (
unsigned int l = 0; l <= 1; ++l) {
149 for (
unsigned int j = 0; j <= 1; ++j) {
152 if (segments[seg_a].vertex(l) == segments[seg_b].vertex(j)) {
153 p = segments[seg_a].vertex(l);
154 common_endpoint =
true;
159 if (!common_endpoint) {
160 p = geometry::intersect(segments[seg_a], segments[seg_b]);
163 if (poly.is_empty() || *(--poly.vertices_end()) != p) {
168 if (*poly.vertices_begin() == *(--poly.vertices_end())) {
170 poly.erase(--poly.vertices_end());
176 template<
typename Kernel>
177 typename graph::BloatedDualGraph<Kernel>::Node find_representative_node(
178 const graph::BloatedDualGraph<Kernel>& bd,
const Point_t<Kernel>& p) {
179 auto& segments = bd.segments;
180 unsigned int opt = -1;
181 Point_t<Kernel> is_with_r;
182 while (opt > segments.size()) {
186 for (
unsigned i = 0; i < segments.size(); ++i) {
187 if (CGAL::do_intersect(segments[i],
r)) {
188 if (opt > segments.size()) {
190 is_with_r = geometry::intersect(segments[i],
r);
192 auto o = geometry::intersect(segments[i],
r);
193 if (squared_distance(o, p) < squared_distance(is_with_r, p)) {
202 unsigned int opt_is = 0;
203 typename Kernel::FT distance = CGAL::squared_distance(segments[opt].source(), is_with_r);
205 for (
unsigned int i = 0; i < bd.segment_to_intersections[opt].size(); ++i) {
206 auto is = bd.get_intersection_point(bd.segment_to_intersections[opt][i]);
207 if (CGAL::squared_distance(is, is_with_r) < distance) {
208 distance = CGAL::squared_distance(is, is_with_r);
213 typename graph::BloatedDualGraph<Kernel>::Node v;
214 bool left = geometry::left_turn(segments[opt], p);
217 OGDF_ASSERT(!bd.segment_to_intersections[opt].empty());
219 if (CGAL::squared_distance(segments[opt].source(), is_with_r)
220 < CGAL::squared_distance(segments[opt].source(),
221 bd.get_intersection_point(bd.segment_to_intersections[opt][opt_is]))) {
223 v = bd.first_left(opt, bd.segment_to_intersections[opt][opt_is]);
225 v = bd.first_right(opt, bd.segment_to_intersections[opt][opt_is]);
230 v = bd.second_left(opt, bd.segment_to_intersections[opt][opt_is]);
232 v = bd.second_right(opt, bd.segment_to_intersections[opt][opt_is]);