2 个不稳定版本
0.2.0 | 2023年4月12日 |
---|---|
0.1.0 | 2023年1月8日 |
#1188 in 算法
每月 25 次下载
30KB
619 行
规则空间哈希
这是一个实验,旨在确定是否可以通过修改二维空间哈希的算法来减少查询的空间。具体来说,不是查询立方体网格,而是使用规则三角形网格或六边形网格可能会带来一些好处,如下所示。
为什么是其他类型的规则镶嵌?
大多数实现使用立方体网格(右和红)。我们感兴趣的是提高围绕一个点的圆形查询的效率。具体目标是要最大化 query_radius/total_area_searched
。由于 query_radius
是固定的,问题变成了最小化 total_area_searched
。在某个半径内,只需要搜索直接相邻给定点块的邻居,所以这个案例是重点,因为许多用例,如粒子碰撞检测,使用固定半径。
对于正方形网格,面积效率是 r : 9r^2
,这实际上是基线,因为它是最常见的。
对于六边形网格,面积效率是 r : 7 * 3√3/2 r^2 = 18.18
。
而对于三角形网格,面积效率是 r : 13/√3 r^2 = 7.505 r^2
。注意,这里的 r
对应于等边三角形的高度,而不是其边长。
因此,使用三角形网格可以提高面积效率的微小改进。
区域效率很重要,因为它与必须在一定距离内检查的点数直接相关。例如,如果点均匀分布,我们预计点的数量将与总搜索区域成正比。因此,通过减少给定查询的搜索区域,我们应该获得大约相等的加速。
区域效率真的重要吗?
现在的问题是,区域效率是否实际上对提高实际运行时间有影响,而不仅仅是理论上。
为什么可能不起作用?
- 额外的开销
- 由于单个三角形有更多的邻居,哈希可能会成为开销
- 由于邻居更多,可能会有更多的哈希冲突,因此有更多的误报。
由于有支持和反对的理由,因此有必要仅对其进行基准测试。
实践中的结果
注意:虽然这些结果很有趣,但对于第一次实现来说,从正方形切换过来可能没有太大的好处。
为了比较每种空间哈希的有效性,我制作了一个简单的plinko玩具,它在均匀分布的桩子之间掉落许多球。球(目前)不会相互碰撞,但会与桩子碰撞,因此必须在每一步检查它们的交集。为此,我使用空间哈希,我的实现使用枚举来指定使用哪种坐标系。然后,在运行时,它只需使用每组坐标初始化桩子,并运行演示。
在演示中,有3个报告值
- FPS:每秒帧数,它与准备每帧的速度相关
- #Checks:实际检查的交集对数,即使它们被拒绝
- 以及每帧持续时间的毫秒数,它报告了计算每帧所需的时间。
我们发现#检查
直接对应于区域差异,立方体大约为14k,三角形为11k,六边形为28k。因此,如果点对点交集检查是使用立方体空间哈希时的瓶颈,则切换到三角形坐标系可能是个好主意。
然而,我们发现这并不直接与演示的速度相关,发现六边形的速度最快,尽管需要更多的检查。这可能是由于对六边形的邻居进行哈希所需的时间是立方体的7/9
,而三角形是13/9
。由于球的数量相对较多,这也成为一个瓶颈。如果我们查询的是单个点与更多的桩子,我们可能会发现不同的结果。
因此,在实际考虑使用哪种方法时,最好对这三种方法都进行基准测试,看看哪种方法真正做得好。
方法论
为什么必须规则?
你可能还会问的一个问题是,为什么铺贴只限于三角形、六边形和正方形?这是因为它们是二维平面上唯一的规则多边形铺贴。
为什么规则铺贴很好?有几个关键特性使得规则性很好。
- 首先,没有一块砖与下一块不同,因此不需要特殊处理。
- 其次,在规则铺贴中确定砖块的邻居很容易。
并且对于实际用途
- 规则铺贴比随机铺贴更容易理解,因此有博客和现有的实现。
- 规则铺贴很容易理解,并且是对称的。不清楚不规则铺贴能带来什么好处。
这扩展到3D吗?
尽管这个实现仅适用于二维,下一个显而易见的问题就是三维空间哈希是否能从中受益。
答案不是立即肯定,因为唯一能镶嵌三维空间的正多面体(多边形的3D等价物)。相反,它可以很容易地扩展到六边形和三角形棱柱。三维空间哈希可以使用六边形哈希来表示两个维度(即X和Y),而在第三个维度(Z)使用网格间距。这仍然会导致更高的体积效率。
资源
- 维基百科。