2014-05-05 77 views
0

我有一個以中心x0,y0爲中心的正方形。我希望旋轉這個正方形的頂點給定的角度(θ),並以順時針方向返回新的旋轉頂點。我用這approach旋轉應用於每個頂點以度角度旋轉一個正方形

旋轉點(PX,PY)各地點(X0,Y0)的角度theta一個點,你會得到:

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 

此外,而不是減法。

+0

我花了幾個小時查找錯誤,謝謝! –

+1

最簡單的是最難捕捉的。 – kmacinnis

1

不要忘記幾何模塊。它可以處理各種基本形狀和處理翻譯,旋轉等...

正方形可以用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度的輕微CW旋轉(-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)點-theta檢查點旋轉公式:

>>> 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)