形成凸多边形的顶点数组的最大前缀
Posted
技术标签:
【中文标题】形成凸多边形的顶点数组的最大前缀【英文标题】:largest prefix of array of vertices that forms a convex polygon 【发布时间】:2011-06-09 08:40:26 【问题描述】:相关:Polygon Decomposition - Removing Concave Points to Form Convex Polygons
我正在寻找一种算法来执行以下操作:
输入是一个二维点数组(P0…PN-1)。数组的长度 N 变化 (3 ≤ N 对于任何 M ≤ N,可能存在也可能不存在顶点为 P0…PM-1 的凸多边形。
注意边不一定是数组中的相邻对。
找到最大 M 以使该凸多边形存在的最有效算法是什么?
我目前的算法效率很低。我用 M=3 然后 M=4, M=5 等进行测试,计算船体然后测试所有 P0…PM-1 是船体的顶点,如果不是,那么我跳出循环并返回 M-1。
示例 #1:[(-2,2), (2,2), (-2,-2), (-1,1)]
结果:3(因为前三个点形成一个三角形,但添加 P3 = (-1,1)
会使多边形非凸)
示例 #2:[(-2,2), (2,2), (-2,-2), (1,-1)]
结果:4(因为可以从数组中的所有 4 个点构造一个凸四边形)
更新示例#3:[(-3,3), (3,3), (2,-1), (-3,-3), (3,-3), (-2,1)]
结果:4。
这个例子说明了为什么只取所有提供点的凸包并找到一个前缀是它的子集是不够的。 (3,-3)
不能是由前五个点组成的凸多边形的一部分,因为这样前一个点 (2,-1)
将不再位于船体上。但是必须拒绝的是(3,-3)
,即使它位于所有六个点的外壳上而(2,-1)
没有。
无效输入示例:
[(-1,-1), (0,0)]
(点数太少)
[(-1,-1), (0,0), (1,1), (1, -1)]
(前三点是共线的:我不希望算法能够处理这个问题。)
【问题讨论】:
这与传统的凸包有何不同?我们想要顶点数最多的凸包吗? @biziclop,是的,我想要顶点数最多的船体。而且我希望它可以比为每个可能的尺寸计算船体更有效。 正如 biziclop 提到的:这只是找到一组点的凸包的问题。这个凸包边缘的点数就是你的大小。因此,O(n*log(n)) 使用 Graham's Scan 或 Quick-Hull 算法。还是我错过了什么? @Bart Kiers,不完全是。我只对作为数组前缀的外壳感兴趣。当我看到一个不能成为船体一部分的点时,我必须停止扫描阵列。任何后续点都必须忽略,即使它们可能是(不同)船体的一部分。 @Bart Kiers,我添加了示例 #3 来说明这一点。 【参考方案1】:我认为你想要一个增量凸包。这里有几个链接:
http://www.personal.kent.edu/~rmuhamma/Compgeometry/MyCG/ConvexHull/incrementCH.htm http://ww3.algorithmdesign.net/handouts/IncrementalHull.pdf http://www.fandm.edu/computer-science/professors-emeriti/anderson/jay-martin-anderson/research-and-development/portal-algorithm-visualization-in-computational-geometry/convex-hull-an-incremental-algorithm【讨论】:
【参考方案2】:如果你尝试一种二分搜索呢?每次整个前缀形成一个凸多边形时,前缀的大小加倍。每次失败时,将前缀的大小缩小到当前大小和之前大小之间的一半。
【讨论】:
【参考方案3】:您可以在 O(m lg m) 时间内完成此操作。
将上壳点和下壳点存储在以 X 坐标为键的搜索树中。 当一个新点到达时,找到覆盖其 X 值的上下线段(搜索树)。 如果新点位于两条线之间,则它不在船体上。放弃吧。 否则,将点插入上壳或下壳(以具有较近线段的为准)。 如果插入点会将相邻点变成内角,则它们不在船体上。放弃吧。 处理边缘情况,例如新的最左边点、垂直点等。 继续直到处理所需的点数。【讨论】:
当你的答案弹出时,我正在发布大致相同的回复。【参考方案4】:对此有一个非常简单的 O(m log m) 解决方案。
假设至少有 3 个点且前 3 个点不共线:
在前 3 个点的三角形中找到一个点 P。
按相对于 P 的角度(逆时针)对 3 个点进行排序。 (这个排序列表将是凸包)
虽然我们不在列表的末尾,但在排序列表中找到下一个点的位置。
如果插入点会使多边形凹入,转到6。(这可以通过检查新的相邻两圈和当前圈来检查)
插入点并转到 3。
完成。
您必须在此处处理的主要边缘情况是插入位于列表的末端之一,因为列表实际上是圆形的。处理这个问题的一种简单方法是在每个点上插入它的角度和角度 +- 2pi。
【讨论】:
以上是关于形成凸多边形的顶点数组的最大前缀的主要内容,如果未能解决你的问题,请参考以下文章