Title: Animate gears with unequal sizes in C#
The example Animate gears in C# shows how to animate three interlocked gears.
Juan Manuel Montes asked, "What if the radius of the green gear is greater?"
When two gears or wheels touch each other, their outer edges must rotate at the same speed. If their radii are different, that means their angular rotation must be different. Because the circumference of the gears is a linear multiple of the radius (circumference = 2πr), the angular rotations will differ by the ratio of the radii.
For this example, I gave the green gear a radius 1.5 times as big as the radii of the other gears. That means it should have 1.5 times as many teeth and its angular rotation should be 1/1.5 times as fast as that of the other gears.
The following code shows how the program draws its gears, rotated by amount StartAngle.
// Draw the gears.
private void picGears_Paint(object sender, PaintEventArgs e)
{
// Draw smoothly.
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
const float axle_radius = 5;
const float radius = 50;
const float tooth_length = 10;
const int num_teeth = 10;
const float green_ratio = 1.5f;
const int num_green_teeth = (int)(num_teeth * green_ratio);
float x = picGears.ClientSize.Width / 2 -
radius - tooth_length - 1;
float y = picGears.ClientSize.Height / 3;
DrawGear(StartAngle, e.Graphics,
Brushes.Black, Brushes.LightBlue,
Pens.Blue, new PointF(x, y), radius,
tooth_length, num_teeth, axle_radius, true);
// Make the green gear 1.5 times as big (so it has 15 teeth).
const float green_radius = (int)(radius * 1.5f);
float green_angle = -StartAngle / 1.5f;
x += radius + green_radius + tooth_length + 2;
DrawGear(green_angle, e.Graphics,
Brushes.Black, Brushes.LightGreen,
Pens.Green, new PointF(x, y), green_radius,
tooth_length, num_green_teeth, axle_radius, true);
// Offset pink gear by half of one tooth.
float pink_angle = (float)(StartAngle - 360 / num_teeth);
y += radius + green_radius + tooth_length + 2;
DrawGear(pink_angle, e.Graphics,
Brushes.Black, Brushes.Pink,
Pens.Red, new PointF(x, y), radius,
tooth_length, num_teeth, axle_radius, true);
}
To make this example easier to read, I moved some of the values used by the previous example into constants. The code starts by setting the values:
- axle_radius - The radius of the small black axle in the center of a gear
- radius - The radius of the smaller two gears
- tooth_length - The amount the teeth stick out
- num_teeth - The number of teeth on the smaller gears
- green_ratio - The green gear has 1.5 times the radius of the others
- num_green_teeth - The number of teeth on the green gear
The code then draws the blue gear as before. It needs to calculate the position of the green gear differently because that gear is larger. It also divides StartAngle by 1.5 so that gear rotates more slowly than the others.
The program only needs to make two changes while drawing the pink gear. First it draws it in a new position because the green gear is larger than in the previous example. It also rotates the pink gear backwards by the size of one tooth.
In the original example, the green gear had 10 teeth so the left and right sides of the gear had teeth sticking out and the top and bottom had empty spots. The new green gear has 15 teeth so initially the right side has a tooth, the left side as an empty spot, and the top and bottom are aligned at the edges of teeth. Rotating the pink gear backwards by one tooth makes it line up properly with the green gear on the bottom.
Admittedly this isn't a trivial change to the previous example, buy by using similar adjustments you should be able to make gears with other numbers of teeth line up and rotate properly.
Download the example to experiment with it and to see additional details.
|