33#ifdef OGDF_INCLUDE_CGAL
46# include <CGAL/Min_circle_2.h>
47# include <CGAL/Min_circle_2_traits_2.h>
54template<
typename Kernel,
typename Graph>
57 using Point = geometry::Point_t<Kernel>;
58 using Segment = geometry::LineSegment_t<Kernel>;
59 using Polygon = geometry::Polygon_t<Kernel>;
60 using Drawing = graph::GeometricDrawing<Kernel, Graph>;
62 using Node =
typename Graph::Node;
63 using Edge =
typename Graph::Edge;
68 const geometry::Rectangle_t<Kernel>&
rect) {
70 using FT =
typename Kernel::FT;
71 FT delta_x = (
d.get_point(u).x() -
d.get_point(w).x());
72 FT delta_y = (
d.get_point(u).y() -
d.get_point(w).y());
74 geometry::Ray_t<Kernel>
r(
d.get_point(u), geometry::Vector_t<Kernel>(
delta_x,
delta_y));
76 for (
unsigned int i = 0; i < 4; ++i) {
77 t = std::max(
t, CGAL::to_double(geometry::distance(
rect.vertex(i),
d.get_point(u))));
80 Segment s = {
d.get_point(u),
d.get_point(u) + geometry::normalize(
r.to_vector()) *
t * 1.1};
86 const std::vector<Node>&
neighbors,
const std::vector<Edge>& edges,
BD&
bd,
87 geometry::Rectangle_t<Kernel>&
rect_box
89 const auto& g =
d.get_graph();
91 bd.segments.reserve(g.number_of_nodes() * v->degree() + edges.size());
96 for (
auto e : edges) {
97 auto s =
d.get_segment(e);
98 if (s.target() < s.source()) {
99 s = {s.target(), s.source()};
103 bd.segments.push_back(s);
104 nodes.insert(e->target());
105 nodes.insert(e->source());
110 if (e->isIncident(w)) {
113 if (geometry::left_turn(s,
d.get_point(w))) {
120 for (
auto u : nodes) {
122 if (u != w && u != v) {
124 if (s.target() < s.source()) {
125 s = {s.target(), s.source()};
128 bd.segments.push_back(s);
131 for (
auto e : g.edges(u)) {
135 auto x = e->opposite(u);
136 if (e->isIncident(w) || e->isIncident(v)) {
139 if (geometry::left_turn(s,
d.get_point(x))) {
148 std::vector<Point>
p_rect;
149 for (
unsigned int i = 0; i < 4; ++i) {
153 p_rect.push_back(
rect_box.vertex(i) + geometry::Vector_t<Kernel>(x, y));
156 for (
unsigned int i = 0; i < 4; ++i) {
159 if (s.target() < s.source()) {
160 s = {s.target(), s.source()};
164 bd.segments.push_back(s);
165 if (geometry::left_turn(s,
d.get_point(v))) {
167 d.get_graph().number_of_edges() *
d.get_graph().number_of_edges());
170 -
d.get_graph().number_of_edges() *
d.get_graph().number_of_edges());
180 if (s.has_on(p) && s.source() != p && s.target() != p) {
187 for (
unsigned int i = 0; i <
segments.size(); ++i) {
188 for (
unsigned int j = i + 1;
j <
segments.size(); ++
j) {
190 Logger::slout() <<
"[math] " << i <<
" " <<
j <<
"; " <<
segments[i] <<
" "
195 Logger::slout() <<
"[math] " << i <<
" " <<
j <<
"; " <<
segments[i] <<
" "
210 auto rep = geometry::find_representative_node(
bd, p);
215 std::vector<typename BD::Node> parent(
bd.number_of_nodes());
216 std::vector<typename BD::Edge>
parent_edge(
bd.number_of_nodes());
218 auto f_weight = [&](
typename BD::Node v,
typename BD::Edge e) {
219 if (
bd.is_face_edge(e) ||
bd.degree(v) == 2) {
221 }
else if (
bd.is_left(v)) {
228 auto expand = [&](
typename BD::Node w,
typename BD::Edge e) {
235 std::vector<typename BD::Node>
queue;
236 std::vector<int> weight(
bd.number_of_nodes(), 0);
237 std::vector<bool> visited(
bd.number_of_nodes(),
false);
239 queue.push_back(rep);
243 auto handle_edge = [&](
typename BD::Node v,
typename BD::Edge e) {
244 typename BD::Node w =
bd.edges[e];
246 if (!visited[w] && expand(v, e) && v != w) {
247 weight[w] = weight[v] +
f_weight(v, e);
255 while (!
queue.empty()) {
276 const std::vector<Edge>& edges, geometry::Rectangle_t<Kernel>&
rect_box,
284# ifdef OGDF_GEOMETRIC_CR_MIN_DEBUG
285 std::cout <<
"intersect..." << std::flush;
287 geometry::PlanarSubdivision<Kernel, false>
ps;
288 bd.intersecting_segments = std::move(
ps.subdivision(
bd.segments));
291# ifdef OGDF_GEOMETRIC_CR_MIN_DEBUG
292 std::cout <<
"done" << std::endl;
294 std::cout <<
"nof segments in bd: " <<
arr_n_segs << std::endl;
296 std::cout <<
"construct bd..." << std::flush;
298 static geometry::BloatedDual<Kernel>
bdc;
300# ifdef OGDF_GEOMETRIC_CR_MIN_DEBUG
301 std::cout <<
"done" << std::endl;
305 Polygon compute(
const Drawing&
d,
const Node& v,
const std::vector<Node>&
neighbors,
306 const std::vector<Edge>& edges, geometry::Rectangle_t<Kernel>&
rect_box,
310 auto dr = geometry::BloatedDual<Kernel>::compute_drawing(
bd);
Declaration of BoothLueker which implements a planarity test and planar embedding algorithm.
Contains logging functionality.
Declaration of extended graph algorithms.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
int randomNumber(int low, int high)
Returns random integer between low and high (including).
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.