Search code examples
c#.netwinformspicturebox

How to detect if mouse has clicked inside of a certain shape in c# on winform app?


Let's say that I have a win form app and I have a picture box called pictureBox1. Then I run the following code:

public System.Drawing.Graphics graphics;
public System.Drawing.Pen blackPen = new System.Drawing.Pen(Color.Black, 2);

public void drawVennDiagram()
{
    graphics = pictureBox1.CreateGraphics();
    graphics.DrawEllipse(blackPen, 0, 0, 100, 100);
    graphics.DrawEllipse(blackPen, 55, 0, 100, 100);
}

If I call drawVennDiagram() , it will draw two circles in pictureBox1 and the circles overlap just enough to look like a venn diagram.

What I am trying to achieve is as follows:

  • Run Method A if the mouse clicks anywhere outside of the venn diagram but in the picturebox.

  • Run Method B if the mouse clicks only inside of the first circle.

  • Run Method C if the mouse clicks inside of both circles.

  • Run Method D if the mouse clicks only inside of the second circle.

So far I have written the code below, which essentially tracks where the cursor clicks, but I have no way of figuring out which parameter (a, b, c, d) the cursor location follows.

private void pictureBox1_Click(object sender, EventArgs e)
{
    this.Cursor = new Cursor(Cursor.Current.Handle);
    int xCoordinate = Cursor.Position.X;
    int yCoordinate = Cursor.Position.Y;
}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
    int xCoordinate = e.X;
    int yCoordinate = e.Y;
}

What is the best way to achieve this?


Solution

  • Yes. Given a circle is positioned with center (xc,yc) and radius r, a coordinate (x,y) is within the circle if: (x-xc)2+(y-yc)2≤r2.

    Given we know that, we also know that your circles have a center at (50,50) and (105,50) and each have a radius of 50. So now we define a method:

    public static bool InsideCircle (int xc, int yc, int r, int x, int y) {
        int dx = xc-x;
        int dy = yc-y;
        return dx*dx+dy*dy <= r*r;
    }
    

    Now you can use:

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e) {
        int x = e.X;
        int y = e.Y;
        bool inA = InsideCircle(50,50,50,x,y);
        bool inB = InsideCircle(105,50,50,x,y);
        if(inA && inB) {
            C();
        } else if(inA) {
            B();
        } else if(inB) {
            D();
        } else {
            A();
        }
    }
    

    Note however that for now, the two circles you paint do not overlap anyway.