以度数 python 围绕另一个点旋转点
Posted
技术标签:
【中文标题】以度数 python 围绕另一个点旋转点【英文标题】:Rotate point about another point in degrees python 【发布时间】:2015-12-19 15:42:28 【问题描述】:如果你有一个点(在 2d 中),你如何在 python 中围绕另一个点(原点)旋转该点?
例如,您可以将第一个点围绕原点倾斜 10 度。
基本上你有一个点 PointA 和它旋转的原点。 代码可能如下所示:
PointA=(200,300)
origin=(100,100)
NewPointA=rotate(origin,PointA,10) #The rotate function rotates it by 10 degrees
【问题讨论】:
这是用 C++ 编写的,但问题完全相同 ***.com/questions/2259476/… 【参考方案1】:以下rotate
函数执行点point
在笛卡尔平面中围绕origin
旋转角度angle
(以弧度为单位),使用通常的轴约定:x 从左增加向右,y 垂直向上增加。所有点都表示为 (x_coord, y_coord)
形式的长度为 2 的元组。
import math
def rotate(origin, point, angle):
"""
Rotate a point counterclockwise by a given angle around a given origin.
The angle should be given in radians.
"""
ox, oy = origin
px, py = point
qx = ox + math.cos(angle) * (px - ox) - math.sin(angle) * (py - oy)
qy = oy + math.sin(angle) * (px - ox) + math.cos(angle) * (py - oy)
return qx, qy
如果您的角度以度为单位,您可以先使用math.radians
将其转换为弧度。对于顺时针旋转,取反角度。
示例:将点(3, 4)
围绕(2, 2)
的原点逆时针旋转10 度角:
>>> point = (3, 4)
>>> origin = (2, 2)
>>> rotate(origin, point, math.radians(10))
(2.6375113976783475, 4.143263683691346)
请注意,rotate
函数中有一些明显的重复计算:math.cos(angle)
和 math.sin(angle)
分别计算了两次,px - ox
和 py - oy
也是如此。如有必要,我留给您考虑。
【讨论】:
这是一个很好的解决方案。如果您想转置 Y 轴的方向(y 垂直向下增加),这会发生什么变化?谢谢。 当我的原始坐标在 [0,127] 范围内并且我将旋转中心设置为 (63.5,63.5) 时,使用此函数有时会得到负坐标。这是由于舍入错误吗?如何预防? @SimonH:可能是舍入错误;可能只是几何。如果您取正方形 [0, 127] x [0, 127] 并将其旋转 10 度(例如)大约 (63.5, 63.5),那么旋转正方形 的位将在第一个之外象限。如果您的点在以 (63.5, 63.5) 为中心的 disk 半径 63.5 内,那么是的,从数学上讲,您不应该看到负坐标的结果。如果您看到非常接近零的负值,那么是的,可能是舍入错误的原因。 谢谢!我想到了。问题与旋转没有直接关系,而是与我在旋转之前执行的缩放有关 我尝试在原点周围旋转多个矩形和三角形平面。它可以工作,但形状会变形(即矩形变成平行四边形)【参考方案2】:将一个点围绕另一个点旋转几度的选项是使用numpy
而不是math
。这允许轻松地泛化函数以将任意数量的点作为输入,例如在旋转多边形时很有用。
import numpy as np
def rotate(p, origin=(0, 0), degrees=0):
angle = np.deg2rad(degrees)
R = np.array([[np.cos(angle), -np.sin(angle)],
[np.sin(angle), np.cos(angle)]])
o = np.atleast_2d(origin)
p = np.atleast_2d(p)
return np.squeeze((R @ (p.T-o.T) + o.T).T)
points=[(200, 300), (100, 300)]
origin=(100,100)
new_points = rotate(points, origin=origin, degrees=10)
print(new_points)
【讨论】:
这是一个优雅而复杂的解决方案。【参考方案3】:import math
def rotate(x,y,xo,yo,theta): #rotate x,y around xo,yo by theta (rad)
xr=math.cos(theta)*(x-xo)-math.sin(theta)*(y-yo) + xo
yr=math.sin(theta)*(x-xo)+math.cos(theta)*(y-yo) + yo
return [xr,yr]
【讨论】:
【参考方案4】:经过大量代码和存储库。这个功能最适合我。它也很有效,因为它只计算一次正弦和余弦值。
import numpy as np
def rotate(point, origin, degrees):
radians = np.deg2rad(degrees)
x,y = point
offset_x, offset_y = origin
adjusted_x = (x - offset_x)
adjusted_y = (y - offset_y)
cos_rad = np.cos(radians)
sin_rad = np.sin(radians)
qx = offset_x + cos_rad * adjusted_x + sin_rad * adjusted_y
qy = offset_y + -sin_rad * adjusted_x + cos_rad * adjusted_y
return qx, qy
【讨论】:
如何将其扩展到 3d?【参考方案5】:如果您将点表示为复数并使用带有虚构参数的 exp 函数(这等效于其他答案中显示的 cos/sin 运算,但更易于编写和记忆),这很容易。这是一个围绕所选原点旋转任意数量点的函数:
import numpy as np
def rotate(points, origin, angle):
return (points - origin) * np.exp(complex(0, angle)) + origin
要以度为单位围绕原点 (x0,y0) 旋转单个点 (x1,y1),您可以使用以下参数调用函数:
points = complex(x1,y1)
origin = complex(x0,y0)
angle = np.deg2rad(degrees)
要旋转多个点 (x1,y1), (x2,y2), ...,请使用:
points = np.array([complex(x1,y1), complex(x2,y2), ...])
单点 (200,300) 围绕 (100,100) 旋转 10 度的示例:
>>> new_point = rotate(complex(200,300), complex(100,100), np.deg2rad(10))
>>> new_point
(163.75113976783473+314.3263683691346j)
>>> (new_point.real, new_point.imag)
(163.75113976783473, 314.3263683691346)
【讨论】:
以上是关于以度数 python 围绕另一个点旋转点的主要内容,如果未能解决你的问题,请参考以下文章