Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

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.