See if the mouse is over a curve in C#

[example]

The post Draw a smooth curve connecting points in C# uses the Graphics class’s DrawCurve method to draw a smooth curve that connects a collection of points. This example shows how you can tell when the mouse is over the resulting curve.

The program uses the following variables to store information about the curve and places where you’ve clicked on the form.

// The points that define the curve.
private Point[] Points =
{
    new Point(213, 204),
    new Point(63, 143),
    new Point(227, 60),
    new Point(123, 222),
    new Point(72, 64),
};

// A GraphicsPath to represent the curve.
GraphicsPath Path = new GraphicsPath();

// Hits and misses.
private List<Point> Hits = new List();
private List<Point> Misses = new List();

The Points array holds the points that define the curve. Path is a GraphicsPath object that will be used to decide whether the mouse is over the curve. The Hits and Misses lists hold points that you click on the form.

When the program starts, the following Load event handler initializes Path.

// Make a GraphicsPath for the curve.
private void Form1_Load(object sender, EventArgs e)
{
    Path = new GraphicsPath();
    Path.AddCurve(Points);
}

This code creates a new GraphicsPath and uses its AddCurve method to add a smooth curve to it. The result is identical to the curve you get from the Graphics object’s DrawCurve method, which is used in the following Paint event handler.

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

    // Draw the curve.
    e.Graphics.DrawCurve(Pens.Blue, Points);

    // Draw the hits and misses.
    foreach (Point point in Misses)
        DrawPoint(e.Graphics, Brushes.Pink, Pens.Red, point);
    foreach (Point point in Hits)
        DrawPoint(e.Graphics, Brushes.Lime, Pens.Green, point);
}

This code makes the Graphics object draw smooth curves. It then calls its DrawCurve method to draw the smooth curve connecting the points in the Points array. It finishes by using the following DrawPoint method to draw the locations where you have previously clicked.

// Draw a point.
private void DrawPoint(Graphics gr, Brush brush,
    Pen pen, Point point)
{
    const int radius = 3;
    const int diameter = 2 * radius;
    Rectangle rect = new Rectangle(
        point.X - radius, point.Y - radius,
        diameter, diameter);
    gr.FillEllipse(brush, rect);
    gr.DrawEllipse(pen, rect);
}

This method fills and then draws an ellipse around a point.

Now to the code that checks whether a point is over the curve. The following method performs the basic test.

// Return true if the point is over the curve.
private bool PointIsOverCurve(Point point)
{
    // Use a three pixel wide pen.
    using (Pen thick_pen = new Pen(Color.Black, 3))
    {
        return Path.IsOutlineVisible(point, thick_pen);
    }
}

This method creates a pen three pixels wide. You could make it thinner or thicker depending on how closely the mouse should lie over the curve. The pen’s color doesn’t matter.

Next the code calls the GraphicsPath object’s IsOutlineVisible method. That method returns true if the point is over the outline of the curve when drawn with the indicated pen.

That’s all there is to the actual test. The program uses the following code to determine whether the mouse is over the curve when you move or click the mouse.

// See if the mouse is over the curve's GraphicsPath.
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    if (PointIsOverCurve(e.Location))
        Cursor = Cursors.Cross;
    else
        Cursor = Cursors.Default;
}

private void Form1_MouseClick(object sender, MouseEventArgs e)
{
    if (PointIsOverCurve(e.Location))
        Hits.Add(e.Location);
    else
        Misses.Add(e.Location);
    Refresh();
}

When you move the mouse, the MouseMove event handler uses the PointIsOverCurve method to see if the mouse is over the curve and it sets the form’s cursor appropriately.

The MouseClick method determines whether the point clicked is over the curve and then adds the point to the Hits or Misses list accordingly. It then refreshes the form to show the newly clicked point’s location.


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 algorithms, drawing, graphics and tagged , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

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