【发布时间】:2021-12-28 19:45:13
【问题描述】:
给定一个可能是凹面并且可能有孔的多边形,我如何获得由其顶点子集组成的最大简单凸多边形?
即,给定简单的凹多边形:
p = Polygon([(30, 2.01), (31.91, 0.62), (31.18, -1.63), (28.82, -1.63), (28.09, 0.62), (30, -0.001970703138552843)])
我想要最大的简单凸多边形(可能相同但没有最左边的点 (28.09, 0.62) 并将 (28.82, -1.63) 替换为 (30, -1.63))。像这样:
这只是一个未测量的示例。可能实际上 (28.09, 0.62) 和 (30, 2.01) 都必须删除,如果这会产生更大的区域,例如可能由切割造成的这里用绿线表示:
但是,假设第一次切割是正确的,如果我们在“另一边”添加一个洞:
p = Polygon([(30, 2.01), (31.91, 0.62), (31.18, -1.63), (28.82, -1.63), (28.09, 0.62), (30, -0.001970703138552843)],
[[(30.1,0.62), (30.1,1.25), (31, 1.25), (31,0.62)]])
在这种情况下,最大的简单凸多边形可能会旋转到多边形的另一半,因此它不会丢弃前一个点,而是会丢弃 (30, 2.01) 并替换 ( 31.91, 0.62) 与 (31, -1.63) 之间有一个点。显然,在这种情况下,它会抛出孔的所有顶点。
评论
任何在多边形内部保持完整的孔都会根据定义为多边形引入一个凹角。如果输入多边形中有一个洞,则最多有一条边可以保留在输出多边形中(并且,根据“简单多边形”的定义,该边将是外部坐标的成员)。
这个定义有点草率,所以我应该尽量清楚。所有内部和外部顶点都是输出简单多边形中可能点集的成员。所有与内部和外部边界相交的点(它们之间的线段)也是如此。点的选择应产生一个简单的凸多边形,该多边形内接在源多边形中。如果源多边形是一个简单的凸多边形,它应该返回与输出相同的多边形。很有可能拥有面积相等的整个候选解决方案系列。如果它们是最大的,它们中的任何一个都可以。
草图方法:如果您像示例中的绿线一样丢弃切割,那么剩下的就是从线段中删除带有投影的点。因此,您可以将所有内部和外部点视为一个集合,并排除其中 0 个或更多的子集,然后找到最大的凸多边形。因此,要么只排除该点,要么当排除一个点产生一个新的凹角时,从该角度的那一侧的线段投影到多边形另一侧的线段(这是用于产生第一个示例解决方案图像)。重新审视绿线切割,这些线将多边形平分并与凹角的中心点相切。如果这个二等分必须垂直于从中心点到剩余多边形质心的线,那么这并不复杂。但我不确定那是真的。无论如何,这需要考虑很多多边形。
注意:起初我标记了一个重复,认为这本质上是另一个问题的更复杂版本(Finding largest subset of points forming a convex polygon,但有漏洞)。但是,这种方法不允许在解决方案中添加新顶点。例如,本文中第一个形状的 Delaunay 三角剖分不会产生新点:
[ 'POLYGON ((28.09 0.62, 28.82 -1.63, 30 -0.001970703138552843, 28.09 0.62))',
'POLYGON ((28.09 0.62, 30 -0.001970703138552843, 30 2.01, 28.09 0.62))',
'POLYGON ((30 2.01, 30 -0.001970703138552843, 31.91 0.62, 30 2.01))',
'POLYGON ((31.91 0.62, 30 -0.001970703138552843, 31.18 -1.63, 31.91 0.62))',
'POLYGON ((28.82 -1.63, 31.18 -1.63, 30 -0.001970703138552843, 28.82 -1.63))']
提供的尽可能重复的文章仅计算点的子集以找到最大的凸包——即,它没有在线上引入点。
【问题讨论】:
-
你能举一个例子来说明你希望得到的形状是什么样的吗?一个包含原始顶点子集的简单凸多边形听起来很像 "convex hull" 对我来说
-
嘿,Cory,我将它添加到第一个样本中.. 问题是,我不确定这个结果是否是 最大的.. 但很可能是。