Check if a point is in a rotated rectangle (C#)

前端 未结 7 1467
囚心锁ツ
囚心锁ツ 2021-01-07 22:20

I have a program in C# (Windows Forms) which draws some rectangles on a picturebox. They can be drawn at an angle too (rotated).

I know each of the rectangles\' star

相关标签:
7条回答
  • 2021-01-07 22:30

    I know this was already answered but I had to do something similar a while ago. I created an extension method for the System.Windows.Point class that helped do exactly what Neil suggested:

        public static double GetAngle(this Point pt)
        {
            return Math.Atan2(pt.X, -pt.Y) * 180 / Math.PI;
        }
    
        public static Point SetAngle(this Point pt, double angle)
        {
            var rads = angle * (Math.PI / 180);
            var dist = Math.Sqrt(pt.X * pt.X + pt.Y * pt.Y);
            pt.X = Math.Sin(rads) * dist;
            pt.Y = -(Math.Cos(rads) * dist);
            return pt;
        }
    

    This would allow me to work with the angles of points around 0, 0. So if you know the center of the rect that you are testing you would offset the point by the negative of this value (for example: pt.X -= 32; pt.Y -= 32) And then you would apply the negative rotation of the rectangle (as suggested by Neil: pt.SetAngle(-45);)...

    Now if the point is within 64, 64 you know you hit the rectangle. More specifically I was checking a pixel of a rotated image to make sure I hit a pixel of a specific color.

    0 讨论(0)
  • 2021-01-07 22:38

    See the rectangle edges as a list of vectors linking a corner to the next, sorting corners clockwise. If the point is in the square, it must be to the right with respect to all of the edge vectors.

    This can be solved by vector products, but it boils down to the following:

    Iterate over rectangle corners:

    • the point to be checked is P=[px,py]
    • the current corner is C=[cx,cy] and the next corner is N=[nx,ny]
    • if px*ny+cx*py+nx*cy<py*nx+cy*px+ny*cx, the point is outside the square.

    this would actually work for every convex polygon.

    0 讨论(0)
  • 2021-01-07 22:49

    Would the rectangles be allowed to overlap? If so, would you want all the rectangles in a point, or just the one in the top layer?

    0 讨论(0)
  • 2021-01-07 22:51

    Is it possible to apply the same rotation applied to the rectangle to the point in reverse?

    For example, Rectangle A is rotated 45 degrees clockwise from its origin (upper left corner), you would then just rotate point B around the same origin 45 degrees COUNTER clockwise, then check to see if it falls within Rectangle A pre-rotation

    0 讨论(0)
  • 2021-01-07 22:51

    Edit: After looking back, I'm using MonoGame and the OP is using Windows Forms. The following is for MonoGame.

    I've been messing this for a while now and have found a couple answers, just none of them actually worked. Here is a C# function that does exactly as OP describes, if not for OP then other people Googling like I was.

    It was a headache to figure this out. A lot of the typical guesswork.

        bool PointIsInRotatedRectangle(Vector2 P, Rectangle rect, float rotation)
        {
            Matrix rotMat = Matrix.CreateRotationZ(-rotation);
            Vector2 Localpoint = P - (rect.Location).ToVector2();
            Localpoint = Vector2.Transform(Localpoint, rotMat);
            Localpoint += (rect.Location).ToVector2();
    
            if (rect.Contains(Localpoint)) { return true; }
            return false;
        }
    

    And here it is in a single line of code. Probably faster to use.

        bool PointIsInRotatedRectangle(Vector2 P, Rectangle rect, float rotation)
        {
            return rect.Contains(Vector2.Transform(P - (rect.Location).ToVector2(), Matrix.CreateRotationZ(-rotation)) + (rect.Location).ToVector2());
        }
    
    0 讨论(0)
  • 2021-01-07 22:53

    If you know the coordinates of the corners of the rectangle, this is an fast, elegant solution that merely involves a couple of dot and scalar products: https://math.stackexchange.com/a/190373/178768

    0 讨论(0)
提交回复
热议问题