什么时候四叉树优于空间散列?


12

我正在同时制作具有很多对象的2d平台游戏。它们都是AABB碰撞检测到的。我首先尝试使用四叉树来减少要检查的对象的数量,尝试了几种不同的配置,但事实证明它并没有达到我所需要的效果。我实现了空间哈希,而且效率更高,每次碰撞要检查的对象数量大大减少了。

是否存在使用四叉树进行2d碰撞检测优于空间散列的情况?根据我的测试,似乎空间散列总是以较少的要测试碰撞的对象结束?

我尚未对算法进行计时,但是例如在C语言中进行编码时,哈希只是非常昂贵或难以实现吗?值得一提的是,我使用javascript编写游戏,其中的哈希是“免费”的。

这是比较,我是否忽略了某些内容?http://zufallsgenerator.github.io/2014/01/26/visually-comparing-algorithms/

Answers:


12

四叉树的主要优点是,它使您可以非常快速地丢弃整个存储桶组。

例如,假设我有一个包含六个级别的四叉树。在最低级别,它是32x32的盒子;包含该最详细的底部的1024个框。为了进行比较,我们还将考虑“空间哈希”-一个平面网格,其中也包含32x32框,总共1024框。(四叉树总共有超过1024个框,因为它在较高级别还包含较大的框)

假设系统中没有可碰撞的对象-我们的四叉树和平面网格中的所有框都是完全空的。

如果要测试某物体的碰撞,该碰撞的大小足以使其边界框与所有这些框相交,并且使用的是扁平网格,则必须检查这1024个框中的每个框,以查看其中是否还有任何东西他们。

但是,如果您使用的是嵌套的四叉树,则最顶层可以告诉您系统中没有其他对象,因此您只需查看单个框即可知道您不会发现碰撞。在树的更深处-您可以立即停止测试。

同样,如果对象仅存在于四叉树的某些区域中,则四叉树自然会引导您仅搜索可能相关的框,而网格要求您检查每个相交的框,因为您无法提前知道哪些网格方块中将包含对象。如果您的四叉树中有很多是空的,并且您正在执行大型,复杂的查询(例如,巨大的摄像机视锥,而不是小的,简单的矩形),那么您可能会发现,如果要遍历的框总数要少得多使用树结构而不是平坦的网格来测试某些东西。这可以带来很大的不同。

当然,所有这些并不意味着树结构总是正确的选择。平面网格非常适合您所遇到的情况-密集的物体云几乎均匀地分布在世界各地,并且我们正在执行简单,廉价的碰撞测试。在这种情况下,网格绝对是最佳方法!


5
简单的总结,对于极端懒惰的人:四叉树更快地处理了大小不同的对象。
Anko 2014年

谢谢,这是一个很好的答案!我怀疑物体的大小一致。
克里斯

实际上,通常,您通常必须在四叉树的所有级别中进行搜索以检查是否没有对象,因为通常而言,一个级别仅包含有关对象的信息,这些对象既完全位于该级别的边界之内,又不位于较低级别。
malthe

1
@malthe如果您坚持使用无法在这种查询中提早实现的四叉树实现,则绝对要使用空间哈希;您将节省33%的内存成本,无论如何您都不会从中受益。或者,您也可以放宽思路,使用一个可以提前的四叉树,方法是让每个节点跟踪其子级中的实体数量,或者使用稀疏的四叉树,使空节点成为从树上断开链接,直到需要它们为止。其实。五年多以后。
特雷弗·鲍威尔

@TrevorPowell当然,您是对的。我只是违反了您的保证,即您只需要看一个盒子。事实并非如此,因为您必须继续努力。据我所知,您可以在树的上方和下方找到较高的碰撞。
malthe
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.