## Introduction

Math problems have a charm of their own. Besides, they help to develop a programmer's skill. Here, we describe a student's exam task: "Develop an application that models the behaviour of a Hypocycloid".

## Background

A cycloid is the curve defined by the path of a point on the edge of a circular wheel as the wheel rolls along a straight line. It was named by Galileo in 1599 (http://en.wikipedia.org/wiki/Cycloid).

A hypocycloid is a curve generated by the trace of a fixed point on a small circle that rolls within a larger circle. It is comparable to the cycloid, but instead of the circle rolling along a line, it rolls within a circle.

Use Google to find a wonderful book of Eli Maor, **Trigonometric Delights** (Princeton, New Jersey). The following passage is taken from this book.

I believe that a program developer must love formulas derivation. Hence, let us find the parametric equations of the hypocycloid.

A point on a circle of radius `r`

rolls on the inside of a fixed circle of radius `R`

. Let `C`

be the center of the rolling circle, and `P`

a point on the moving circle. When the rolling circle turns through an angle in a clockwise direction, `C`

traces an arc of angular width `t`

in a counterclockwise direction. Assuming that the motion starts when `P`

is in contact with the fixed circle (figure on the left), we choose a coordinate system in which the origin is at `O`

and the x-axis points to `P`

. The coordinates of `P`

relative to `C`

are:

(r cos b; -r sin b)

The minus sign in the second coordinate is there because `b`

is measured clockwise. Coordinates of `C`

relative to `O`

are:

((R - r) cos t, (R - r) sin t)

Note, angle `b`

may be expressed as:

b = t + β; β = b - t

Thus, the coordinates of `P`

relative to `O`

are:

((R - r) cos t + r cos β, (R - r) sin t - r sin β) (1)

But the angles `t`

and `b`

are not independent: as the motion progresses, the arcs of the fixed and moving circles that come in contact must be of equal length `L`

.

L = R t L = r b

Using this relation to express `b`

in terms of `t`

, we get

b = R t / r

Equations (1) become:

x = (R - r) cos t + r cos ((R / r - 1) t) (2)
y = (R - r) sin t - r sin ((R / r - 1) t)

Equations (2) are the parametric equations of the hypocycloid, the angle `t`

being the parameter (if the rolling circle rotates with constant angular velocity, `t`

will be proportional to the elapsed time since the motion began). The general shape of the curve depends on the ratio `R/r`

. If this ratio is a fraction `m/n`

in lowest terms, the curve will have `m`

cusps (corners), and it will be completely traced after moving the wheel `n`

times around the inner rim. If `R/r`

is irrational, the curve will never close, although going around the rim many times will nearly close it.

## Using the code

The demo application provided with this article uses a `Hypocycloid`

control derived from `UserControl`

to model a behaviour of a hypocycloid described above.

The functionality of the hypocycloid is implemented in the `Hypocycloid`

class. It has a `GraphicsPath path`

data field that helps to render the hypocycloid path over time. A floating point variable, `angle`

, corresponds to the angle `t`

described earlier.

- Variable
`ratio = R / r`

`delta = R - r`

All the math is done within the timer `Tick`

event handler.

void timer_Tick(object sender, EventArgs e)
{
angle += step;
double
cosa = Math.Cos(angle),
sina = Math.Sin(angle),
ct = ratio * angle;
movingCenter.X = (float)(centerX + delta * cosa);
movingCenter.Y = (float)(centerY + delta * sina);
PointF old = point;
point = new PointF(
movingCenter.X + r * (float)Math.Cos(ct),
movingCenter.Y - r * (float)Math.Sin(ct));
int n = (int)(angle / pi2);
if (n > round)
{
round = n;
ParentNotify(msg + ";" + round);
}
if (round < nRounds)
path.AddLine(old, point);
else if (!stopPath)
{
ParentNotify(msg + ";" + round + ";" + path.PointCount);
stopPath = true;
}
parent.Invalidate();
}

`ParentNotify`

is the event of the generic delegate type `Action<string>`

.

public event Action<string> ParentNotify;

We use it to notify a parent control of a current angle (round).

Besides a constructor, the class has the following public methods: `Reset`

, `Draw`

, `Start`

, `Stop`

, and `SaveToFile`

. Remember also that the Y axis in a Windows window goes down.