【发布时间】:2013-05-19 17:30:24
【问题描述】:
当我遇到这个问题时,我很想创建一个稀疏的八叉树实现,就像 nVidia ("Efficient Sparse Voxel Octrees") 的人们正在为他们的体素所做的那样:
我有一个字节类型的位域(所以只有 8 位),它告诉我八叉树的叶子在哪里(1 表示叶子,0 表示没有叶子,连接了 8 个节点 --> 8 位)。我现在要做的是返回一个叶子位置的数组。我当前的实现是使用一个while循环来确定是否设置了LSB。之后输入移位 1。所以我是这样做的:
int leafposition = _leafmask & _validmask;
int[] result = new int[8];
int arrayPosition = 0;
int iteration = 0;
while ( leafposition > 0 )
{
iteration++; //nodes are not zero-indexed ... ?
if ( (leafposition & 1) == 1 ) // LSB set?
{
result.SetValue( iteration, arrayPosition );
arrayPosition++;
};
leafposition = leafposition >> 1;
}
return result;
这看起来并不优雅,并且有两点令人不安:
- 这个 while 循环模仿了一个 for 循环
- 结果数组很可能小于 8 个值,但调整大小的成本很高
我希望结果类似于[2,4,6] for 42 (0010 1010)。
谁能提供一个更优雅且可读的解决方案?
结果
我正在使用我之前实现的八叉树叶计数函数来将数组设置为适当的大小。
【问题讨论】:
-
重新分配数组并没有那么慢。对于您的目的而言,它是否太慢是另一回事(因为这可能是经常调用的内部循环代码)。您可以考虑首先计算汉明权重(位数设置为 1),以便您可以分配适当大小的数组,并测量这两种方法。 stackoverflow.com/questions/109023/…
-
你知道,这就是我在这里问的原因。我写的最后一个方法就是尽可能快地获得叶子数......不敢相信我这样做时没有考虑我自己的代码。非常感谢您提出最明显的想法!
标签: c# bit-manipulation bit-shift octree