Самый простой способ повернуть прямоугольник - PullRequest
7 голосов
/ 18 февраля 2010

Я использую прямоугольники, определенные в соответствии с их координатами x y, их шириной и высотой. Я понял, как повернуть их в терминах координат (x = cos(deg) * x - sin(deg) * y y = sin(deg) * x + cos(deg) * y), но я застрял на высоте и ширине. Я уверен, что есть очевидное решение, которое я пропускаю. Если это имеет значение, я использую Python.

edit Извините за запутанное описание. Мое намерение состоит в том, чтобы изменить ширину и высоту либо на обратную, либо на отрицательную из-за любого угла. Например, при повороте на 90 градусов значения будут меняться. При повороте на 180 градусов ширина будет отрицательной. Кроме того, я намерен использовать кратные 90 в моем сценарии. Я мог бы просто использовать if операторы, но я предполагал, что будет более "элегантный" метод.

Ответы [ 4 ]

5 голосов
/ 18 февраля 2010

Просто рассчитайте четыре угла вашего прямоугольника:

p1 = (x, y)
p2 = (x + w, y)
p3 = (x, y + h)

и поверните каждый на угол Вы хотите:

p1 = rotate(p1, angle)
# and so on...

и преобразуйте обратно в прямоугольное представление:

x, y = p1
w = dist(p1, p2)  # the same as before rotation
h = dist(p1, p3)

где dist вычисляет расстояние между двумя точками.

Редактировать: Почему бы вам не попробовать применить формулу, которую вы написали для (width, height) пары?

x1 = cos(deg) * x - sin(deg) * y
y2 = sin(deg) * x + cos(deg) * y

Легко видеть, что если deg == 90 значения поменяются:

x1 = -y
y2 =  x

и если deg == 180 они будут отрицаться:

x1 = -x
y2 = -y

и так далее ... Я думаю, это то, что Вы ищете.

Edit2:

А вот и функция быстрого вращения:

def rotate_left_by_90(times, x, y):
    return [(x, y), (-y, x), (-x, -y), (y, -x)][times % 4]
2 голосов
/ 18 февраля 2010

Правильным способом было бы прибегнуть к матрицам преобразования. Кроме того, исходя из вашего вопроса, я предполагаю, что вы хотите повернуть относительно (x = 0, y = 0), но если нет, вам нужно будет принять это во внимание и сначала перевести прямоугольник в центр плана ( затем переведите его обратно, когда вращение будет выполнено).

M = Матрица для перевода в центр R = матрица вращения

Матрица преобразования = M ^ (- 1) * R * M

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

Чтобы узнать больше о матрицах преобразования: http://en.wikipedia.org/wiki/Transformation_matrix

1 голос
/ 18 февраля 2010

Из того, как вы описываете вращение только на 90 градусов, и из-за того, как вы определяете ширину и высоту, возможно, вы ищете что-то вроде

direction = 1     // counter-clockwise degrees
// or
direction = -1    // clockwise 90 degrees

new_height = width * direction
new_width = -height * direction
width = new_width
height = new_height

Не уверен, почему вы хотите иметь отрицательные значения для ширины и высоты, хотя .. потому что в противном случае каждое вращение на 90 градусов эффективно просто меняет ширину и высоту, независимо от того, в каком направлении вы вращаетесь.

1 голос
/ 18 февраля 2010

Вращение не должно меняться width и height. Ваше уравнение верное, если вы хотите повернуть (x, y) примерно на (0,0) на deg, но учтите, что часто функции cos и sin ожидают аргументы в радианах, а не в градусах, поэтому вам может потребоваться умножьте deg на pi/180 (радианы на градус).

Если вам нужно найти расположение других вершин прямоугольника помимо (x, y) после поворота, то вам следует либо сохранить и повернуть их вместе с (x, y), либо сохранить некоторую информацию об ориентации прямоугольника (например, градус). ) так что вы можете пересчитать их как, например, x + width cos (deg), y + height sin (deg).

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