barnsley_fern.png


バーンズリーのシダ

 一応、フラクタルの一種(?)なのでしょうか?バーンズリーのシダと呼ばれるグラフィックを描画して、これをレイトレーシングのモチーフとして使ってみます。

計算方法

 下図がバーンズリーのシダと呼ばれるグラフィックです。

barnsley_fern.png

※都合により、時計回りに90°寝かせてあります。以下文章中の右とか左と言った表現にはご注意ください。寝かせる前の画像に対して述べています。

 確かに、シダ植物の葉っぱに似たグラフィックが表示されています。でもこれ、ある規則に従って描画された、ただの点の集合なのです。ただの点の集合なのに、そこここに自己相似図形が見えているのが不思議です。

 フラクタルの中には、再帰的に図形を描画しながら画像を生成して行くものが多いのですが、バーンズリーのシダは、ちょっと違っています。全体に満遍なく点が打たれて行って、ある程度点の数が増えてくると、上図の様な図形が見えてきます。
 このまま繰り返し回数を増やしていくと、上図葉っぱの先端の様に、白い部分がすべて点で埋め尽くされていくのではないでしょうか??

アフィン変換

 バーンズリーのシダを描画するための規則を説明する前に、二次元空間のアフィン変換(拡大・縮小、回転、平行移動など)について説明が必要です。
 二次元空間の図形をアフィン変換するには、点(x,y)を点(x’,y’)に変換する以下の様な数式を使用します。

affine_2d.png

 高校数学で勉強する代数幾何学の行列演算です。変数a〜fは、以下の様に設定します。

 アフィン変換と一口で言っても、この次元では、回転や相似変換(行列)と平行移動(加算項)を別々に計算する必要があって、ちょっと扱いにくいのです。そこで、敢えて一次元格上げして以下の様に扱うことがあります。

affine_3d.png

 各々、行列演算を展開して比べてみると、同じ意味の数式であることが解ると思います。

 バーンズリーのシダは2Dの図形なので、二次元空間で説明しましたが、Xi-TRACEは三次元空間に物体を配置するソフトウェアですので、3Dのアフィン変換をサポートしています。二次元の場合と同様に一次元格上げして、4×4行列を使って三次元空間のアフィン変換を実施しています。
 今回使用する二次元のアフィン変換は、三次元アフィン変換のサブセットなので、変換行列を以下の様に対応することで、Xi-TRACEの三次元アフィン変換機能(4×4行列)を使って計算させようと思います。

affine_4d.png

バーンズリーのシダ生成規則

 バーンズリーのシダに戻りましょう。
 バーンズリーのシダでは、点を打つ座標を(x,y)と置きます。(x,y)の初期値は(0,0)です。次に点を打つ座標(x’,y’)は、以下に示すf1〜f4の数式でアフィン変換をかけて求めます。

f1_4.png

 正直、数式だけ見せられても、何の事やらさっぱりわかりません。が、以下の様な確率でランダムにf1〜f4を適用して行くと、最初に示したようなシダの葉っぱに見える図形が生成できるのです。不思議。

 数式そのものにはランダムな要素は含まれておらず、次の点(x’,y’)を計算するためのf1〜f4を選択する時に乱数を使います。
 新しい座標(x’,y’)に点を打ったら、(x,y)=(x’,y’)として、同じことを何回も繰り返します。

Xi-TRACEのデータに落とす

 アフィン変換の所で触れた様に、Xi-TRACEには4×4行列を使ってアフィン変換を実施する機能が備わっていますので、行列演算はXi-TRACEに丸投げしてしまうことが出来ます。

  // affine transform
  nx=px;
  ny=py;
  nz=0;
  rn=rnd (1);
  if (rn<pr1)
  {
    // f1: 茎
    matrix 0.00,  0.00,  0,    0.00,
        0.00,  0.16,  0,    0.00,
        0,    0,    1,    0,
        0,    0,    0,    1;
    linear nx,ny,nz;
  }
  elif (rn<pr1 + pr2)
  {
    // f2: 左葉
    matrix 0.20,  -.26,  0,    0.00,
        0.23,  0.22,  0,    1.60,
        0,    0,    1,    0,
        0,    0,    0,    1;
    linear nx,ny,nz;
  }
  elif (rn<pr1 + pr2 + pr3)
  {
    // f3: 右葉
    matrix -.15,  0.28,  0,    0.00,
        0.26,  0.24,  0,    0.44,
        0,    0,    1,    0,
        0,    0,    0,    1;
    linear nx,ny,nz;
  }
  else
  {
    // f4: 小葉
    matrix 0.85,  0.04,  0,    0.00,
        -.04,  0.85,  0,    1.60,
        0,    0,    1,    0,
        0,    0,    0,    1;
    linear nx,ny,nz;
  }


 この処理によって、今の座標(x,y)=(px,py)から、次の座標(x’,y’)=(nx,ny)を計算しています。matrix命令でアフィン変換行列(4×4行列)を指定し、予め(nx,ny,nz)に元の座標を代入しておいたら、linear命令でアフィン変換を実施しておしまいです。
 Xi-TRACEは三次元空間なので、z座標nzを指定する必要があるのですが、nzは常に0なので無視して構いません。

 上の処理1回で1個の点(nx,ny)を打つことが出来ます。シダの葉に見えるようになるためには、この処理を何千回か繰り返して、数1,000個の点を打つ必要があります。繰り返し回数は、画像の解像度や打つ点の大きさなどで最適値が異なるので、綺麗に見えるパラメータを探ってみてください。
 上で示した図形は、480×480ドットの画面に、約50,000個の点をプロットして作図した物です。

 「不思議だな」と、思った描画中の様子を動画にしておきます(↓)。



完成データ

 完成したデータをリンクしておきます。

1) Xi-TRACEデータ barnsley_fern.xitr
2) Xi-TRACEデータ barnsley_fern_2d.xitr

 2)のデータは、普通に二次元の「バーンズリーのシダ」を描画します。
 1)は、「バーンズリーのシダ」を3D化してレイトレーシングするためのデータです。レイトレーシングした動画を以下に示します。



 3Dと言うより、2.5Dと言ったところですね……(1^^;)。


home

download

gallery