マンデルブロ集合(4) -暫定コード-

2011 / 02 / 07 by
Filed under: Coding の素 
Bookmark this on Delicious
[`livedoor` not found]
[`yahoo` not found]

過去3回を踏まえてコードを書くと以下のようになります。
しかしこのコード、マンデルブロ集合図描画の考え方を何のひねりもなくコードにしたものなので、実用性にはかなり問題あり。
たとえば複素数平面を走査する二重ループの部分(23、24行目)でインクリメント値が小数にしているため、ステージ幅・高によっては、正常に描画されません。インクリメントループのインクリメント値はやはり整数でないダメですね。

package {
  import flash.display.Bitmap;
  import flash.display.BitmapData;
  import flash.display.Sprite;
  [SWF(width = "500", height = "500", frameRate = "30", backgroundColor = "#000000")]
  
  public class Mandelbrot extends Sprite {
    
    public function Mandelbrot() {
      var w:int = stage.stageWidth;
      var h:int = stage.stageHeight;

      var bmd:BitmapData = new BitmapData(w, h, false, 0x000000);
      addChild(new Bitmap(bmd));
      
      var colors:Vector.<uint> = new Vector.<uint>();  // 発散までにかかったループ回数による色分けのための色を格納する Vector
      for (var i:int = 0; i < 256; i++) colors.push(0xFF << 16 | i << 8 | i);
      
      var data:Vector.<uint> = new Vector.<uint>();
      var cRl:Number;  // 漸化式 c の実数部
      var cIm:Number;  // 漸化式 c の虚数部
      var step:Number = 4 / w;
      for (var y:Number = -2; y <= 2; y += step) {
        for (var x:Number = -2; x <= 2; x += step) {
          var zRl:Number = 0.0;  // 漸化式 z_n の実数部
          var zIm:Number = 0.0;  // 漸化式 z_n の虚数部
          var zRlNext:Number;    // 漸化式 z_n+1 の実数部
          var zImNext:Number;    // 漸化式 z_n+1 の虚数部
          var loop:int = 256;
          while (loop--) {
            cRl = x;
            cIm = y;
            if (Math.sqrt(zRl * zRl + zIm * zIm) > 2) break;  // 発散したら while を離脱
            zRlNext = zRl * zRl - zIm * zIm + cRl;
            zImNext = 2 * zRl * zIm + cIm;
            zRl = zRlNext;
            zIm = zImNext;
          }
          var color:uint = (loop == -1) ? 0x000000 : colors[loop];  // while が break されなかったときは 0x000000
          data.push(color);
        }
      }
      
      bmd.setVector(bmd.rect, data);
    }
  }
}

実行結果で示されているもののうち、黒い部分がマンデルブロ集合に該当する部分です。
で、それ以外の赤や白の部分は発散した部分です。赤が濃いほど発散評価の部分でループを繰り返していることになります。

ひとつ捕捉。

発散した(マンデルブロ集合でなかった)場合、何色にするのかというのは、あらかじめ Vector 型の変数 colors を用意しておき(16、17行目)、発散評価ループ(30~38行目)での変数 loop の値を colors のインデックスとして値を取り出し、色を決めるというやり方をしています。なので colors の length (17行目)と loop の初期値(29行目)はそろえないといけません。
黒い部分がマンデルブロ集合だと言いましたが、マンデルブロ集合だということは、発散評価のループで break が実行されなかった、ということです。つまりそのときの変数 loop (29行目で定義して、30行目の while でデクリメントしている変数)の値は -1 になっています。
Vector 型変数のインデックスに -1 は当然取れませんから、その場合の色の決定は colors から取得するのとは別のプロセスが必要であるため、39行目のような三項条件式になるわけです。

[ad#aquioux_net_article]



Comments

Tell me what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!





WP-SpamFree by Pole Position Marketing