Processing で、セル オートマトンを任意の数の次元 (合計、最近傍、ムーア近傍) でシミュレートするプログラムを作成しました。物事を単純化し、プログラムをできるだけ一般的なものにするために、セルの状態を 1 次元の整数配列に格納します。セルの n 次元の隣接セルを計算するために、1 次元配列をラスター順序として扱います (最初の座標をゼロから問題の空間のサイズまで反復し、次の座標を 1 ずつインクリメントし、最初の座標を反復します)。もう一度、など。)
コンピュータ画面の 2 次元で n 次元データを表示する洗練された方法はほとんどないため (特にこの場合、n は理論的には 2 から無限大までの範囲であり、実際には少なくとも 2 から 5 までの範囲である)、 Z オーダーを使用してみることにしましたが、この件に関して読んだことすべてが混乱し、すべての資料はデカルト座標 (x1、x2、x3...xn) の仮定から始まっているようです。私の場合はあまり当てはまりません。
私が望むのは、1 次元のセル配列の要素を別の 1 次元配列に格納し、n 次元の Z オーダーで並べ替え、その配列を 2 次元の Z オーダーで並べ替えた配列に変換できるようにすることです。表示できるようにします。私はこれを効率的な方法で実行したいと考えています (プログラムを毎秒少なくとも 0.5 フレームで実行し続けようとしていますが、これは小さなスペースでも 5 次元ではすでに困難です)。
ビット インターリービング アルゴリズムは知っていますが、32 ビット整数をオーバーフローさせずに処理に実装する方法がよくわかりません。どんな助けでも大歓迎です。詳細が必要な場合は、関連するコードを以下に示します (はい、面倒なことはわかっています。それが私の仕事です)。
void setup() {
colorMode(HSB,255);
background(0);
frameRate(10);
noStroke();
ruledensity = random(1.1);
celldensity = 0.1;
dimension = 2;
numstates = 5;
scale = 20;
rule = new int[int(pow(3.0,float(dimension)))*numstates];
cells = new int[int(pow(float(scale),float(dimension)))];
ncells = new int[int(pow(float(scale),float(dimension)))];
zorder = new int[int(pow(float(scale),float(dimension)))];
size(scale * 4,scale * 4);
for (int a = 0; a < rule.length; a++) {
if (random(1.0) < ruledensity) {
rule[a] = 1 + floor(random(numstates - 1));
} else {
rule[a] = 0;
}
}
for (int b = 0; b < cells.length; b++) {
if (random(1.0) < celldensity) {
cells[b] = 1 + floor(random(numstates - 1));
} else {
cells[b] = 0;
}
ncells[b] = cells[b];
}
}
void draw() {
background(0);
for (int x = 0; x < cells.length; x++) {
nsum = 0;
for (int ex = 0; ex <= dimension; ex++) {
for(int i = -1; i <= 1; i++) {
nsum += cells[cyclize(x + i * int(pow(float(scale),float(ex-1))),cells.length)];
}
}
ncells[x] = rule[nsum];
}