Draw a smooth curve connecting points in C#

[curve]

The Graphics class’s DrawCurve method draws a smooth curve connecting a sequence of points.

The type of curve drawn is called a spline. In general, a spline is a smooth curve with a shape determined by a collection of control points. In some splines, the control points guide the shape of the curve but the curve doesn’t touch them. The DrawCurve method draws a spline that passes through each of its control points.

This example uses the following code to let you select points.

// The points selected by the user.
private List<Point> Points = new List<Point>();

// Select a point.
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
    Points.Add(e.Location);
    Refresh();
}

Each time you click the mouse, the MouseClick event handler adds the point to the Points list. It then refreshes the form to make it execute the following Paint event handler.

private void Form1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    // Draw the points.
    foreach (Point point in Points)
        e.Graphics.FillEllipse(Brushes.Black,
            point.X - 3, point.Y - 3, 5, 5);
    if (Points.Count < 2) return;

    // Draw the curve.
    e.Graphics.DrawCurve(Pens.Red, Points.ToArray());
}

This code loops through the points and draws circles for each. Then if the Points list contains fewer than 2 points, the method exits. Otherwise it calls the list’s ToArray method to create an array of points and passes them to the call to DrawCurve.

The only other piece of code is the following method, which executes when you select the Curve menu’s New command.

// Start a new point list.
private void mnuCurveNew_Click(object sender, EventArgs e)
{
    Points = new List<Point>();
    Refresh();
}

This code simply creates a new empty Points list and refreshes the form.


Download Example   Follow me on Twitter   RSS feed   Donate




About RodStephens

Rod Stephens is a software consultant and author who has written more than 30 books and 250 magazine articles covering C#, Visual Basic, Visual Basic for Applications, Delphi, and Java.
This entry was posted in drawing, graphics and tagged , , , , , , , , , , . Bookmark the permalink.

5 Responses to Draw a smooth curve connecting points in C#

  1. Pingback: Change curve tension in C# - C# HelperC# Helper

  2. Ramin says:

    thank you so much for this tutorial.
    Would you please say How can we have an event like Curve_click?
    that when you click on drawn curve for example a message box is triggered.

    thanks

  3. RodStephens says:

    The short answer is that would be hard to do. This program uses the Graphics object’s DrawCurve method to draw the curve. It doesn’t know the coordinates of the points on the curve so it can’t tell if the point you click is close to the curve.

    A kuldgy alternative would be to look at the pixels near the clicked point to see if any have the color of the curve. If the picture only contains the curve, then that would mean you had clicked near it.

    A better alternative would be to learn how to draw splines with your own code. Then you could calculate the points on the curve and see if any was near the point clicked. That would be harder but better.

    Finally you could create a class to represent the curve. It would have a method to draw and another method to tell whether a point was near it.

  4. Vic Joseph says:

    I just happened to stumble into this blog on a detour from far-off VB.Net country, and I’d like to offer some succour to the Csharp natives ;). There is a fairly easy way to detect a click on a curve. In fact the technique applies not just to curves but to practically anything you can draw in GDI+.

    First, declare a Drawing2D.GraphicsPath, and do your drawing to that instead of directly to the Graphics object (in this case, with GraphicsPath.AddCurve). You can render the path when needed with Graphics.DrawPath, and the sum effect is the same as using Graphics.DrawCurve.

    The GraphicsPath has a built-in hit testing capability for lines, namely the GraphicsPath.IsOutlineVisible method, which returns a Boolean value. The simplest overload is this:
    GraphicsPath.IsOutlineVisible(pen, point)

    You can use any System.Drawing.Pen for the first argument. The pen’s colour doesn’t matter, just its width. This is user-friendly method because you can provide a wider margin of error by specifying a thicker pen. If the specified point is on the path-as-if-drawn with the given pen, the method returns True.

    For fancy work, you could even give the Pen a dashstyle or endcaps, and these will also be hit-tested. That’s why a Pen argument is used rather than just a width.

    all the best,
    Vic

Leave a Reply

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