我知道有一种最坏情况的O(n log n)算法用于找到复杂多边形的凸包,而最坏情况的O(n)算法用于找到简单多边形的凸包。是否有最坏情况的O(n)算法来寻找复杂多边形的凸包?
复杂多边形是线段可以相交的多边形。找到复杂多边形的凸包相当于找到无序点列表的凸包。
答案 0 :(得分:2)
我很确定不是。任意点集上的凸壳可以显示为等于排序。我们可以对任意点集进行排序,并按顺序连接这些点,使其成为复杂多边形,从而减少任意点集上的问题。
以下是proof的链接,凸包相当于排序。我太懒了,打得太糟糕了,不能自己写出来。
答案 1 :(得分:2)
如果您的点集是这样的,一些非基于比较的排序机制(如基数排序)将比基于比较的方法更快,那么似乎您可以使用格雷厄姆扫描算法(http://www.math.ucsd.edu/~ronspubs/72_10_convex_hull.pdf)来计算它。格雷厄姆扫描的时间复杂度由分类步骤决定。其余的是线性的。
答案 2 :(得分:0)
一般来说,没有O(n)解决方案。像素化版本优于O(n log n)。然而,它在其他方面如此蹒跚,以至于你在实践中使用它会疯狂。
将第一个多边形(使用顶点0,1,2)渲染到屏幕空间中,然后使用不同的ID重新渲染顶点,以便稍后识别它们。例如,您可以将帧缓冲区清除为RGBA ffffffff,并将fffffffe用于凸包覆盖的空间。每个顶点将使用其ID作为RGBA进行渲染; 00000000,00000001等
一个16位的例子:
fffffffffffffff
fffffff0fffffff
ffffffeeeffffff
fffffeeeeefffff
ffffeeeeeeeffff
fffeeeeeeeeefff
ff2eeeeeeeee1ff
fffffffffffffff
检查新点是当前帧缓冲区中的简单查找。如果它占据的像素是用多边形或顶点ID'阴影',则新顶点被拒绝。
如果新顶点位于现有多边形之外,您会发现新顶点与凸包内部某些点之间的第一个像素(第一个多边形中间的某个点正常工作)并沿着船体的圆周行进 - 在两个方向 - 直到你发现自己从新的顶点到船体的远端。 (我将此作为练习留给用户。从效率的角度来看,有很多解决方案都很糟糕。)填充由这两个点定义的多边形和带有多边形空间ID的新顶点 - 小心不要删除任何顶点ID - 并继续下一个像素。
完成后,任何包含未被船体ID完全包围的顶点ID的像素都是凸包顶点。
虽然算法的复杂度是顶点数的O(n),但它的缺陷是显而易见的。 没有正确思想的人会使用它,除非他们有一个荒谬,疯狂,惊人的点数来处理,以便几乎每个顶点都会被立即拒绝,除非他们能接受别名结果的限制
朋友们不要让朋友实施这个算法。
答案 3 :(得分:0)
如果你的点来自有限的宇宙(在实践中总是如此),你可以进行基数排序,然后运行安德鲁的单调链算法。