マンデルブロ集合(4) -暫定コード-
過去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!
