三角函数的奇怪行为

时间:2019-01-14 20:52:31

标签: python pygame trigonometry

我正在为将来要实现的游戏机制设计原型,并且在使用Python的三角函数时遇到了一些奇怪的行为。我以为Python的trig函数的工作方式不同于Java,这是我惯用的语言,但是我找不到任何文档或证据来支持它。

问题是我正在尝试将小的手势运动编码为代表他们运动方向的数字:

Diagram 1

然后这些数字是一个字符串,代表用户移动鼠标以创建图形的每个片段的方向。然后,我可以使用Levenshtein距离算法来确定与预定义“绘图”最接近的匹配。

我似乎没有从atan2方法中获得正确的theta值,这是造成困惑的原因。 PyGame的坐标系是标准的左上(0,0)原点,y向下增加。要计算两点的θ,我要做:

theta = math.atan2((p2[1] - p1[1]), (p2[0] - p1[0]))
theta = ((theta + (math.pi * 2)) % (math.pi * 2))

用户完成手势绘制后,将其表示为一系列点,并定义它们之间的距离。我遍历这些点,并将它们与列表中它们前面的点进行比较,以获取该线段的theta值,然后将其编码为1-8:

DIRECTIONS = [...list of radian values of angles 0 through 2pi...]
for p in range(len(points) - 1):
    p1 = points[p]
    p2 = points[p + 1]
    theta = math.atan2((p2[1] - p1[1]), (p2[0] - p1[0]))
    theta = ((theta + (math.pi * 2)) % (math.pi * 2))
    closest = 0
    cDiff = (math.pi * 2)
    for i in range(len(DIRECTIONS)):
        direction = DIRECTIONS[i]
        diff = abs(theta - direction)
        if diff < cDiff:
            cDiff = diff
            closest = i
    if closest == (len(DIRECTIONS) - 1):
        dir.append(1) # redundancy so you can compare theta values > 315 to 0
    else:
        dir.append(closest + 1)

这应该给我一串数字1-8,代表这些线段“移动”的方向。但是,我注意到某些角度似乎“翻转”的奇怪结果,例如:

Angle

在此方向上的手势应给我数字“ 2”以表示45度角变化,而给我“ 8”(-45度角变化或7 / 4pi)。对于y变化不为0的所有角度,我都会得到类似的结果。因此,基本上任何不是“ 1”或“ 5”的方向。

有人知道为什么会这样吗?

1 个答案:

答案 0 :(得分:0)

在计算角度时,y 轴必须反转(-y 分别为 p1[1] - p2[1]),因为在 PyGame 坐标系中,y 轴是向下的。但是 math.atan2 在数学坐标系中计算逆时针角度,x 轴指向右侧,y 轴指向上方:

theta = math.atan2((p2[1] - p1[1]), (p2[0] - p1[0]))

theta = math.atan2((p1[1] - p2[1]), (p2[0] - p1[0]))

另见How to know the angle between two points?How do I find the coordinates of a point on a circle in PyGame?