マンデルブロ集合

user-pic
0

シェルピンスキのガスケット、シェルピンスキのカーペット、コッホ曲線を描いたら、次は「真打ち」のマンデルブロ集合となるのが相場だが、あいにく私は、ジュリア集合は描いたことがあるものの、マンデルブロ集合を描いたことがない。

それで、マンデルブロ集合を描く前にぽっくり死んだとしてもあまり後悔しないと思うが、とりあえず生きているうちに描こうと努力することにした。

さて、マンデルブロ集合やジュリア集合は複素力学系と呼ばれていて、複素変数をzとすると、ある複素関数fを以って、z ← f(z)のように繰り返し代入していく。特にマンデルブロ集合やジュリア集合の場合、f(z) = z2 + cのような関数を使う。cは複素定数である。

そこで、z = x + yi, c = a + biのように書き表すと、z ← f(z)は
x ← x2 - y2 + a
y ← 2xy + b
と変形される。

普通、力学系z ← f(z)というとき、zの軌跡を追ったりするが、この場合、f(z)のパラメータをいろいろ変えて、z ← f(z)がある有限の絶対値内に収まるかどうかを調べるのが、マンデルブロ集合やジュリア集合なのであった。特にそのとき、z ← f(z)の初期値z0 = 0と置き、異なるcごとに有限性をみていくのがマンデルブロ集合、cをあらかじめ決めておき、初期値z0をいろいろ変えてみるのがジュリア集合である。すなわち、当然にジュリア集合の方が多様である。歴史的にはまず、ジュリア集合があって、その後、その特殊な場合としてマンデルブロ集合が見出されたようである。

それで、ともかくとりあえず描いてみたマンデルブロ集合の画像と、そのプログラムを示す。マンデルブロ集合の画像は以下のとおりである。


ふつう、閾値を超えたループの回数で色分けするらしいのだが、そのあたりのノウハウが私はまったくないので、折角のエキゾチックなマンデルブロ集合が、田舎の案山子的な気の抜けたものになってしまっている。しかし、私の画像デザイン的センスは、プログラム的センスよりはるかに劣るのだから仕方ない。そのうち時間をみて、もう少し見るに堪えるものにしてみる。

それにしても、昔はこのような描画が、下手したら丸一日とかかかったりしたものだが、いまだと1分もかからなかったりする。時代の進歩は、少なくともこの分野では速い。

あ、そうそう、マンデルブロ集合がフラクタルである、というのは、シェルピンスキのガスケットのような相似次元を適用できないので、極めて非自明で、その次元もハウスドルフ次元などを使うしかなくて、計算も難しい。まあ、余裕があったら、そのうち勉強してみる。

あと、下記のコードで、

tx = x*x - y*y + a;
ty = 2.0*x*y + b;
x = tx;
y = ty;
のようにいったん仮変数tx, tyに代入するのは本質的で(じつはtyは余計だが)、こうしないと、次ステップの値であるxが、いきなり次の式に代入されて計算が狂う。そんな初歩的なミスを犯す人はいないと思うが(私だよ!)、一応念のため記しておく。じつは、このミスをすると、マンデルブロ集合の首が括れなくて、猪首になってしまうのだった。

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
double x,y,tx,ty;
double a;
double b;
int px, py;
int A,B,n;

 for ( A = -250; A < 200; A++ )     {
   for ( B = -200; B < 200; B++ )  {
     x = 0.0; y = 0.0;
	 n = 0;
	 a = (double) A /120.0;
	 b = (double) B /120.0;
     while ( x*x + y*y < 4.0 )   {
	  tx = x*x - y*y + a;
	  ty = 2.0*x*y + b;
	  x = tx;
	  y = ty;
      n++;
	  if ( n > 300 ) break;
	}
	px = A + 500; py = B + 300;
	if ( n > 300 ) Canvas->Pixels[px][py] = clBlack;
    else if ( n == 1 ) Canvas->Pixels[px][py] = clGreen;
    else if ( n == 2 ) Canvas->Pixels[px][py] = clYellow;
    else if ( n == 3 ) Canvas->Pixels[px][py] = clBlue;
	else Canvas->Pixels[px][py] = clRed;
  }
 }	
  
}
//---------------------------------------------------------------------------

トラックバック(0)

トラックバックURL: http://commutative.world.coocan.jp/mt/mt-tb.cgi/4534

コメントする

このブログ記事について

このページは、あやたろうが2017年5月11日 05:13に書いたブログ記事です。

ひとつ前のブログ記事は「本能寺の変」です。

次のブログ記事は「法医昆虫学捜査官」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。