自适应“均匀”网格的数据结构和算法?

时间:2013-02-13 21:18:59

标签: computational-geometry

我需要一个数据结构来将浮点值存储在均匀采样的3D网格中:

x = x0 + ix * dx其中0 <= ix&lt;为nx

y = y0 + iy * dy其中0 <= iy&lt; NY

z = z0 + iz * dz其中0 <= iz&lt; NZ

到目前为止,我已经使用了我的Array类:

Array3D<float> A(nx, ny,nz);
A(0,0,0) = 0.0f; // ix = iy = iz = 0

在内部,它将浮点值存储为具有nx * ny * nz元素的一维数组。

但是现在我需要用比RAM更多的值表示网格, 例如nx = ny = nz = 2000。

我认为这样的网格中的许多邻居节点可能具有相似的值,所以我在想是否有一些简单的方法可以使我能够#34;粗糙&#34;网格自适应。

例如,如果此网格中单元格的8(ix,iy,iz)节点的值小于5%;他们被删除&#34;并仅用一个值代替; 8个值的平均值。

我怎样才能以简单有效的方式实现这样的数据结构?

编辑: 感谢Ante建议有损压缩。我认为这可以通过以下方式工作:

#define BLOCK_SIZE 64
struct CompressedArray3D {
    CompressedArray3D(int ni, int nj, int nk) {
        NI = ni/BLOCK_SIZE + 1;
        NJ = nj/BLOCK_SIZE + 1;
        NK = nk/BLOCK_SIZE + 1;

        blocks = new float*[NI*NJ*NK];
        compressedSize = new unsigned int[NI*NJ*NK];
    }

    void setBlock(int I, int J, int K, float values[BLOCK_SIZE][BLOCK_SIZE][BLOCK_SIZE]) {
        unsigned int csize;
        blocks[I*NJ*NK + J*NK + K] = compress(values, csize);
        compressedSize[I*NJ*NK + J*NK + K] = csize;
    }

    float getValue(int i, int j, int k) {
        int I = i/BLOCK_SIZE;
        int J = j/BLOCK_SIZE;
        int K = k/BLOCK_SIZE;

        int ii = i - I*BLOCK_SIZE;
        int jj = j - J*BLOCK_SIZE;
        int kk = k - K*BLOCK_SIZE;

        float *compressedBlock = blocks[I*NJ*NK + J*NK + K];
        unsigned int csize = compressedSize[I*NJ*NK + J*NK + K];

        float values[BLOCK_SIZE][BLOCK_SIZE][BLOCK_SIZE];
        decompress(compressedBlock, csize, values);
        return values[ii][jj][kk];   
    }

    // number of blocks:
    int NI, NJ, NK;

    // number of samples:
    int ni, nj, nk;

    float** blocks;
    unsigned int* compressedSize; 
};

为了使这个有用,我需要一个有损压缩:

  • 速度非常快,也适用于小型数据集(例如64x64x64)
  • 压得很硬&gt; 3x,没关系,如果它失去了相当多的信息。

有什么好的候选人吗?

2 个答案:

答案 0 :(得分:1)

听起来你正在寻找LOD(细节水平)自适应网格。这是视频游戏和地形模拟中反复出现的主题。

对于地形,请参见此处:http://vterrain.org/LOD/Papers/ - 查找IIRC的ROAM视频,不仅可以按距离自适应,还可以按视角方向自适应。

对于非地形实体,有大量的工作(这里有一个例子:http://http.developer.nvidia.com/GPUGems3/gpugems3_ch05.html)。

答案 1 :(得分:0)

我建议使用OctoMap来处理大型3D数据。 并按照here所示扩展它以处理几何属性。