甜甜圈2D空间的二进制空间划分数据结构

时间:2011-11-06 01:08:49

标签: c# algorithm data-structures space-partitioning

我有一个包裹在边缘的2D地图。因此,如果您离开右边缘,您将重新出现在地图的左侧。与其他三条边相同。

这是KDTree的遗传问题,我用它来查找点范围内的元素。通常你会检查超球是否与超平面碰撞,看看你是否应继续搜索树的另一面,但这种检查不适用于包边。

有没有办法修改KD树以使用甜甜圈2D空间?

3 个答案:

答案 0 :(得分:3)

数据结构不必更改,但搜索过程可以。用[0,w)* [0,h)中的坐标(x,y)表示每个点,其中w是地图的宽度,h是高度,*表示笛卡尔乘积。将这些点存储在普通的KD树中。

在给定点(x,y)和矩形[a,b] * [c,d]的情况下,搜索KD树的基本原语确定从点到矩形的距离(平方)。通常这是g(x,a,b) 2 + g(y,c,d) 2 ,其中

g(z, e, f) = e - z if z < e
             0     if e <= z <= f
             z - f if f < z

是z与[e,f]的一维距离。在环形空间中,我们稍微修改g以考虑环绕。

g(z, e, f, v) = min(e - z, (z + v) - f) if z < e
                0                       if e < z < f
                min(z - f, (e + v) - z) if f < z.

并且距离的平方是g(x,a,b,w) 2 + g(y,c,d,h) 2 。我希望这种变体的运行时间具有可比性。 (我会重做复发,但是常规KD树的最坏情况比大部分时间更糟糕--O(n 1/2 )用于识别n中的最近邻居点。)

答案 1 :(得分:2)

Jitamaro建议但没有解释基于“2x大小”四叉树的方法。这是一个合理的建议,除了四叉树使用四倍的节点而不是两个,我将在下面解释之前暂时建议另一种方法。

假设每个(x,y)坐标都有-.5 < x <= .5-.5 < y <= .5,并且每当j, k是整数时,点(x + j,y + k)与点(x, Y)。设四边形T覆盖坐标范围为-1 < x,y <= 1的点。每次在(x,y)向T -.5 < x,y <= .5添加项目时,x' = {x-1 x>0 x+1}y' = {y-1如果{y>0 1}}其他y+1}。同时在(x,y'),(x',y')和(x',y)处添加项目。 [当您稍后删除点时,再次计算(x',y')等并删除它们。]很容易看到最近点查找将正常工作,只要在区间(-.5,.5]之外的任何查找坐标都可以调整得当。

如果四倍数量的节点是一个交易破坏者,请注意,如果上面描述的坐标用于上面的水平k=3,并且相对坐标存储在水平k以下,应该可以在级别k以下维护单个子树副本。也就是说,级别k的每个子树都有四个父级。 (我没有想过这足以知道这是否完全有效;如果我发现它没有,我会编辑答案。)

答案 2 :(得分:0)

四叉树是具有4片叶子的KD树。四叉树无助于换行,因为它的数据结构本身就是换行。您只需要使用结构的四倍树大小。