确定线段触摸的常规2d网格中所有单元格的最快方法是什么

时间:2012-11-12 21:55:57

标签: performance algorithm grid graphics2d

我想找到触摸或包含给定有限线段部分的所有网格图块。网格是2d规则网格,因此我可以从图块位置(行,列)推导出任何图块的中心,反之亦然我可以从给定的浮点坐标计算图块位置,具有两个快速整数除法。瓷砖是二次的,例如0.25x0.25,其中0.25定义为图块宽度。 现在我需要确定给定线段触摸的所有图块 (浮点数中给出的两个2d点定义了一个线段)。 我目前的方法是将片段分割成等距点,其距离是拼贴宽度的一半(向shannon的问候)。我收集包含给定点的所有瓷砖并删除重复的瓷砖。 由于此操作是我的程序中性能最关键的部分,我想知道是否有更快的方法来计算相应的图块。

编辑:正如帕特里夏所指出的那样,我当前的方法并没有产生完整的图块集,因为不会包含只触及该线的一小部分的图块。这对我来说是可以接受的,因为在我看来,速度比准确性更重要,但应该注意到。

为了让它更清晰:我想要图像中的所有红色瓷砖,但我可以省略例如如果我获得速度,那就是玫瑰花。

Grid with found Tiles

3 个答案:

答案 0 :(得分:5)

您的问题基本上归结为在光栅图像上绘制线段。

如果您可以使用粉红色瓷砖,请使用Bresenham的算法。否则,使用与绘制抗锯齿线相似的技术:

从包含段的一端并将其放入队列的磁贴开始。然后使用常规BFS算法,仅将与段相交的切片放入队列:

在一次迭代中,从队列的一端取一个图块,这是您下次找到的相交图块。然后找到它的所有邻居,并将与段相交的那些(在这种情况下足以测试与一条线的交点)到队列的另一端。必须根据线的方向选择邻居。如果它向右下方,使用向下,向右和向右的瓷砖作为邻居,如果它上升,只使用邻居,依此类推。

当您到达包含该段另一端的图块时结束。

答案 1 :(得分:1)

使用相同的渐变符号对着瓷砖对角线测试线条的渐变。 如果它比瓷砖对角线更陡,请在下面更换x和y坐标。

如果渐变比图块对角线浅,则线条接触或穿过给定图块,并且图块不包含终点,其与图块边缘的交叉点中的至少一个必须位于x边界上瓷砖。

对于每个行结束,收集包含触摸结束点的图块或图块。

对于作为两个终点x坐标之间的切片边缘的每个x坐标,计算线的y坐标。收集接触该点的瓷砖。

我认为这一切都可以通过最多几个部门来完成渐变检查。主要过程是乘法,加法和比较。

答案 2 :(得分:1)

给定线段的终点,您可以轻松计算线的等式y = mx + b。并且考虑到段的长度,您可以计算参数形式:

x = x0 + ft
y = y0 + gt

给定这些方程式中的任何一个,您可以计算线上任何给定y坐标的x坐标。所以...

从该行的第一个终点开始,您知道包含该点的单元格位于该集合中。您知道每个单元格的x坐标,因此您可以快速确定线段穿过单元格边界的y坐标。如果y坐标高于单元格的顶部y坐标,则线段与起始单元格上方的单元格相交。 (如果线的斜率“向下”,则替换“下方”。)

如果您对x轴上的每个单元边界重复该测试,您将获得该段穿过的所有单元格的列表。