Проверьте, находится ли точка во вращающемся прямоугольнике (C #)

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

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

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

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

Например, прямоугольник A поворачивается на 45 gradleусов по часовой стрелке от его начала (в верхнем левом углу), тогда вы просто вращаете точку B вокруг того же начала 45 gradleусов COUNTER по часовой стрелке, затем проверяете, попадает ли он в прямоугольник A перед rotationм

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

Я знаю, что это уже ответили, но мне нужно было сделать что-то подобное некоторое время назад. Я создал метод расширения для classа 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) И тогда вы применили бы отрицательное rotation прямоугольника (как предложил Neil: pt.SetAngle (-45);) …

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

Edit: Оглядываясь назад, я использую MonoGame, а OP использует Windows Forms. Для MonoGame предусмотрено следующее.

Я уже давно это испортил и нашел пару ответов, только никто из них не работал. Вот C # -функция, которая работает точно так, как описывает OP, если не для OP, то другие люди, как я, были Google.

Это была головная боль, чтобы понять это. Много типичных догадок.

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

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

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