解析
- マンデルブロ集合
複素数クラスを使ってマンデルブロ集合を描画してみましょう。
public partial class FormMandelbrot : Form
{
private void FormMandelbrot_Load( object sender, EventArgs e )
{
pictureBox1.Width = 500;
pictureBox1.Height = 500;
pictureBox1.Image = DrawMandelbrot( pictureBox1.Width, pictureBox1.Height );
}
/// <summary>
/// マンデルブロ集合描画実行。ビットマップで取得
/// </summary>
/// <returns>ビットマップ</returns>
public Bitmap DrawMandelbrot( int nWidth, int nHeight )
{
//-------------------------------------------------------------------
// 仮想画面を準備
Bitmap bmpData = new Bitmap( nWidth, nHeight );
Graphics g = Graphics.FromImage( bmpData );
Complex c;
Complex z;
int nCount;
int nCountMax; //繰返し回数の上限、カラー階調数
// 設定データ
nCountMax = 64;
Pen pen = new Pen( Color.Red );
for( int x = 0; x < nWidth; x++ )
{
for( int y = 0; y < nHeight; y++ )
{
// 複素平面状の点(中心を原点とする)
c = new Complex( -this.Width / 2 + x, this.Height / 2 - y );
c *= 0.00625;
nCount = 0;
z = new Complex();
while( true )
{
z = z * z + c; // Mandelbrot集合の繰返し演算(Z=Z*Z+C)
if( z.GetSquareModulus() >= 4.0 ) break;
nCount++;
if( nCount > nCountMax )
{
// 発散しないと判断(黒く塗る)
nCount = -1;
break;
}
}
pen.Color = GetColor( nCount );
g.DrawLine( pen, x, y, x, y + 1 );
}
}
pen.Dispose();
return bmpData;
}
//数値を色に変換するメソッド
private Color GetColor( int nCount )
{
int d, r, g, b;
if( nCount < 0 ) return Color.Black;
d = nCount % 16;
d *= 256 / 16;
int m = ( int )( d / 42.667 );
switch( m )
{
case 0: r = 0; g = 6 * d; b = 255; break; // 青→シアン
case 1: r = 0; g = 255; b = 255 - 6 * ( d - 43 ); break; // シアン→緑
case 2: r = 6 * ( d - 86 ); g = 255; b = 0; break; // 緑→黄
case 3: r = 255; g = 255 - 6 * ( d - 129 ); b = 0; break; // 黄→赤
case 4: r = 255; g = 0; b = 6 * ( d - 171 ); break; // 赤→マゼンタ
case 5: r = 255 - 6 * ( d - 214 ); g = 0; b = 255; break; // マゼンタ→青
default: r = 0; g = 0; b = 0; break;
}
return Color.FromArgb( r, g, b );
}
}