Draw gears in C#

The DrawGear method shown in the following code draws a gear.

// Draw a gear.
private void DrawGear(Graphics gr, Brush axle_brush,
 Brush gear_brush, Pen gear_pen, PointF center,
 float radius, float tooth_length, int num_teeth,
 float axle_radius, bool start_with_tooth) { float dtheta = (float)(Math.PI / num_teeth); float dtheta_degrees = (float)(dtheta * 180 / Math.PI); const float chamfer = 2; float tooth_width = radius * dtheta - chamfer; float alpha = tooth_width / (radius + tooth_length); float alpha_degrees = (float)(alpha * 180 / Math.PI); float phi = (dtheta - alpha) / 2; // Set theta for the beginning of the first tooth. float theta; if (start_with_tooth) theta = dtheta / 2; else theta = -dtheta / 2; // Make rectangles to represent the gear's inner and outer arcs. RectangleF inner_rect = new RectangleF( center.X - radius, center.Y - radius, 2 * radius, 2 * radius); RectangleF outer_rect = new RectangleF( center.X - radius - tooth_length, center.Y - radius - tooth_length, 2 * (radius + tooth_length), 2 * (radius + tooth_length)); // Make a path representing the gear. GraphicsPath path = new GraphicsPath(); for (int i = 0; i < num_teeth; i++) { // Move across the gap between teeth. float degrees = (float)(theta * 180 / Math.PI); path.AddArc(inner_rect, degrees, dtheta_degrees); theta += dtheta; // Move across the tooth's outer edge. degrees = (float)((theta + phi) * 180 / Math.PI); path.AddArc(outer_rect, degrees, alpha_degrees); theta += dtheta; } path.CloseFigure(); // Draw the gear. gr.FillPath(gear_brush, path); gr.DrawPath(gear_pen, path); gr.FillEllipse(axle_brush, center.X - axle_radius, center.Y - axle_radius, 2 * axle_radius, 2 * axle_radius); }

The code first defines some variables to make drawing easier. It sets dtheta to the angle spanned by each tooth.

The value chamfer gives the amount by which a tooth's end is narrower than its base. This makes the tooth taper slightly. (In real gears the tooth may have curved sides so it fits better with other teeth but straight-line edges are good enough for this.)

The tooth_width variable holds the desired width of the tooth at its end. This is the width at the base minus the chamfer amount.

The value alpha holds the angle subtended by the end of the tooth. The value phi holds half the difference between dtheta and alpha. This gives the angle between the base and the end of the tooth. (See the picture on the right.)

With these values, you should be able to follow the geometry of the gear-drawing code.

Next the code sets an initial angle theta. If the gear should start with a tooth (as opposed to a gap between two teeth) on the right, the code sets theta equal to dtheta / 2 so drawing will begin above the gear's horizontal center. If the gear should begin with a gap on its right edge, the code sets theta equal to -dtheta / 2 so drawing will begin below the gear's horizontal center.

The code then enters a loop to draw the gear's teeth. It starts drawing each tooth by drawing a gap between teeth. It then draws the tooth itself. The initial value for theta determines whether the first tooth's gap begins above the horizontal centerline (so a tooth falls on the centerline) or below the horizontal centerline (so a gap falls on the centerline).

The code calls CloseFigure to close the GraphicsPath object by connecting its last point to its first point. Finally the code fills and draws the path that defines the gear.

The program uses the following code to draw three gears on the picGears PictureBox.

// Draw the gear.
private void picGears_Paint(object sender, PaintEventArgs e)
{
    // Draw smoothly.
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    const float radius = 50;
    const float tooth_length = 10;
    float x = picGears.ClientSize.Width / 2 - radius - tooth_length - 1;
    float y = picGears.ClientSize.Height / 3;
    DrawGear(e.Graphics, Brushes.Black, Brushes.LightBlue, Pens.Blue, new PointF(x, y),
        radius, tooth_length, 10, 5, true);

    x += 2 * radius + tooth_length + 2;
    DrawGear(e.Graphics, Brushes.Black, Brushes.LightGreen, Pens.Green, new PointF(x, y),
        radius, tooth_length, 10, 5, false);

    y += 2 * radius + tooth_length + 2;
    DrawGear(e.Graphics, Brushes.Black, Brushes.Pink, Pens.Red, new PointF(x, y),
        radius, tooth_length, 10, 5, true);
}

   

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this post.
Comments
  • No comments exist for this post.
Leave a comment

Submitted comments are subject to moderation before being displayed.

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.