Task: Mandelbrot set



C#: using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using System.Windows.Forms;




public class MandelbrotSetForm : Form
{
    const double MaxValueExtent = 2.0;
    Thread thread;

    static double CalcMandelbrotSetColor(ComplexNumber c)
    {
        
        const int MaxIterations = 1000;
        const double MaxNorm = MaxValueExtent * MaxValueExtent;

        int iteration = 0;
        ComplexNumber z = new ComplexNumber();
        do
        {
            z = z * z + c;
            iteration++;
        } while (z.Norm() < MaxNorm && iteration < MaxIterations);
        if (iteration < MaxIterations)
            return (double)iteration / MaxIterations;
        else
            return 0; 
    }

    static void GenerateBitmap(Bitmap bitmap)
    {
        double scale = 2 * MaxValueExtent / Math.Min(bitmap.Width, bitmap.Height);
        for (int i = 0; i < bitmap.Height; i++)
        {
            double y = (bitmap.Height / 2 - i) * scale;
            for (int j = 0; j < bitmap.Width; j++)
            {
                double x = (j - bitmap.Width / 2) * scale;
                double color = CalcMandelbrotSetColor(new ComplexNumber(x, y));
                bitmap.SetPixel(j, i, GetColor(color));
            }
        }
    }

    static Color GetColor(double value)
    {
        const double MaxColor = 256;
        const double ContrastValue = 0.2;
        return Color.FromArgb(0, 0,
            (int)(MaxColor * Math.Pow(value, ContrastValue)));
    }
    
    public MandelbrotSetForm()
    {
        
        this.Text = "Mandelbrot Set Drawing";
        this.BackColor = System.Drawing.Color.Black;
        this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
        this.MaximizeBox = false;
        this.StartPosition = FormStartPosition.CenterScreen;
        this.FormBorderStyle = FormBorderStyle.FixedDialog;
        this.ClientSize = new Size(640, 640);
        this.Load += new System.EventHandler(this.MainForm_Load);
    }

    void MainForm_Load(object sender, EventArgs e)
    {
        thread = new Thread(thread_Proc);
        thread.IsBackground = true;
        thread.Start(this.ClientSize);
    }

    void thread_Proc(object args)
    {
        
        Size size = (Size)args;
        int width = 16;
        while (width * 2 < size.Width)
        {
            int height = width * size.Height / size.Width;
            Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
            GenerateBitmap(bitmap);
            this.BeginInvoke(new SetNewBitmapDelegate(SetNewBitmap), bitmap);
            width *= 2;
            Thread.Sleep(200);
        }
        
        Bitmap finalBitmap = new Bitmap(size.Width, size.Height, PixelFormat.Format24bppRgb);
        GenerateBitmap(finalBitmap);
        this.BeginInvoke(new SetNewBitmapDelegate(SetNewBitmap), finalBitmap);
    }

    void SetNewBitmap(Bitmap image)
    {
        if (this.BackgroundImage != null)
            this.BackgroundImage.Dispose();
        this.BackgroundImage = image;
    }

    delegate void SetNewBitmapDelegate(Bitmap image);

    static void Main()
    {
        Application.Run(new MandelbrotSetForm());
    }
}

struct ComplexNumber
{
    public double Re;
    public double Im;

    public ComplexNumber(double re, double im)
    {
        this.Re = re;
        this.Im = im;
    }

    public static ComplexNumber operator +(ComplexNumber x, ComplexNumber y)
    {
        return new ComplexNumber(x.Re + y.Re, x.Im + y.Im);
    }

    public static ComplexNumber operator *(ComplexNumber x, ComplexNumber y)
    {
        return new ComplexNumber(x.Re * y.Re - x.Im * y.Im,
            x.Re * y.Im + x.Im * y.Re);
    }

    public double Norm()
    {
        return Re * Re + Im * Im;
    }
}









Ada: with Lumen.Binary;
package body Mandelbrot is
   function Create_Image (Width, Height : Natural) return Lumen.Image.Descriptor is
      use type Lumen.Binary.Byte;
      Result : Lumen.Image.Descriptor;
      X0, Y0 : Float;
      X, Y, Xtemp : Float;
      Iteration   : Float;
      Max_Iteration : constant Float := 1000.0;
      Color : Lumen.Binary.Byte;
   begin
      Result.Width := Width;
      Result.Height := Height;
      Result.Complete := True;
      Result.Values := new Lumen.Image.Pixel_Matrix (1 .. Width, 1 .. Height);
      for Screen_X in 1 .. Width loop
         for Screen_Y in 1 .. Height loop
            X0 := -2.5 + (3.5 / Float (Width) * Float (Screen_X));
            Y0 := -1.0 + (2.0 / Float (Height) * Float (Screen_Y));
            X := 0.0;
            Y := 0.0;
            Iteration := 0.0;
            while X * X + Y * Y <= 4.0 and then Iteration < Max_Iteration loop
               Xtemp := X * X - Y * Y + X0;
               Y := 2.0 * X * Y + Y0;
               X := Xtemp;
               Iteration := Iteration + 1.0;
            end loop;
            if Iteration = Max_Iteration then
               Color := 255;
            else
               Color := 0;
            end if;
            Result.Values (Screen_X, Screen_Y) := (R => Color, G => Color, B => Color, A => 0);
         end loop;
      end loop;
      return Result;
   end Create_Image;

end Mandelbrot;