1. ホーム
  2. フラクタル
  3. 確率的反復関数

ここでは、書籍「アートで魅せる数学の世界」のp.207-209に掲載されている、確率的反復関数を用いたレヴィC曲線とドラゴン曲線を再現してみました。

確率的反復関数を用いたレヴィC曲線とドラゴン曲線

確率的反復関数を用いたレビィC曲線とドラゴン曲線です。

確率的反復関数

レヴィC曲線を描くための反復関数は別記事「反復関数」で、ドラゴン曲線を描くための反復関数は別記事「反復関数2」で、それぞれ解説しています。それらの反復関数をまとめると、以下のようになります。\[ \begin{align} f_1 &: x \to \frac{l}{4} + \frac{1}{2} (x-\frac{l}{4})-\frac{1}{2} (y-\frac{l}{4}) , \ \ y \to \frac{l}{4} + \frac{1}{2} (x-\frac{l}{4})+\frac{1}{2} (y-\frac{l}{4}) \\ f_2 &: x \to \frac{l}{4} – a \left( \frac{1}{2} (x-\frac{l}{4})+\frac{1}{2} (y-\frac{l}{4}) – \frac{l}{4} \right) + \frac{3l}{4}, \ \ y \to \frac{l}{4} – a \left( -\frac{1}{2} (x-\frac{l}{4})+\frac{1}{2} (y-\frac{l}{4}) + \frac{l}{4} \right) + \frac{l}{4} \end{align} \]ここで、\(a=-1\)のときレヴィC曲線、\(a=1\)のときドラゴン曲線となります。

通常の反復関数では、初期値として与えられた線分上のすべての点に対して\(f_1\)と\(f_2\)を実施して線分を更新し、この更新を順次繰り返していくことで図形を成長させていきました。一方、確率的反復関数では、初期値として与えられた点に対して、\(f_1\)と\(f_2\)のどちらかがランダムに選ばれて実行され、その点をプロットすることを繰り返していきます。そうすることでレヴィC曲線やドラゴン曲線を描くことができます。

ソースコード

今回作成した確率的反復関数を用いたレヴィC曲線とドラゴン曲線のプログラムのソースコードを示します。

int iteration_num = 13; // 反復回数 

void setup(){
  size(600,600);
  background(255,255,255);

  PVector center = new PVector(width/4.0, height/4.0); // 原点の座標
  float len = width/2.0; // 最初に与える線分の長さ

  // 直線を描画する
  line(center.x, center.y, center.x + len, center.y); 
  
  PImage img;
  int iter = 0;
  while(iter<iteration_num){
    // 描いた図形を一旦imgに保存する
    img = createImage(width, height, RGB);
    loadPixels();
    for(int j=0; j<img.height; j++){
      for(int i=0; i<img.width; i++){
        img.set(i, j, pixels[j*width + i]);
      }
    }
    background(255,255,255); // キャンバスを白色で塗りつぶす
    // imgの画素が黒色の場合、2つの反復変換を行ってドラゴン曲線を更新していく
    for(int j=0; j<img.height; j++){
      for(int i=0; i<img.width; i++){
        if(img.get(i,j) == color(0,0,0)){
          rect(center.x + 0.5*(i-center.x) - 0.5*(j-center.y), center.y + 0.5*(i-center.x) + 0.5*(j-center.y), 0.1, 0.1);
          rect(center.x - 0.5*(i-center.x) - 0.5*(j-center.y) + len, center.y + 0.5*(i-center.x) - 0.5*(j-center.y) , 0.1, 0.1);
        }
      }
    }
    iter++;
  }
}