Повернуть квадрат на угол в градусах
У меня есть квадрат с центром х0, у0. Я хочу повернуть вершину этого квадрата на заданный угол (тета), выраженный в градусах, и вернуть новую повернутую вершину по часовой стрелке. Я использую этот подход, чтобы повернуть одну точку, примененную для каждой вершины
поверните точку (px, py) вокруг точки (x0, y0) на угол тета, который вы получите:
p'x = cos(theta) * (px-x0) - sin(theta) * (py-y0) + x0
p'y = sin(theta) * (px-x0) + cos(theta) * (py-y0) + y0
where:
px, py = coordinate of the point
y0, x0, = centre of rotation
theta = angle of rotation
Я написал в Python функцию, параметры которой: x, y (= центр квадрата), сторона квадрата и theta_degree (угол поворота в градусах), но возвращаемое значение направлено против часовой стрелки
from math import cos, sin
def get_square_plot(x, y, side, theta_degree=0):
theta = theta_degree * pi/180
xa = x-side/2
ya = y+side/2
xb = x+side/2
yb = y+side/2
xc = x+side/2
yc = y-side/2
xd = x-side/2
yd = y-side/2
xa_new = cos(theta) * (xa - x) - sin(theta) * (ya - y) + x
ya_new = sin(theta) * (xa - x) - cos(theta) * (ya - y) + y
xb_new = cos(theta) * (xb - x) - sin(theta) * (yb - y) + x
yb_new = sin(theta) * (xb - x) - cos(theta) * (yb - y) + y
xc_new = cos(theta) * (xc - x) - sin(theta) * (yc - y) + x
yc_new = sin(theta) * (xc - x) - cos(theta) * (yc - y) + y
xd_new = cos(theta) * (xd - x) - sin(theta) * (yd - y) + x
yd_new = sin(theta) * (xd - x) - cos(theta) * (yd - y) + y
return [(xa_new, ya_new),(xb_new, yb_new),(xc_new, yc_new),(xd_new, yd_new)]
get_square_plot(0, 0, 10, 0)
[(-5.0, -5.0), (5.0, -5.0), (5.0, 5.0), (-5.0, 5.0)]
вместо
[(-5.0, 5.0), (5.0, 5.0), (5.0, -5.0), (-5.0, -5.0)]
2 ответа
Это так просто - у вас неверная формула для всех ваших значений y.
Так должно быть:
ya_new = sin(theta) * (xa - x) + cos(theta) * (ya - y) + y
сложение вместо вычитания.
Не забывайте и о геометрическом модуле. Он может иметь дело с различными основными формами и обрабатывать перевод, вращение и т. Д.
Квадрат может быть построен с помощью RegularPolygon. Это достигается путем нахождения вершин заданного радиуса от центра; чтобы получить квадрат с заданной длиной стороны, разделите на sqrt(2). Вот функция для поворота алмазной ориентации, чтобы стороны были параллельны осям, а затем поворачивали желаемый угол, a
:
>>> Square = lambda c, r, a: RegularPolygon(c, r/sqrt(2), 4, -rad(a) - pi/4)
>>> Square((0,0),10,0).vertices
[Point(5, -5), Point(5, 5), Point(-5, 5), Point(-5, -5)]
>>> [w.n(2) for w in Square((0,0),10,1).vertices]
[Point(4.9, -5.1), Point(5.1, 4.9), Point(-4.9, 5.1), Point(-5.1, -4.9)]
Обратите внимание, что небольшое вращение по часовой стрелке на 1 градус (-rad(1)) помещает первую вершину немного ближе к оси y и немного ниже, как мы ожидаем. Вы также можете ввести символ для угла:
>>> from sympy.utilities.misc import filldedent
>>> print filldedent(Square((0,0),10,a).vertices)
[Point(5*sqrt(2)*cos(pi*a/180 + pi/4), -5*sqrt(2)*sin(pi*a/180 +
pi/4)), Point(5*sqrt(2)*sin(pi*a/180 + pi/4), 5*sqrt(2)*cos(pi*a/180 +
pi/4)), Point(-5*sqrt(2)*cos(pi*a/180 + pi/4), 5*sqrt(2)*sin(pi*a/180
+ pi/4)), Point(-5*sqrt(2)*sin(pi*a/180 + pi/4),
-5*sqrt(2)*cos(pi*a/180 + pi/4))]
Вы также можете проверить формулу вращения точки, вращая точку-тета (для CW):
>>> var('px py theta x0 y0')
(px, py, theta, x0, y0)
>>> R = Point(px,py).rotate(-theta, Point(x0,y0))
>>> R.x
x0 + (px - x0)*cos(theta) + (py - y0)*sin(theta)
>>> R.y
y0 + (-px + x0)*sin(theta) + (py - y0)*cos(theta)