随机将多边形放在多边形内

时间:2015-10-16 13:43:58

标签: algorithm polygon intersection

我将两个多边形定义为一系列2D浮点值。它们不保证是凹的或凸的。他们不会跨越自己。他们不能旋转。我想根据它的大小随意放置一个在另一个内部。主要问题是效率。我必须在几秒钟内完成大约200次左右。

我一直在研究这几天,并没有取得任何明显的进展。任何线索都会受到赞赏。

2 个答案:

答案 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,你就会更快地失败。下图说明了三种情况。

enter image description here

(图片来自:http://www.cs.berkeley.edu/~ug/slide/pipeline/assignments/as4/figures/boundcull.gif

预处理: 确定形成B的行的等式。将它们存储在HashMap<<Point, Point>, Line>中,以便稍后执行该步骤。您可以通过斜率 m 唯一地定义直线并拦截 c ,并且您的直线的终点将成为关键( <Point, Point> )的HashMap。

算法:

对于通过上述过滤器的每个S:

  1. 读取S的点并确定形成S
  2. 的行
  3. 对于S的每一行,看看它是否与B 的任何一行相交(它们已存储在HashMap中)
  4. 如果没有交叉点,S在B内部,你所要做的就是画线而不用担心交叉。
  5. 在最坏的情况下,此算法的复杂性将为 O(bs)以绘制每个多边形。

    这一步是蛮力的,以保持算法易于理解。否则,可以在此处进行能够更快地提供结果的关键优化。您可以过滤B的行。如果B的行的端点位于S的最左侧点的左侧,或者位于S的最右侧的点的右侧,则不需要考虑B的行与S的交点。 S或S以下。这可以节省大量的计算。

答案 1 :(得分:1)

如果这里的其他答案有用,这是它的附录。它显示了另一种方法,以查看较小的多边形是否在较大的多边形内。

要测试多边形包含,可以查看是否包含多边形的所有边。要测试所有边缘,请测试是否包含每条边的所有点。

  1. 通过在现有顶点之间添加顶点来加密较小的多边形。下图显示了一行的密集化。enter image description here
  2. 现在对于加密多边形,测试其点是否都位于外部多边形内。这个测试可以通过从两侧发出无限远的点绘制线条,然后计算该线与更大的多边形相交的次数。Image taken from: http://d21vdchv0ihj7g.cloudfront.net//wp-content/uploads/polygon31.png
  3. 如果所有点都在,则多边形在。
  4. 之内

    <子> First Image source

    Second Image source