Animate two rods connected to a wheel in C#

This example draws two rods and a wheel. One rod is connected to the other and to a wheel. The second rod is connected to the first and is anchored in the middle. (I made this project because I wanted to see what path the farther end of the blue rod would travel. In retrospect, it’s obvious that it must be an arc of a circle.)

The program uses a timer to rotate the wheel. The following code shows the timer’s event handler.

// Rotate the wheel.
// The wheel's current angle of rotation.
private const double Dtheta = Math.PI / 10;
private double Theta = 0;

private void tmrTurnWheel_Tick(object sender, EventArgs e)
{
    Theta += Dtheta;
    DrawSystem();
    picCanvas.Refresh();
}

This code simply increases the wheel’s angle of rotation, Theta. It then calls the DrawSystem method shown in the following code to draw the picture.

// Draw everything.
private void DrawSystem()
{
    Gr.Clear(this.BackColor);
    Gr.SmoothingMode = SmoothingMode.AntiAlias;

    using (Pen custom_pen = new Pen(Color.Blue, 2))
    {
        // Draw the wheel.
        RectangleF wheel_rect = new RectangleF(
            Cx - Radius, Cy - Radius,
            2 * Radius, 2 * Radius);
        Gr.FillEllipse(Brushes.LightBlue, wheel_rect);
        custom_pen.Color = Color.Blue;
        custom_pen.Width = 2;
        Gr.DrawEllipse(custom_pen, wheel_rect);

        // Find the ends of the linkage.
        float linkage_x1 =
            (float)(Cx + Math.Cos(Theta) * Radius);
        float linkage_y1 =
            (float)(Cy + Math.Sin(Theta) * Radius);
        PointF pt1, pt2;
        FindCircleCircleIntersections(
            Ax, Ay, L2,
            linkage_x1, linkage_y1, L1,
            out pt1, out pt2);
        float linkage_x2 = pt1.X;
        float linkage_y2 = pt1.Y;

        // Draw the linkage.
        custom_pen.Color = Color.Green;
        custom_pen.Width = 5;
        Gr.DrawLine(custom_pen,
            linkage_x1, linkage_y1, linkage_x2, linkage_y2);
        custom_pen.Color = Color.Lime;
        custom_pen.Width = 2;
        Gr.DrawLine(custom_pen,
            linkage_x1, linkage_y1, linkage_x2, linkage_y2);

        // Draw the upper arm.
        custom_pen.Color = Color.Blue;
        custom_pen.Width = 5;
        Gr.DrawLine(custom_pen, Ax, Ay, linkage_x2, linkage_y2);
        custom_pen.Color = Color.LightBlue;
        custom_pen.Width = 2;
        Gr.DrawLine(custom_pen, Ax, Ay, linkage_x2, linkage_y2);

        // Draw the lower arm.
        float dx = Ax - linkage_x2;
        float dy = Ay - linkage_y2;
        double length = Math.Sqrt(dx * dx + dy * dy);
        float lower_x1 = (float)(Ax + dx * L3 / length);
        float lower_y1 = (float)(Ay + dy * L3 / length);
        custom_pen.Color = Color.Blue;
        custom_pen.Width = 5;
        Gr.DrawLine(custom_pen, Ax, Ay, lower_x1, lower_y1);
        custom_pen.Color = Color.LightBlue;
        custom_pen.Width = 2;
        Gr.DrawLine(custom_pen, Ax, Ay, lower_x1, lower_y1);

        // Draw joints.
        Gr.FillEllipse(Brushes.Black, Cx - 4, Cy - 4, 8, 8);
        Gr.FillEllipse(Brushes.Green,
            linkage_x1 - 4, linkage_y1 - 4, 8, 8);
        Gr.FillEllipse(Brushes.Green,
            linkage_x2 - 4, linkage_y2 - 4, 8, 8);
        Gr.FillEllipse(Brushes.Black, Ax - 4, Ay - 4, 8, 8);
        Gr.FillEllipse(Brushes.Blue,
            lower_x1 - 4, lower_y1 - 4, 8, 8);
    }
}

This code simply draws the wheel and its two rods. The center and radius of the wheel are known. The blue rod’s anchor point A and the blue rod’s lengths on each side of that point are also known. Finally the length of the green rod is known. The only tricks are figuring out where points B and C are. Once you know that, drawing the picture is reasonably straightforward.

Finding point B is straightforward. Its location is determined by the wheel’s current angle of rotation.

To find point C you need to realize that it is a fixed distance from point B along the blue rod and a different fixed distance from point B along the green rod. That means point C must lie on the blue and green dashed circles. Mathematically point C lies at the intersection of the dashed circles.

The example Determine where two circles intersect in C# explains how to determine where two circles intersect. This example uses the FindCircleCircleIntersections method described by that example.

Note that two circles may intersect in two places, as they do in this example. That means there are two possible configurations for this system. In the second configuration, the point C is at the bottom of the picture. This example picks the solution it does by always using the first point of intersection returned by the FindCircleCircleIntersections method.

The rest of the DrawSystem method draws all of the system’s pieces so they look nice.



The picture immediately above shows the complete program. Use the textboxes to experiment with the length and radius parameters:

  • D – Distance between the blue rod’s anchor and the wheel’s center
  • L1 – Length of green rod
  • L2 – Length of blue rod between points A and C
  • L3 – Length of the other part of the blue rod
  • R – Radius of the wheel


Download Example   Follow me on Twitter   RSS feed   Donate




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

Leave a Reply

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