我将两个多边形定义为一系列2D浮点值。它们不保证是凹的或凸的。他们不会跨越自己。他们不能旋转。我想根据它的大小随意放置一个在另一个内部。主要问题是效率。我必须在几秒钟内完成大约200次左右。
我一直在研究这几天,并没有取得任何明显的进展。任何线索都会受到赞赏。
答案 0 :(得分:4)
免责声明: 如果您尝试在更大的多边形内部打包多个多边形,那么我认为this problem is NP hard因此,高效精确的算法不太可能被开发以解决这个问题。多边形可以在平面中连续平移和旋转,这意味着放置可能是无限的,这使得问题的解空间也是无限的。如果您只是想找到较小的多边形是否适合较大的多边形,我缺乏有效的答案,但正如您所问 - “任何线索都会受到赞赏” - 这里有一个。
让较大的多边形为B,较小的多边形(要插入的多边形)为S. B总共有b个点,S总共有s个点。
下图显示了边界框和最小边界矩形。我们使用它来获取快速失败过滤器(非常简单的想法......在下一段中定义)。下面显示的框(a)计算速度更快,而框(b)更精确的过滤。画出那个箱子,为您的箱子提供更好的投资回报。虽然在下图中它们都是椭圆形而不是多边形,但你可以得到这个想法。
http://portal.ku.edu.tr/~cbasdogan/Tutorials/imageU21.JPG
(图片来自:http://portal.ku.edu.tr/~cbasdogan/Tutorials/imageU21.JPG)
Crux:如果B的任何一行与S的任何一行相交,或者如果S的所有行都在B之外,则B不能接受S。
快速失败过滤器: 获取B和S的边界矩形。如果无法将边界矩形S放置在B的边界矩形内,则你不能将多边形S放在多边形B内。这样,如果B不可能包围S,你就会更快地失败。下图说明了三种情况。
(图片来自:http://www.cs.berkeley.edu/~ug/slide/pipeline/assignments/as4/figures/boundcull.gif)
预处理: 确定形成B的行的等式。将它们存储在HashMap<<Point, Point>, Line>
中,以便稍后执行该步骤。您可以通过斜率 m 唯一地定义直线并拦截 c ,并且您的直线的终点将成为关键( <Point, Point>
)的HashMap。
算法:
对于通过上述过滤器的每个S:
在最坏的情况下,此算法的复杂性将为 O(bs)以绘制每个多边形。
† 这一步是蛮力的,以保持算法易于理解。否则,可以在此处进行能够更快地提供结果的关键优化。您可以过滤B的行。如果B的行的端点位于S的最左侧点的左侧,或者位于S的最右侧的点的右侧,则不需要考虑B的行与S的交点。 S或S以下。这可以节省大量的计算。
答案 1 :(得分:1)
如果这里的其他答案有用,这是它的附录。它显示了另一种方法,以查看较小的多边形是否在较大的多边形内。
要测试多边形包含,可以查看是否包含多边形的所有边。要测试所有边缘,请测试是否包含每条边的所有点。
<子> First Image source 子>