重新排列四叉树/八叉树的数据

时间:2013-03-26 23:17:21

标签: algorithm sorting quadtree octree

我正在努力实现体素八叉树raycaster,剩下的唯一事情是重新排列数据以填充八叉树的叶级别,以便可以对数据进行平均以构建树的较低级别。

为了方便起见,我在2D(四叉树)中思考。我的数据如图中左侧所示,我现在能够像右边那样重新排列。示例是8x8

Current

但是,我意识到我需要按节点顺序排序数据,如下图所示:

Wanted

换句话说,我想从一个数据对应于这样的索引的数组:

[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]);
  }

1 个答案:

答案 0 :(得分:4)

对于我说的问题, phs 暗示我称它为Z阶曲线。多亏了这一点,我发现了这个问题:Z-order-curve coordinates,其中给出了2D案例的算法。我尝试过,它的确有效。

以下是3D案例的一些实现:How to compute a 3D Morton number (interleave the bits of 3 ints)