Mandelbrot Set C#

.Net, C#, mandelbrot , fractal, Microsoft

Here is how to code a graphic interactive Mandelbrot Set application in a few steps with Microsoft .Net technologie.


Do you know that Visual studio isn't mandatory to build a graphical .Net Windows application? Here is how to build  fractal application and generate   pictures like this:
 
All  of this just with  notepad and the csc.exe compiler  which are both included  on most windows  distributions

Step 1 Create a directory for the project
Step 2 In this directory put a text file named fractalform.cs (personnaly I used a UTF-8 format with Notepad) containing the following:

using System;
using System.Drawing;
using System.Windows.Forms;


namespace mandelbrot
 

{


/// <summary>
/// Description résumée de Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
Complex C1,C2,C3;
private System.Windows.Forms.Button trace;
private System.Windows.Forms.PictureBox BoiteImage;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox hgx;
private System.Windows.Forms.TextBox hgy;
private System.Windows.Forms.TextBox bdy;
private System.Windows.Forms.TextBox bdx;
private System.Windows.Forms.Label label2;
/// <summary>
/// Variable nécessaire au concepteur.
/// </summary>
private System.ComponentModel.Container components = null;

public Form1()
{
//
// Requis pour la prise en charge du Concepteur Windows Forms
//
InitializeComponent();

}

/// <summary>
/// Nettoyage des ressources utilisées.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

private void InitializeComponent()
{
this.trace = new System.Windows.Forms.Button();
this.BoiteImage = new System.Windows.Forms.PictureBox();
this.hgx = new System.Windows.Forms.TextBox();
this.hgy = new System.Windows.Forms.TextBox();
this.bdy = new System.Windows.Forms.TextBox();
this.bdx = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// trace
//
this.trace.Location = new System.Drawing.Point(512, 8);
this.trace.Name = "trace";
this.trace.Size = new System.Drawing.Size(80, 32);
this.trace.TabIndex = 12;
this.trace.Text = "trace";
this.trace.Click += new System.EventHandler(this.button1_Click);
//
// BoiteImage
//
this.BoiteImage.Location = new System.Drawing.Point(24, 56);
this.BoiteImage.Name = "BoiteImage";
this.BoiteImage.Size = new System.Drawing.Size(584, 416);
this.BoiteImage.TabIndex = 13;
this.BoiteImage.TabStop = false;
//
// hgx
//
this.hgx.Location = new System.Drawing.Point(32, 24);
this.hgx.Name = "hgx";
this.hgx.Size = new System.Drawing.Size(80, 20);
this.hgx.TabIndex = 14;
this.hgx.Text = "-1,5";
//
// hgy
//
this.hgy.Location = new System.Drawing.Point(128, 24);
this.hgy.Name = "hgy";
this.hgy.Size = new System.Drawing.Size(80, 20);
this.hgy.TabIndex = 15;
this.hgy.Text = "-1,5";
//
// bdy
//
this.bdy.Location = new System.Drawing.Point(304, 24);
this.bdy.Name = "bdy";
this.bdy.Size = new System.Drawing.Size(80, 20);
this.bdy.TabIndex = 16;
this.bdy.Text = "1,5";
//
// bdx
//
this.bdx.Location = new System.Drawing.Point(216, 24);
this.bdx.Name = "bdx";
this.bdx.Size = new System.Drawing.Size(80, 20);
this.bdx.TabIndex = 17;
this.bdx.Text = "1,5";
//
// label1
//
this.label1.Location = new System.Drawing.Point(88, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(64, 23);
this.label1.TabIndex = 19;
this.label1.Text = "hautgauche";
//
// label2
//
this.label2.Location = new System.Drawing.Point(272, 0);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(64, 16);
this.label2.TabIndex = 20;
this.label2.Text = "BasDroite";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(632, 470);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.bdx);
this.Controls.Add(this.bdy);
this.Controls.Add(this.hgy);
this.Controls.Add(this.hgx);
this.Controls.Add(this.BoiteImage);
this.Controls.Add(this.trace);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// Point d'entrée principal de l'application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}




private void button1_Click(object sender, System.EventArgs e)
{
int nbPix=1000;
double diagDest;

int x,y;
Bitmap Imag;
Color col;
int iDiv;
Complex c= new Complex();

//define the complex plan zone
Complex cHG = new Complex(Convert.ToDouble( this.hgx.Text),Convert.ToDouble( this.hgy.Text));
Complex cBD = new Complex(Convert.ToDouble(this.bdx.Text),Convert.ToDouble(this.bdy.Text));
diagDest=Convert.ToDouble( this.hgx.Text)-Convert.ToDouble( this.bdx.Text);

//instantiate the bitmap
Imag = new Bitmap(nbPix ,nbPix);

//scan the bitmap
for(x=0;x<Imag.Size.Width;x++)
for(y=0;y<Imag.Size.Height;y++)
{
//convert the pixel coordinate into a complex number
c = new Complex(diagDest*x/nbPix,diagDest*y/nbPix)-cHG;

//calculate divergence
iDiv = c.diverg();

//choose the color of the pixel
if (iDiv >= 255)
//if it converge it's black
col = System.Drawing.Color.FromArgb(255,0,0,0);
else //if it is not it depend of the speed
col = System.Drawing.Color.FromArgb(128,iDiv,iDiv,iDiv);

//set the pixel color
Imag.SetPixel(x,y,col );
}
//draw the image
BoiteImage.SizeMode = PictureBoxSizeMode.StretchImage ;
BoiteImage.ClientSize = new Size(Imag.Size.Width, Imag.Size.Height);
BoiteImage.Image = (Image) Imag ;

}

}
}



Step 3Put a second file named cplx.cs
containing the following

using System;// to include the basic libraries

namespace mandelbrot//a namespace groups classes working together,
{
// The main class
class Complex
{
//constants
const int IMAX_ITER = 255 ;// number of iterations to estimate the divergence
const double MODUL_LIMIT = 2;//


public double x;//pretty close to c++ syntax,
//"public" indicates that the users of the class can access this property...
public double y;

//////////////////////////
//constructors

//the basic one , do nothing but is mandatory for operators overloading
public Complex()
{}

//the main constructor
public Complex(double i, double j)
{
x = i;
y = j;
}

//////////////////////////
//Operators overloading

//plus
public static Complex operator +(Complex c1,Complex c2)
{
Complex temp = new Complex();
temp.x = (c1.x)+(c2.x);
temp.y = c1.y+c2.y;
return temp;
}
//minus
public static Complex operator -(Complex c1,Complex c2)
{
Complex temp = new Complex();
temp.x = (c1.x)-(c2.x);
temp.y = c1.y-c2.y;
return temp;
}
// multiplication, a little more complicated
public static Complex operator *(Complex c1,Complex c2)
{
Complex temp = new Complex();
temp.x = c1.x*c2.x-c1.y*c2.y;
temp.y = c1.y*c2.x+c1.x*c2.y;
return temp;
}

/////////////////////
//methods

//Module, used to measure the complex number
public double Module()
{
double temp;
temp = System.Math.Sqrt( x*x+y*y);
return temp ;
}
//use to measure the divergence of the complex number
//the number return is use to define the color of the affix's point
public int diverg()
{
int i=0 ;
Complex c = new Complex(x,y) ;

while (i<IMAX_ITER && c.Module()<MODUL_LIMIT)
{
c = c*c+this;//yep "*" and "+" are the operator we've just overload.
i++;
}
return i;//the number of iteration is return to set the color
}
}


}




Step 4 Now open a command line window on the directory you've just create.
type the folowing:
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\csc.exe /target:winexe /recurse:*.*
(You may have to replace C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\ by your computer's c# compiler path.)
Then  run the  ".exe"  you may obtain this kind of things :

Comments

Marc Boizeau
Marc Boizeau
IT Project Manager at ASI Informatique
Saint Mandé
Article rating:
Your rating:
All Rights Reserved.
Version: 7
Versions
Last edited: Dec 3, 2008 1:37 AM.

Activity for this knol

This week:

34pageviews

Totals:

1497pageviews
2comments