均一にサンプリングされた3Dメッシュにfloat値を格納するためのデータ構造が必要です。
x = x0 + ix * dxここで、0 <= ix <nx
y = y0 + iy * dyここで、0 <= iy <ny
z = z0 + iz * dzここで、0 <= iz <nz
これまで、Arrayクラスを使用してきました。
Array3D<float> A(nx, ny,nz);
A(0,0,0) = 0.0f; // ix = iy = iz = 0
内部的には、float値をnx * ny*nz要素を持つ1D配列として格納します。
ただし、RAMよりも多くの値でメッシュを表す必要があります(例:nx = ny = nz = 2000)。
そのようなメッシュ内の多くの隣接ノードは同様の値を持っている可能性があると思うので、メッシュを適応的に「粗く」することができる簡単な方法があるかどうかを考えていました。
たとえば、このメッシュ内のセルの8つの(ix、iy、iz)ノードの値の間隔が5%未満の場合。それらは「削除」され、1つの値に置き換えられます。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など)でも
- 3倍を超える非常にハードに圧縮します。かなりの情報が失われてもかまいません。
良い候補はありますか?