Jon*_*ine 6 python trigonometry
对于我不会涉及的上下文,我需要两个基本上彼此互逆的函数.
angle_to()应返回的度数一个clockhand将不得不求助于从0°行进到连接线路p1来p2(即p1是旋转的中心),和其中两个p1与p2是像素坐标.
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)
编辑#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)
通过使用一些简单的规则,您可以大大简化代码。简单的代码不太可能出现错误。
首先,顺时针和逆时针之间的转换只是意味着反转符号: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)