Hit Detection on a Line

I want to know if the mouse is over (hitting) a line. Therefore I created a Region object that holds the line and use the IsVisible() method to test if the mouse hits the line. It doesn't work! In the little program below I create two Regions: one is square, the other is a line. Hit testing works on the square-Region, not on the line-Region.

How can I do a hit-test over a line


//namespace HitTest
namespace HitTest
{


//class Form
class Form:System.Windows.Forms.Form
{



//two points that make up a line
System.Drawing.Point point1=new System.Drawing.Point(0,0);
System.Drawing.Point point2=new System.Drawing.Point(50,50);




//a rectangle
System.Drawing.Rectangle rectangle=new
System.Drawing.Rectangle(50,50,100,100);




//a line region
System.Drawing.Region line;




//a square region
System.Drawing.Region square;




//a brush
System.Drawing.Brush brush=System.Drawing.Brushes.White;




//constructor
Form()
{


//set style for double buffered graphics
SetStyle
(
System.Windows.Forms.ControlStyles.AllPaintingInWmPaint|
System.Windows.Forms.ControlStyles.DoubleBuffer|
System.Windows.Forms.ControlStyles.ResizeRedraw|
System.Windows.Forms.ControlStyles.UserPaint,
true
);


//get a GraphicsPath object
System.Drawing.Drawing2D.GraphicsPath graphicspath=new
System.Drawing.Drawing2D.GraphicsPath();


//add a line to the graphicspath
graphicspath.AddLine(0,0,50,50);


//use the graphicspath to define the line-region
line=new System.Drawing.Region(graphicspath);


//use the rectangle to define the square-region
square=new System.Drawing.Region(rectangle);


//prepare for mouse-input
MouseMove+=new System.Windows.Forms.MouseEventHandler(OnMouseMove);


//prepare for paint
Paint+=new System.Windows.Forms.PaintEventHandler(this.OnPaint);

}




//OnMouseMove
void OnMouseMove(object a,System.Windows.Forms.MouseEventArgs b)
{

//use White brush
brush=System.Drawing.Brushes.White;

if(square.IsVisible(b.X,b.Y))
{

//use Red brush if mouse is over square
brush=System.Drawing.Brushes.Red;
}

else if(line.IsVisible(b.X,b.Y))
{

//use Blue brush if mouse is over line
brush=System.Drawing.Brushes.Blue;
}

//force redraw
Invalidate();
}




//OnPaint
void OnPaint(object a,System.Windows.Forms.PaintEventArgs b)
{
b.Graphics.DrawLine(System.Drawing.Pens.Black,point1,point2);
b.Graphics.DrawRectangle(System.Drawing.Pens.Black,rectangle);
b.Graphics.FillRegion(brush,square);
}




//Main
public static void Main()
{
System.Windows.Forms.Application.Run(new Form());
}
}
}




Answer this question

Hit Detection on a Line

  • Marian Drumea

    Here is the same program with some minor modifications that DOES implement a hit test on a line (thanks to Stoitcho Goutsev)


    //namespace HitTest
    namespace HitTest
    {


    //class Form
    class Form:System.Windows.Forms.Form
    {



    //two points that make up a line
    System.Drawing.Point point1=new System.Drawing.Point(0,0);
    System.Drawing.Point point2=new System.Drawing.Point(50,50);




    //a rectangle
    System.Drawing.Rectangle rectangle=new
    System.Drawing.Rectangle(50,50,100,100);




    //a square region
    System.Drawing.Region square;



    //a graphicspath
    System.Drawing.Drawing2D.GraphicsPath graphicspath=new
    System.Drawing.Drawing2D.GraphicsPath();




    //a brush
    System.Drawing.Brush brush=System.Drawing.Brushes.White;




    //constructor
    Form()
    {


    //set style for double buffered graphics
    SetStyle
    (
    System.Windows.Forms.ControlStyles.AllPaintingInWmPaint|
    System.Windows.Forms.ControlStyles.DoubleBuffer|
    System.Windows.Forms.ControlStyles.ResizeRedraw|
    System.Windows.Forms.ControlStyles.UserPaint,
    true
    );


    //add a line to the graphicspath
    graphicspath.AddLine(point1,point2);



    //use the rectangle to define the square-region
    square=new System.Drawing.Region(rectangle);


    //prepare for mouse-input
    MouseMove+=new System.Windows.Forms.MouseEventHandler(OnMouseMove);


    //prepare for paint
    Paint+=new System.Windows.Forms.PaintEventHandler(OnPaint);

    }




    //OnMouseMove
    void OnMouseMove(object a,System.Windows.Forms.MouseEventArgs b)
    {

    //use White brush
    brush=System.Drawing.Brushes.White;

    if(square.IsVisible(b.X,b.Y))
    {

    //use Red brush if mouse is over square
    brush=System.Drawing.Brushes.Red;
    }

    else if(graphicspath.IsOutlineVisible(b.X,b.Y,System.Drawing.Pens.Black))
    {

    //use Blue brush if mouse is over line
    brush=System.Drawing.Brushes.Blue;
    }

    //force redraw
    Invalidate();
    }




    //OnPaint
    void OnPaint(object a,System.Windows.Forms.PaintEventArgs b)
    {
    b.Graphics.DrawLine(System.Drawing.Pens.Black,point1,point2);
    b.Graphics.DrawRectangle(System.Drawing.Pens.Black,rectangle);
    b.Graphics.FillRectangle(brush,rectangle);
    }



    //Main
    public static void Main()
    {
    System.Windows.Forms.Application.Run(new Form());
    }
    }
    }



  • Hit Detection on a Line