Draw a colored butterfly curve in C#

butterfly curve

This program uses the following equations to draw the butterfly curve:


butterfly curve

The following Paint event handler draws the curve.

private const int period = 24;

// Draw the butterfly.
private void Form1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    e.Graphics.Clear(this.BackColor);

    // Scale and translate.
    RectangleF world_rect =
        new RectangleF(-4.0f, -4.4f, 8.0f, 7.3f);
    float cx = (world_rect.Left + world_rect.Right) / 2;
    float cy = (world_rect.Top + world_rect.Bottom) / 2;

    // Center the world coordinates at origin.
    e.Graphics.TranslateTransform(-cx, -cy);

    // Scale to fill the form.
    float scale = Math.Min(
        this.ClientSize.Width / world_rect.Width,
        this.ClientSize.Height / world_rect.Height);
    e.Graphics.ScaleTransform(scale, scale, MatrixOrder.Append);

    // Move the result to center on the form.
    e.Graphics.TranslateTransform(
        this.ClientSize.Width / 2,
        this.ClientSize.Height / 2, MatrixOrder.Append);

    // Generate the points.
    PointF pt0, pt1;
    double t = 0;
    double expr = 
        Math.Exp(Math.Cos(t))
        - 2 * Math.Cos(4 * t)
        - Math.Pow(Math.Sin(t / 12), 5);
    pt1 = new PointF(
        (float)(Math.Sin(t) * expr), 
        (float)(-Math.Cos(t) * expr));
    using (Pen the_pen = new Pen(Color.Blue, 0))
    {
        const long num_lines = 5000;
        for (long i = 0; i < num_lines; i++)
        {
            t = i * period * Math.PI / num_lines;
            expr = 
                Math.Exp(Math.Cos(t))
                - 2 * Math.Cos(4 * t)
                - Math.Pow(Math.Sin(t / 12), 5);
            pt0 = pt1;
            pt1 = new PointF(
                (float)(Math.Sin(t) * expr), 
                (float)(-Math.Cos(t) * expr));
            the_pen.Color = GetColor(t);
            e.Graphics.DrawLine(the_pen, pt0, pt1);
        }
    }
}

The code uses translation and scale transformations to make the curve fit the form nicely. It then loops the variable t from 0 to 24π to generate the points along the curve. For the each line segment between a pair of adjacent points, the code calls the following GetColor method to pick a color for that segment and then draws it.

// Return an appropriate color for this segment.
private Color GetColor(double t)
{
    return Colors[(int)(t / Math.PI)];
}

The GetColor method divides the parameter t by π and uses the result as an index into the Colors array, which is initialized in the form’s Load event handler.

private Color[] Colors;

// Initialize the colors.
private void Form1_Load(object sender, EventArgs e)
{
    // Redraw when resized.
    this.ResizeRedraw = true;

    Colors = new Color[] 
    {
        Color.Pink,
        Color.Red,
        ...
        Color.Violet
    };
}


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in algorithms, fractals, graphics, mathematics and tagged , , , , , , , , , . Bookmark the permalink.

6 Responses to Draw a colored butterfly curve in C#

  1. Richard Moss says:

    Pretty but your math based examples always fry my mind 🙁

  2. Rod Stephens says:

    Sorry about that 😉

    Even if you don’t follow the equations (I don’t really understand them too well, either), there are some things to learn from this example. For example, how to plot a parametric function X(t) and Y(t).

    The next two examples will also highlight techniques used by this example.

  3. Ebrima says:

    Fantastic, I wish I have a maths background like you, it is extra ordinary

  4. Yelinna says:

    There’s a tiny tiny (not so tiny) mistake in the original formulas:
    x = Cos(t) * Exp(Cos(t)) – 2 * Cos(4 * t) – Sin(t / 12) ^ 5
    y = Sin(t) * Exp(Cos(t)) – 2 * Cos(4 * t) – Sin(t / 12) ^ 5

    They really are:
    x = Cos(t) * (Exp(Cos(t)) – 2 * Cos(4 * t) – Sin(t / 12) ^ 5)
    y = Sin(t) * (Exp(Cos(t)) – 2 * Cos(4 * t) – Sin(t / 12) ^ 5)

    Then I got my butterfly 😀

  5. Rod Stephens says:

    Sorry about that. You’re right. I didn’t transcribe from the source code correctly.

  6. Pingback: Use double buffering to prevent flicker when drawingC# Helper

Leave a Reply

Your email address will not be published. Required fields are marked *