マンデルブロ集合(3) -外側のループ-
マンデルブロ集合を描くプログラムを書く場合、二重のループ構造を取ることになります。
そのループとは以下のふたつです。
- 外側のループは、複素数 c の集合を得るために離散的な複素数を順次評価するループ
- 内側のループは、漸化式が発散するか否かを評価するためのループ
前回は内側のループの話をしました。今回は外側のループの話。
漸化式 zn+1 = zn ^ 2 + c
前々回、漸化式における c を順次変えながらその都度、内側のループを実行するということで、以下のような模式を示しました。
for(var c = cの初期値; c < cの最大値; c++){
発散評価のルーチン
}
複素数はそのまま扱えないので、実際にコード化する場合、模式のようなわけにはいきません。
じゃあどう書くのか。
ここで出てくるのがガウス平面。
ガウス平面は、とある複素数を、横軸に実数値、縦軸に虚数値を割り当てることで、複素数の位置関係をビジュアル化できます。
それは、とある座標を、横軸に X、縦軸に Y を割り当てることで、その座標の位置関係をビジュアル化するデカルト平面と同じ。
つまり今回の課題は、平面の全座標を走査するのと同じように考えれば良いわけ。例えば画像を走査して各ピクセルに何か処理をおこなうときのようなコードと同じ。以下みたいな感じの。
for(var y:int = 0; y<100; y++){
for(var x:int = 0; x<100; x++){
処理
}
}
上では開始座標を (0, 0)、終了座標を(100, 100)、インクリメント値を X軸・Y軸 それぞれ 1 としていますが、マンデルブロ集合 c を評価するときには、それぞれの値はいくつに設定すればいいんでしょうか。
wikipedia のマンデルブロ集合の項にある図を見ると、実軸(横軸)では最小値が -2、最大値が 1(実際は 0.5 くらい)。虚軸(縦軸)では最小値が -1、最大値 1。このごくごく狭い範囲の中でマンデルブロ集合全体が描かれることがわかります。
前回、発散評価の説明で、複素数の絶対値が2を超えると以降必ず発散するという話をしましたが、たぶんそれが理由なんだと思います。
とりあえず今回は実軸(X軸)、虚軸(Y軸)ともに最小値が -2、最大値が 2 の 4×4 の範囲で計算するということにしましょう。
あとは実軸・虚軸それぞれのインクリメント値ですが、ステージのサイズとの兼ね合いになります。例えばステージサイズを 400×400 にした場合、-2~2 を 400 ピクセルで表せばいいんだから 4÷400 = 0.01 になります。
すると以下のようになります。前回同様パフォーマンス的に問題のある書き方をしていますが、今回も説明を分かりやすくするための処置です。
var cRl:Number; // (1)
var cIm:Number; // (2)
for(var y:Number = -2; y<=2; y+=0.01){
for(var x:Number = -2; x<=2; x+=0.01){
cRl = x;
cIm = y;
(内側のループでコード化した部分)
}
}
(1) と (2) は漸化式の c に関わる値で、(1) が実数部、(2) が虚数部です。
このループが回るたびに c の値は変わり、その c の値でもって発散の評価をおこなう。そういう流れになります。
[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!
