0

I want to draw a line in a bmp which is located in PictureBox with a Graphic.DrawLine(), which I can move by mouse. I can't find any function to check if the mouse is on the line or not. I found many methods to check if the mouse is over the Graphic.FillPolygon() but none about DrawLine(). Is any good solution to check it?

Edit: So by the suggestion I made such a function:

private bool IsPointInPolygon4(Point[] poly, Point p)
{
    System.Drawing.Drawing2D.GraphicsPath test = new System.Drawing.Drawing2D.GraphicsPath();
    if (poly.Length == 2) // it means there are 2 points, so it's line not the polygon
    {
        test.AddLine(poly[0], poly[1]);
        if (test.IsVisible(p, g))
        {
            MessageBox.Show("You clicked on the line, congratulations", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
            test.Dispose();
            return true;
        }
    }
    else
    {
        test.AddPolygon(poly);
        if (test.IsVisible(p, g))
        {
            MessageBox.Show("You clicked on the polygon, congratulations", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
            return true;
        }
    }
    return false;
}

It Works great for the polygons. But I can't still get the mouse event on the line. Any suggestions?

Blabla
  • 367
  • 4
  • 16

2 Answers2

2

You cannot ever be over a geometric line because it has no dimension. You can only have a point be part of the line itself, but that's impossible unless you hit it at infinite precision (even doubles won't do the job here). You can be on a pixel that has been drawn for the line but that's not the same.

You should take the geometric coordinates of the two points and the coordinates of the mouse. Then compute the distance of the mouse point from the line (it's pretty easy there's a lot of documentation on the Internet for this).

If the absolute distance is less than a threshold (1? 1.5? 2?) then you're close enough to say "on the line":

if (distance(px, py, qx, qy, mx, my) < 1.5)
{
    // on the line
}

I leave the implementation of distance() to you.

pid
  • 11,472
  • 6
  • 34
  • 63
0

Since your line can be at angles other than 0 and 90 degrees, I see 2 options.

The first is to use a Line Drawing Algorithm to compute the points of the line and check the position of the mouse vs those generated coords. This match may be slightly "fuzzy" if the line algorithm you choose differs from the one .NET uses to draw the line.

The second one is to use a GraphicsPath containing your line and call the .IsVisible(point) method on it, which will return true if the path contains the point.

I'd recommend option 2, as it is probably easier to implement, and will allow you to use a "virtual path" that is thicker than the actual line, making it a little easier for your users to interact with it.

Bradley Uffner
  • 16,641
  • 3
  • 39
  • 76
  • So I made a function in a way you suggested. I have multiple shapes, and I have arleady most functions, but there was a problem to detect the line. This works great for the polygon, but still I cant detect the mouse on the line – Blabla Apr 15 '16 at 20:09
  • Ok, i found the answer int the "duplicate" thread. thanks you :) – Blabla Apr 15 '16 at 20:14