Проверьте, находится ли точка в повернутом прямоугольнике (C #) - PullRequest
16 голосов
/ 06 августа 2009

У меня есть программа на C # (Windows Forms), которая рисует несколько прямоугольников на картинке. Их тоже можно нарисовать под углом (повернуто).

Я знаю начальную точку каждого прямоугольника (верхний левый угол), их размер (ширина + высота) и их угол. Из-за поворота начальной точкой не обязательно является левый верхний угол, но здесь это не имеет значения. Затем, когда я щелкаю на картинке, мне нужно проверить, в каком прямоугольнике (если есть) я щелкнул.

Так что мне нужен какой-то способ проверить, находится ли точка в прямоугольнике, но мне также нужно учитывать вращение каждого прямоугольника. Кто-нибудь знает способ сделать это в C #?

Ответы [ 6 ]

22 голосов
/ 06 августа 2009

Можно ли применить то же вращение, примененное к прямоугольнику, к обратной точке?

Например, прямоугольник А поворачивается на 45 градусов по часовой стрелке от его начала (в верхнем левом углу), вам нужно просто повернуть точку B вокруг того же источника на 45 градусов СЧЕТЧИК по часовой стрелке, а затем проверить, не попадает ли он в прямоугольник А. вращение

5 голосов
/ 06 августа 2009

Вы можете сохранить второе, не отображаемое изображение, где вы рисуете дубликаты прямоугольников, каждый из которых имеет уникальный цвет. Когда пользователь нажимает на поле рисунка, найдите цвет соответствующего пикселя на втором изображении, который определит, какой прямоугольник был нажат.

3 голосов
/ 03 апреля 2017

Редактировать: оглянувшись назад, я использую 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;
    }
2 голосов
/ 07 августа 2009

Я знаю, что на этот вопрос уже ответили, но некоторое время назад мне пришлось сделать нечто подобное. Я создал метод расширения для класса System.Windows.Point, который помог сделать именно то, что предложил Нил:

    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) И тогда вы бы применили отрицательное вращение прямоугольника (как предложил Нил: pt.SetAngle (-45);) ...

Теперь, если точка находится в пределах 64, 64, вы знаете, что попали в прямоугольник. Точнее говоря, я проверял пиксель повернутого изображения, чтобы убедиться, что попал в пиксель определенного цвета.

1 голос
/ 26 сентября 2014

Если вам известны координаты углов прямоугольника, это быстрое и элегантное решение, которое включает в себя только пару точечных и скалярных произведений: https://math.stackexchange.com/a/190373/178768

1 голос
/ 07 августа 2009

Могут ли прямоугольники перекрываться? Если это так, вы хотите, чтобы все прямоугольники в точке или только один в верхнем слое?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...