Loading [MathJax]/extensions/tex2jax.js

Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
LargestCircleInPolygon.h
Go to the documentation of this file.
1
31#pragma once
32
33#ifdef OGDF_INCLUDE_CGAL
34
38
39# include <queue>
40
41//https://blog.mapbox.com/a-new-algorithm-for-finding-a-visual-center-of-a-polygon-7c77e6492fbc
42namespace ogdf {
43namespace internal {
44namespace gcm {
45namespace geometry {
46
47template<typename Kernel>
48Point_t<Kernel> largest_circle_in_polygon(const Polygon_t<Kernel>& polygon, double precision = 1) {
49 using FT = typename Kernel::FT;
50
51 struct Cell {
52 Bbox bb;
53 FT m_distance;
54
55 Cell(Bbox& bb_, FT distance) : bb(bb_), m_distance(distance) {
56 //nothing to do
57 }
58
59 FT cell_size() const {
60 return std::min(bb.height(), bb.width()); //use max?
61 }
62
63 FT potential() const { return m_distance + bb.width() * bb.height() / 4; }
64
65 bool operator<(const Cell& c) const { return potential() > c.potential(); }
66 };
67
68 Bbox bb_p(polygon.bbox());
69
71
72 Cell opt(bb_p, squared_distance(polygon, bb_p.template center<Kernel>()));
73 pq.push(opt);
74
75 while (!pq.empty()) {
76 const Cell top = pq.top();
77 pq.pop();
78
79 if (top.potential() < 0) {
80 continue;
81 }
82
83 if (top.m_distance > opt.m_distance) {
84 opt = top;
85 }
86
87 if (top.potential() - opt.m_distance < precision) {
88 continue;
89 }
90
91 auto h = top.bb.height() / 2;
92 auto w = top.bb.width() / 2;
93
94 Bbox b1(top.bb.xmin(), top.bb.ymin(), top.bb.xmin() + w, top.bb.ymin() + h);
95 Bbox b2(top.bb.xmin() + w, top.bb.ymin(), top.bb.xmax(), top.bb.ymin() + h);
96 Bbox b3(top.bb.xmin() + w, top.bb.ymin() + h, top.bb.xmax(), top.bb.ymax());
97 Bbox b4(top.bb.xmin(), top.bb.ymin() + h, top.bb.xmin() + w, top.bb.ymax());
98
99 pq.push(Cell(b1, squared_distance(polygon, b1.template center<Kernel>())));
100 pq.push(Cell(b2, squared_distance(polygon, b2.template center<Kernel>())));
101 pq.push(Cell(b3, squared_distance(polygon, b3.template center<Kernel>())));
102 pq.push(Cell(b4, squared_distance(polygon, b4.template center<Kernel>())));
103 }
104
105 // center point must be in polygon
106 OGDF_ASSERT(contains(polygon, opt.bb.template center<Kernel>()));
107
108 return opt.bb.template center<Kernel>();
109}
110
111}
112}
113}
114}
115
116#endif
Priority queue interface wrapping various heaps.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:41
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
bool operator<(const MDMFLengthAttribute &x, const MDMFLengthAttribute &y)
The namespace for all OGDF objects.