如何有效地存储矩形网格?

时间:2014-04-19 23:24:19

标签: c++ tiling

所以我正在考虑用不同形状的矩形制作建筑游戏而不仅仅是正方形,但我无法找到一种有效的方法来做到这一点。例如,我不想要像俄罗斯方块那样组成每个形状的瓷砖网格。我希望每件作品都是一个宽度和高度的物件。例如,2 * 3件不会占用6个瓷砖,它只是一个矩形。我必须能够有效地整理作品并能够以一定的坐标获得作品。如果我只是使用二维数组的瓷砖,它将使用我不需要的内存。

4 个答案:

答案 0 :(得分:2)

无论你如何操作,在任何给定坐标上获取矩形都是非常昂贵的,但最有效的方法可能是创建矩形不受限制的松散网格。每当一个棋子移动时,它将更新一个二维数组,并在其全部或部分包含的所有正方形中引用它。每当给定坐标时,计算坐标所在的网格中的哪个方格,然后从中可以进行更广泛的计算,以检查坐标是否实际位于矩形内。

答案 1 :(得分:1)

早些时候发布这个帖子,我知道您已经接受了答案,但您可能需要考虑以下内容。

我想我明白你在问什么。您想通过检查矩形边界来检查图块属于哪个矩形(如果有)。因此,要检查此方块中的右上方平铺是否属于任何矩形,其中任何-是不属于矩形的平铺

a a a -
a a a b
a a a b
a a a b

您要检查图块a的矩形b和矩形(0,3),并查看它既不属于它。

您尝试避免的替代方法是将每个图块设置为属于矩形:

(0, 0).parent = 'a'

(0, 1).parent = 'a'

...

(2, 2).parent = 'a'

或类似的东西。

每种解决方案的权衡取舍不同"

在第一个中,每次要查找拼贴所属的矩形时,您都必须进行大量的比较。 O(n)比较,您将比较最差情况下的n次,最佳情况下的1和平均n/2次比较(如果每个磁贴的概率相等)属于一个矩形,在类似俄罗斯方块的游戏中不是真的。)

在第二个解决方案中,您必须将父变量存储到每个磁贴。这会增加内存使用量,但时间复杂度始终为O(1)

每个人可能会更好,具体取决于您的网格设置方式:

a a a a a a a a a a a b d d d d d d d d
a a a a a a a a a a a b d d d d d d d d
a a a a a a a a a a a b d d d d d d d d
a a a a a a a a a a a b d d d d d d d d
a a a a a a a a a a a b d d d d d d d d
a a a a a a a a a a a b d d d d d d d d
a a a a a a a a a a a - e e e e e e e e
a a a a a a a a a a a c e e e e e e e e
a a a a a a a a a a a c e e e e e e e e
a a a a a a a a a a a c e e e e e e e e

检查特定图块的父图标非常快:您只需检查5个矩形,如果图块不在任何图块中,则它没有父图标。

检查图块是否具有父图标同样快。

然而,当你开始有越来越多的矩形......

a b c d e f g h i j k l m n o p q r s t
A B C D E F G H I J K L M N O P Q R S T
u v w x y z U V W X Y Z 1 2 3 4 5 6 7 8
9 0 ...
...

您必须进行大量比较,以确定特定磁贴是否具有父级。您不必精确定位坐标并检查其父值,而是必须检查每个矩形以查看切片是否位于其中任何一个中。


我建议您只使用NxN网格并为每个图块存储父矩形值(第一个解决方案),除非您知道您不会使用那么多矩形或者网格将主要填充为空空格。

答案 2 :(得分:0)

我只需创建一个宽度高度高度的类矩形,然后我将使用此类'实例的数组。

答案 3 :(得分:0)

矩形是否重叠?如果没有,您可以在此处使用RectangleGrid类:https://github.com/eyal0/OctoPrint-Slicer/blob/master/src/RectanglePacker.js#L10

添加矩形可能很慢,但对于您的用例可能会有效。  查询给定位置的矩形是O(nlogn)。