我需要找到一个凸多边形的最大内切圆,我已经搜索了很多网站,我知道这可以通过使用Delaunay三角剖分来完成。我在CGAL讨论中发现thread使用CGAL算法:
您可以使用CGAL轻松计算:
首先,计算点的Delaunay三角剖分。
然后,迭代三角测量的所有有限面。 对于每个有限面f
- 计算其外心c
- 在三角测量中找到c(为了加快速度,你可以给一个 f的顶点作为点位置的起始提示)
- 如果由locate(c,提示)返回的面是有限的,那么外心 c位于点的凸包中,因此,f是候选
- 如果f是这样的候选面,则计算其平方圆周 只保留最小平方圆周的脸
CGAL手册(第2D章三角测量,以及一些内容 来自内核)显示了执行此操作的每个基本功能。
我对这个算法的最后一部分感到有点困惑。当我读到它时,我从中理解的是,三角测量面的最小圆周是最大的圆的圆的半径。但是从具有Delaunay三角剖分的多边形的例子来看,即使最小的外接圆有时也不能适合多边形,所以它如何与最大的内切圆具有相同的半径?
答案 0 :(得分:4)
多边形中的最大内切圆。 针对多边形的最大内切圆问题的经典计算几何解决方案是使用多边形面部的generalized Voronoi diagram resp。多边形的medial axis。这种方法适用于更常规的设置,例如带孔的多边形,请参阅此stackoverflow answer以查找类似的问题。
凸面输入。 然而,输入多边形的凸性给问题带来了更多的结构,我想对此进行评论。考虑下面的凸输入多边形(黑色),Voronoi图(蓝色)和以Voronoi节点为中心的最大内切圆(绿色)。
经典的基于Voronoi的解决方案是(i)计算Voronoi图和(ii)使Voronoi节点具有最大间隙(即到其定义面的距离)。
具有孔的多边形(即,顶点和边的集合)的Voronoi图可以在O(n log n)时间内计算,c.f。 Fortune's algorithm (1986)。后来Chin et alii (1999)给出了一个简单多边形的中轴的O(n)算法。
对于凸多边形,然而,由于Aggarwal et alii,在1989年已经知道在O(n)时间内运行的Voronoi图的时间最优算法。该算法基本上遵循以下思想:考虑以单位速度向内移动的灰色偏移曲线。如果你将这个运动投射到三个空间,其中z轴是时间你在多边形上得到一个单位斜坡屋顶:
这个屋顶模型的特征还可以如下:在每个多边形边缘上以45°斜率放置一个半空间,使其具有多边形(使得它们包含多边形)并将它们全部相交。因此,如果您可以快速计算半空间的交叉,那么您还可以快速计算凸多边形的Voronoi图。实际上,对于最大内切圆问题,我们不需要回到Voronoi图,而是采取屋顶的一个峰值,这标志着最大内切圆的中心。
现在半空间二元化到点,然后半空间的交集对应于其双点的凸包。 Aggarwal等人。现在发现了一个O(n)算法,用于凸起来自这种设置的点的凸包。
这种结构的总结可以在我的blog article找到导致任何维度中凸多面体的Voronoi图算法。
简单&快速实现。计算Voronoi图的简单算法由straight skeletons推动。对于凸多边形,Voronoi图和直骨架是相同的。
直骨架实现Stalgo背后的算法基本上模拟了波前结构的演变(灰色偏移曲线)。对于凸多边形,这会减少以找到折叠的边缘序列。
因此,简单的O(n log n)算法可能如下所示:
实际上,您可以进一步简化上述算法:您不需要更新优先级队列中的边缘折叠,只需插入新的折叠:由于边缘的新崩溃时间严格较低,因此您始终首先获得正确的事件,解雇其他人,队列的增长不超过2n。因此,您不会损害O(n log n)时间复杂度。
对于最大内切圆问题,您可以进一步简化上述算法:您查找的Voronoi节点(直接骨架节点)是由于优先级队列中循环结束时最后三角形的崩溃造成的
该算法应该在实践中快速进行,并且只需几行代码。
答案 1 :(得分:0)
最后一步可能意味着选择三角形的最小面。然后冲洗并重复。