重新排列数据以适应四叉树/八叉树

6
我正在实现一个体素八叉树的光线投射器,唯一剩下的就是重新排列数据以填充八叉树的叶级别,这样数据就可以平均分配到树的较低层中。

为了方便起见,我最初考虑使用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四叉树的例子。
我无法想出如何做到。我的主要问题是处理任意树大小。如果我事先知道大小,我可能可以硬编码一组嵌套的循环,但这显然不是一个好的或优雅的解决方案。我在考虑可能有一种递归方式来实现它。
这是我用于按照第一张图片描述的方式对数据进行排序的快速而肮脏的草图。它基本上通过跟踪原始数据中的四个位置,然后将这些位置向前移动,以填充新数组。据我所知,这样做是有效的,但不能满足我的需求。
 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]);
  }

展示一下你尝试过的内容。 - Jim Mischel
2
看起来有点像Z顺序曲线(http://en.wikipedia.org/wiki/Z-order_curve),考虑到你正在谈论四叉/八叉树,这是有道理的。话虽如此,我不确定你在问什么。 - phs
添加了我尝试过的内容和一些进一步的澄清。它看起来确实像是一个Z顺序曲线!我还在考虑创建一个代理树,遍历它并使用该顺序填充新结构可能会更容易。 - Victor Sand
1个回答

4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接