Illustratorでジェネラティブアートを作ってみる5
バーンズリーのシダ
バーンズリーのシダ(Barnsley Fern)は、アフィン変換 を用いたフラクタルの一種なんですけど、わたしが色々書くよりWiki読んでもらったほうが理解が進むと思うので、詳細に関しては
https://ja.wikipedia.org/wiki/バーンズリーのシダ
こちらをご参照ください。
今回のスクリプトはフラクタルを作成するための反復関数系(IFS:Iterated Function System)の有名な例となります。
平面座標系でバーンズリーが示した係数を用いれば全く同じ表現が再現できます。本当はコラージュの定理等重要な概念があるのですが、この処理では初期値からの確率的選択で次々に写像をプロットしていくという反復処理によるものなので処理自体に難しさはありません。
手順
1. 初期点 (x, y) = (0, 0) を設定
2. 確率的に4つのアフィン変換のいずれかを適用して茎・一次葉・二次葉・三次葉の点を決定しプロット
3. 以降規定の回数まで繰り返し
以上を数万回繰り返すとプロットされた写像はシダの葉を模した自己相似形の形状を示します。
コードは以下のように至ってシンプルです。
//Barnsley Fern
var lyr = app.activeDocument.layers.add();
lyr.name = "Barnsley Fern";
var iterations = 20000;
var x = 0, y = 0;
// 色設定
var green = new CMYKColor();
green.cyan = 50;
green.magenta = 0;
green.yellow = 80;
green.black = 0;
// シダの描画
for (var i = 0; i < iterations; i++)
{
var r = Math.random();
var nextX, nextY;
if (r < 0.01)
{ // root
nextX = 0;
nextY = 0.16 * y;
}
else if (r < 0.86)
{ // 1st
nextX = 0.85 * x + 0.04 * y;
nextY = -0.04 * x + 0.85 * y + 1.6;
}
else if (r < 0.93)
{ // 2nd
nextX = 0.2 * x - 0.26 * y;
nextY = 0.23 * x + 0.22 * y + 1.6;
}
else
{ // 3rd
nextX = -0.15 * x + 0.28 * y;
nextY = 0.26 * x + 0.24 * y + 0.44;
}
x = nextX;
y = nextY;
var px = 250 + x * 50;
var py = -100 - y * 50;
var pt = lyr.pathItems.ellipse(py, px, 1, 1);
pt.filled = true;
pt.fillColor = green;
pt.stroked = false;
}
先のリンク先に写像を計算するアフィン変換の詳細がありますが、これらのパラメータを確率的に選択して写像を得るという流れをif文による振り分けで書いています。もうちょっとスマートに書けそうですけど、誰でも読みやすい構成ということでこうしました。
このようなIFSによるフラクタル処理ではコラージュの定理とかハウスドルフ距離なんてものが知識として必要になるんですけど概念自体が結構ややこしくって難解なものです。
コラージュの定理(Collage Theorem)とは?
コラージュの定理 は、フラクタルを近似する自己相似写像の集合を見つける方法を提供する定理。
特に IFS(Iterated Function System:反復関数系) を使ったフラクタルの構成において重要な役割を果たします。
ハウスドルフ距離(Hausdorff Distance)とは?
ハウスドルフ距離は、2つの集合(主に点集合)の間の 最大の最小距離 を測る指標です。
特に、形状の類似性を評価 するのに使われ、画像認識や形状解析などの分野で応用されています。
定義
2つの集合 𝐴 と𝐵 があるとし、各点 𝑎∈𝐴 について、集合 𝐵 の中で最も近い点までの距離を求め、その中で 最大の最小距離を取る。これを 𝑑𝐻(𝐴,𝐵)とする。逆に各点 𝑏∈𝐵 について、集合 𝐴 の中で最も近い点までの距離を求め、最大値を取る。これらのうち 最大の値がハウスドルフ距離 となる。
2つの形(点集合)があるとき、どちらか一方の形からもう一方の形までの最も遠い 最近接点 の距離を測る。
非常に乱暴な書き方をすると「値が大きい場合形状が大きく異なり、小さい場合形状がよく似ている。」となりますが、他にも様々な関連する概念があったりするので、フラクタル関連を触る時にとっても苦労します。
このあたりは情報を読む際に必要になる部分なんですけど、コードに落とし込む際には直接関係しませんので、暇な時にじっくり読み込むことをお勧めしておきます。
ちなみにトップのイメージは30万回まわしています。