Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

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
42 namespace ogdf {
43 namespace internal {
44 namespace gcm {
45 namespace geometry {
46 
47 template<typename Kernel>
48 Point_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 
70  PriorityQueue<Cell> pq;
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
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
PriorityQueue.h
Priority queue interface wrapping various heaps.
ogdf::embedder::operator<
bool operator<(const MDMFLengthAttribute &x, const MDMFLengthAttribute &y)
Definition: MDMFLengthAttribute.h:90
Rectangle.h
Polygon.h