Draw a hypotrochoid (Spirograph curve) in C#

hypotrochoid
hypotrochoid

The hypotrochoid is a curve drawn by rolling a circle of radius B around the inside circumference of another of radius A. A point attached to the inner circle and distance C from its center draws the curve. (See the smaller picture on the right.)

 

The following parametric functions generate points along the hypotrochoid.

// The parametric function X(t).
private double X(double t, double A, double B, double C)
{
    return (A - B) * Math.Cos(t) + C * Math.Cos((A - B) / B * t);
}

// The parametric function Y(t).
private double Y(double t, double A, double B, double C)
{
    return (A - B) * Math.Sin(t) - C * Math.Sin((A - B) / B * t);
}

To trace the entire curve, the variable t must vary from 0 to 2 π B / GCD(A, B). For information on calculating the GCD (Greatest Common Divisor), see Calculate the greatest common divisor (GCD) and least common multiple (LCM) of two integers in C#.

The program uses the following code to draw the complete curve when you enter parameters and click Draw. The iter parameter determines how many points the program uses. Bigger values give smoother results, although using very small values can be interesting, too.

// Draw the hypotrochoid.
private void btnDraw_Click(object sender, EventArgs e)
{
    int A = int.Parse(txtA.Text);
    int B = int.Parse(txtB.Text);
    int C = int.Parse(txtC.Text);
    int iter = int.Parse(txtIter.Text);

    int wid = picCanvas.ClientSize.Width;
    int hgt = picCanvas.ClientSize.Height;
    Bitmap bm = new Bitmap(wid, hgt);
    using (Graphics gr = Graphics.FromImage(bm))
    {
        gr.SmoothingMode = SmoothingMode.AntiAlias;

        int cx = wid / 2;
        int cy = hgt / 2;
        double t = 0;
        double dt = Math.PI / iter;
        double max_t = 2 * Math.PI * B / GCD(A, B);
        double x1 = cx + X(t, A, B, C);
        double y1 = cy + Y(t, A, B, C);
        List points = new List();
        points.Add(new PointF((float)x1, (float)y1));
        while (t <= max_t)
        {
            t += dt;
            x1 = cx + X(t, A, B, C);
            y1 = cy + Y(t, A, B, C);
            points.Add(new PointF((float)x1, (float)y1));
        }
        // Draw the polygon.
        gr.DrawPolygon(Pens.Red, points.ToArray());
    }

    picCanvas.Image = bm;
}

This code parses the parameters you entered. It then makes the variable t loop from 0 to the 2 π B / GCD(A, B). For each value of t, it adds the corresponding point to a list of points. After it finishes the loop, the code draws a polygon defined by the points.


Download Example   Follow me on Twitter   RSS feed


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

8 Responses to Draw a hypotrochoid (Spirograph curve) in C#

  1. Rohit says:

    Hi,

    Firstly I would like to thank you for this immense fountain of knowledge! I really appriciate your work and books.

    Can you please confirm that the code here for hypotrochoid is indeed corect? I am not doubting your code but I seem to be getting slightly differnt curves to what i would expect.

    For example, see http://en.wikipedia.org/wiki/Hypotrochoid

    I cant seem to generate the curve suggetsed on that wikipedia page (parameters are R = 5, r = 3, d = 5).

    Many thanks
    Rohit (grand.mariner@gmail.com)

  2. Rod Stephens says:

    Oops! There was a typo in the Y function. It said “+ H” instead of “- H.” A tiny thing that made all the difference (although it still produced a cool curve).

    I’ve posted a new example that shows the curve animated so it’s easier to see what it’s doing at Draw an animated hypotrochoid (Spirograph curve) in C#.

  3. Rohit says:

    Many thanks! I did correct it earlier today when I figured it out and just now saw your post. I am actually using the old/incorrect code as it creates cool cloud shapes which I am experimenting with!

  4. Rohit says:

    This code is much better as it now builds a list of points. Using this list you can now use FillPolygon method to fill the curve as well. I was using a floodfill method which was a nightmare.

    Anyone knows of a good way to have FloodFill in C#?

  5. Rod Stephens says:

    If you come up with some good pictures, email me and I’ll post a few.

  6. Rod Stephens says:

    Ive done flood fill in .NET before. I’ll try to put together an example in the next couple days and email it to you. (And post it to the blog.)

  7. Pingback: Draw an animated hypotrochoid (Spirograph curve) in C# |

Leave a Reply

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