使用python计算径向角度,顺时针/逆时针方向,给定像素坐标(反之亦然)

Jon*_*ine 6 python trigonometry

对于我不会涉及的上下文,我需要两个基本上彼此互逆的函数.

angle_to()应返回的度数一个clockhand将不得不求助于从0°行进到连接线路p1p2(即p1是旋转的中心),和其中两个p1p2像素坐标.

point_pos()应返回的,其中长度的clockhand像素坐标amplitude就会把它变成angle.

对于这两种,正x轴= 0°= 3时,和参数rotation的计算开始在顺时针或逆时针方向上之前应该转移该轴; 然后说计算应该与这个调整后的参考方向一致.

我在每个方面取得的进展如下:失败的是:

当顺时针= False时,它返回顺时针条件的正确答案; 当顺时针= True时,angle_between()返回带有舍入错误的正确答案,而point_pos()完全给出了错误的答案.

我还附上了可视化解释,我在Illustrator嘲笑了作为道歉,互联网是无力解决这一点,在什么情况下,我追求的是不明确的.

编辑:根据下面的一个答案清理了一条不必要复杂的行.

from math import sin, cos, radians, pi, atan2, degrees

def angle_to(p1, p2, rotation=0, clockwise=False):
    if abs(rotation) > 360:
        rotation %= 360
    p2 = list(p2)
    p2[0] = p2[0] - p1[0]
    p2[1] = p2[1] - p1[1]

    angle = degrees(atan2(p2[1], p2[0]))
    if clockwise:
        angle -= rotation
        return angle if angle > 0 else angle + 360
    else:
        angle = (360 - angle if angle > 0 else -1 * angle) - rotation
        return angle if angle > 0 else angle + 360

def point_pos(origin, amplitude, angle, rotation=0, clockwise=False):
    if abs(rotation) > 360:
        rotation %= 360
    if clockwise:
        rotation *= -1
    if clockwise:
        angle -= rotation
        angle = angle if angle > 0 else angle + 360
    else:
        angle = (360 - angle if angle > 0 else -1 * angle) - rotation
        angle = angle if angle > 0 else angle + 360

    theta_rad = radians(angle)
    return int(origin[0] + amplitude * cos(theta_rad)), int(origin[1] + amplitude * sin(theta_rad))
Run Code Online (Sandbox Code Playgroud)

angle_to() point_pos()

编辑#2:根据请求,这里有一些失败的输出:

angle_to() 顺时针和逆时针翻转(当我试图修复它时,我最终得到错误的答案),顺时针方向,旋转和计算不同的方向

>>> print angle_to((100,100), (25,25))  # should be 225  
135.0
>>> print angle_to((100,100), (25,25), 45)  # should be 180
90.0
>>> print angle_to((100,100), (25,25), clockwise=True) # should be 135
225.0
>>> print angle_to((100,100), (25,25), 45, clockwise=True)  # should be 90
180.0
Run Code Online (Sandbox Code Playgroud)

point_pos() 在逆时针方向上是错误的

# dunno what these should be (i'm bad at trig) but when I visually place the
# given p1 and the output p2 on screen it's obvious that they're wrong
>>> print point_pos((100,100), 75, 225)               
(46, 153)
>>> print point_pos((100,100), 75, 225, 45)
(100, 175)

# these are basically correct, rounding-errors notwithstanding
>>> print point_pos((100,100), 75, 225, clockwise=True)
(46, 46)
>>> print point_pos((100,100), 75, 225, 45, clockwise=True)
(99, 25)
Run Code Online (Sandbox Code Playgroud)

Mar*_*som 7

通过使用一些简单的规则,您可以大大简化代码。简单的代码不太可能出现错误。

首先,顺时针和逆时针之间的转换只是意味着反转符号:angle = -angle

其次,将角度限制在[0, 360)您只需使用的范围内angle % 360。无论角度开始时是负数还是正数、整数还是浮点,这都有效。

def angle_to(p1, p2, rotation=0, clockwise=False):
    angle = degrees(atan2(p2[1] - p1[1], p2[0] - p1[0])) - rotation
    if not clockwise:
        angle = -angle
    return angle % 360
Run Code Online (Sandbox Code Playgroud)