BLOG.CSHARPHELPER.COM: Draw a hypotrochoid (Spirograph curve) in C#
Draw a hypotrochoid (Spirograph curve) in C#
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.
You can draw an hypotrochoid with the following parametric functions:
// 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 * Pi * 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)) { 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); while (t <= max_t) { double x0 = x1; double y0 = y1; t += dt; x1 = cx + X(t, A, B, C); y1 = cy + Y(t, A, B, C); gr.DrawLine(Pens.Black, (float)x0, (float)y0, (float)x1, (float)y1); } }
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.
5/4/2011 7:16 AMRod Stephens wrote:
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).
5/4/2011 7:27 AM
Rohit wrote:
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! Reply to this
5/4/2011 7:40 AM
Rohit wrote:
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#? Reply to this
5/4/2011 3:16 PMRod Stephens wrote:
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.) Reply to this
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 ([email protected])
Reply to this
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#.
Reply to this
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!
Reply to this
If you come up with some good pictures, email me and I'll post a few.
Reply to this
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#?
Reply to this
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.)
Reply to this
I've posted a FloodFill example at Write a graphical floodfill method in C#.
Reply to this