以度数 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 - oxpy - 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 围绕另一个点旋转点的主要内容,如果未能解决你的问题,请参考以下文章

使用 atan2() 返回的角度围绕另一个点旋转一个点

OpenCV Python围绕特定点旋转图像X度

使用OpenCV旋转点周围的点

想问一个关于数学旋转的问题,就是在直角坐标系中,某个点绕原点旋转某个度数,应该怎么求出旋转后的度数

围绕特定轴旋转 gluCylinder()?

物体围绕某个点旋转一定角度