リアプノフ・フラクタル
ロジスティック写像を拡張したフラクタルにリアプノフ・フラクタル1というものがある.
一定の手順でこれは描画ができるので、今回はこれを見ていこう.
まず最初に適当な長さのABからなる文字列を生成する.
,として考えると、Wikiのに合わせてあげると以下のようになる.
この文字列をN回繰り返した文字列を生成すればOK.
今回は試しに200個のを並べるようなコード例を以下に書いてみた.
const int loop = 200;
for (int32 n = 0; n < loop; ++n)
{
for (int i = 0; i < MaxIter; i++)
{
// 200回の周期で生成
auto s = sequence[i];
}
}
これをピクセル単位で選択するので、以下のように生成すればよい.
生成した後は
lyapunovという関数に渡して、計算をしていくことになる. for (int i = 0; i < resolution.x; i++)
{
double a = Clamp(static_cast<double>(i) / resolution.x * 4.0, 0.0, 4.0);
for (int j = 0; j < resolution.y; j++)
{
double b = Clamp(static_cast<double>(j) / resolution.y * 4.0, 0.0, 4.0);
// 計算
auto lm = lyapunov(a, b);
// ...
}
}
lyapunov内を見ていこう.
初期値はとする.
結果は和を取っていったものなので、resultとして用意しておく.
周期を最初に述べたように取っていくが、ならを選択,ならを選択とする.
この結果をとして保存しておこう.
for (int32 n = 0; n < loop; ++n)
{
for (int i = 0; i < MaxIter; i++)
{
// rnをAABABの周期で選択
double rn = sequence[i] == 1 ? a : b;
// ...
}
}
後はを計算していくことになるが、これは以下のように定義される.
という風に足し合わせてあげればよい.
リアプノフはの値で色を塗り分ける.
なら安定、ならカオスなので、これを基準に塗ればよい.
// 計算
auto lm = lyapunov(a, b);
// 色付け
if (lm > 0)
{
double value = Clamp(lm, 0.0, 1.0);
image[j][i] = ColorF(1.0, value, value);
}
else
{
double value = Clamp(Exp(lm), 0.0, 1.0);
image[j][i] = ColorF(value, value, 1.0);
}
こうして得られた結果は以下のようになる.
うん、いい感じに描画できた.
一応条件はWikiのものに揃えたけど、見た目が若干違うので、どこか間違ってるかもしれない.
文字列は今回としたが、別段他の文字でも行けるので色々試すと面白いかもしれない.