检查点是否在旋转的矩形中(C#)

时间:2009-08-06 18:41:57

标签: c# math graphics geometry

我有一个C#程序(Windows窗体),它在一个图片框上绘制一些矩形。它们也可以以一定角度绘制(旋转)。

我知道每个矩形的起点(左上角),它们的大小(宽度+高度)和它们的角度。由于旋转,起点不一定是左上角,但这并不重要。 然后当我点击图片框时,我需要检查我点击了哪个矩形(如果有的话)。

所以我需要一些检查点是否在矩形中的方法,但我还需要考虑每个矩形的旋转。 有没有人知道在C#中做到这一点的方法?

7 个答案:

答案 0 :(得分:22)

是否可以将应用于矩形的相同旋转应用于反向点?

例如,矩形A从其原点(左上角)顺时针旋转45度,然后您可以顺时针旋转点B绕同一原点45度逆时针旋转,然后检查它是否属于矩形A前旋转

答案 1 :(得分:5)

您可以保留第二个未显示的图像,其中绘制矩形的副本,每个矩形都是唯一着色的。当用户点击图片框时,找到第二张图片中相应像素的颜色,这将识别被点击的矩形。

答案 2 :(得分:3)

编辑:回顾之后,我使用的是MonoGame,而OP正在使用Windows Forms。以下是MonoGame。

我现在已经搞砸了一段时间并找到了几个答案,但其中没有一个真正起作用。这是一个C#函数,完全按照OP描述,如果没有OP,那么其他人用谷歌搜索就像我一样。

想出这个很令人头疼。很多典型的猜测。

    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;
    }

这里只有一行代码。可能更快使用。

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

答案 3 :(得分:2)

我知道这已经回答了,但我不得不做一些类似的事情。我为System.Windows.Point类创建了一个扩展方法,该方法完全符合Neil的建议:

    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;
    }

这将允许我使用0,0左右的点的角度。因此,如果您知道正在测试的矩形的中心,则会将该点偏移该值的负值(例如:pt.X - = 32; pt.Y - = 32)然后你将应用矩形的负旋转(如Neil所建议:pt.SetAngle(-45);)......

现在如果该点在64,64之内,你知道你击中了矩形。更具体地说,我正在检查旋转图像的像素,以确保我击中特定颜色的像素。

答案 4 :(得分:1)

是否允许矩形重叠? 如果是这样,你想要一个点中的所有矩形,还是只需要顶层中的那个矩形?

答案 5 :(得分:1)

如果您知道矩形角的坐标,这是一个快速,优雅的解决方案,仅涉及几个点和标量产品:https://math.stackexchange.com/a/190373/178768

答案 6 :(得分:0)

将矩形边缘看作是矢量列表,这些矢量将一个角链接到下一个角,顺时针对角进行排序。如果该点在正方形中,则它必须相对于所有边缘向量在右侧。

这可以通过矢量积来解决,但是归结为以下几点:

遍历矩形角:

  • 要检查的点是P=[px,py]
  • 当前拐角是C=[cx,cy],下一个拐角是N=[nx,ny]
  • 如果px*ny+cx*py+nx*cy<py*nx+cy*px+ny*cx,则该点在正方形之外。

这实际上适用于每个凸多边形。