我正在努力实现体素八叉树raycaster,剩下的唯一事情是重新排列数据以填充八叉树的叶级别,以便可以对数据进行平均以构建树的较低级别。
为了方便起见,我在2D(四叉树)中思考。我的数据如图中左侧所示,我现在能够像右边那样重新排列。示例是8x8
。
但是,我意识到我需要按节点顺序排序数据,如下图所示:
换句话说,我想从一个数据对应于这样的索引的数组:
[0 1 2 3 4 5 6 7 8 9 ... 63]
到具有此顺序数据的数组:
[0 1 4 5 16 17 20 21 2 3 ... 63]
表示8x8
四叉树示例。
我无法弄明白该怎么做。我的主要问题是处理任意树大小。如果我事先知道大小,我可能会硬编码一组嵌套循环,但它显然不是一个伟大或优雅的解决方案。我想可能会有一种递归方式来实现它。
这就是我用图1中描述的方式对数据进行排序的快速和脏的草图。它基本上通过跟踪原始数据中的四个位置,然后在新阵列填满时将它们向前移动来工作。据我所知,这种方法很好,但不能满足我的需求:
int w = 8;
int[] before = new int[w*w*w];
int[] after = new int[w*w*w];
for (int i=0; i<w*w*w; i++) {
before[i] = i;
}
int toFill = 0;
int front = 0;
int back = w;
int frontZ = w*w;
int backZ = w*w + w;
do {
for (int i=0; i<w/2; i++) {
for (int j=0; j<w/2; j++) {
after[toFill++] = front++;
after[toFill++] = front++;
after[toFill++] = back++;
after[toFill++] = back++;
after[toFill++] = frontZ++;
after[toFill++] = frontZ++;
after[toFill++] = backZ++;
after[toFill++] = backZ++;
}
front += w;
back += w;
frontZ += w;
backZ += w;
}
front += w*w;
back += w*w;
frontZ += w*w;
backZ += w*w;
} while (toFill < w*w*w);
for (int i=0; i<w*w*w; i++) {
println("after " + i + " " + after[i]);
}
答案 0 :(得分:4)
对于我说的问题, phs 暗示我称它为Z阶曲线。多亏了这一点,我发现了这个问题:Z-order-curve coordinates,其中给出了2D案例的算法。我尝试过,它的确有效。
以下是3D案例的一些实现:How to compute a 3D Morton number (interleave the bits of 3 ints)