Tesseral算术/四叉树

时间:2012-02-18 07:12:51

标签: bit-manipulation quadtree

我做了一个项目,一段时间回到路径寻找与四胞胎,我想改善其性能。似乎使用tesseral算法确定节点邻接(根据this page,由不列颠哥伦比亚大学地理系提供)将比我目前使用的强力方法快得多(我' m检查共享边缘,这适用于静态四叉树,但如果地图正在改变则会产生太多开销)。

我或多或少地理解在Adjacency Algorithm部分中所说的内容,但我不确定如何开始。我主要对C#感兴趣,但是如果已经有一些源代码可以用来处理我可以看到的tesseral算法,无论语言如何,它都会很棒。否则,任何人都可以给我一些关于处理加/减进位的指示吗?

2 个答案:

答案 0 :(得分:4)

好吧,我不知道有效地做到这一点,但通常的“按位操作添加”算法建议使用以下算法(未经测试):

static int tesseral_add(int x, int y)
{
    int a, b;
    do
    {
        a = x & y;
        b = x ^ y;
        x = a << 2; // move carry up 2 places instead of the usual 1
        y = b;
    } while (b != 0);
    return b;
}

如果有携带链,可能会循环很多。


实际上,有一种更好的方法可以做到这一点。

观察z = interleave(a, -1); w = interleave(b, 0);,直接添加zw会得到部分正确的结果,因为任何进位都会重新进位(所有“中间”位都是1) 。唯一的“问题”是它会破坏y坐标。

所以要添加两个tesseral数字z = interleave(a, b); w = interleave(c, d);,有一个很好的简短方法:

int xsum = (z | 0xAAAAAAAA) + (w & 0x55555555);
int ysum = (z | 0x55555555) + (w & 0xAAAAAAAA);
int result = (xsum & 0x55555555) | (ysum & 0xAAAAAAAA);

答案 1 :(得分:2)

我认为,处理tesseral算术的最简单方法是“bit-unzip”数字,正常执行任意数量的算术运算,并在需要tesseral形式时将其“bit-zip”:

z = bit_zip(bit_unzip(x) + bit_unzip(y));

(此示例仅适用于unsigned。对于有符号整数,请将每个数字解包为两个变量,并分别对这两个部分进行常规算术运算。)

您可以在“Matters Computational ”中找到“bit-unzip”和“bit-zip”的快速实现,第1.15节“按位压缩”。