我正在为将来要实现的游戏机制设计原型,并且在使用Python的三角函数时遇到了一些奇怪的行为。我以为Python的trig函数的工作方式不同于Java,这是我惯用的语言,但是我找不到任何文档或证据来支持它。
问题是我正在尝试将小的手势运动编码为代表他们运动方向的数字:
然后这些数字是一个字符串,代表用户移动鼠标以创建图形的每个片段的方向。然后,我可以使用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,代表这些线段“移动”的方向。但是,我注意到某些角度似乎“翻转”的奇怪结果,例如:
在此方向上的手势应给我数字“ 2”以表示45度角变化,而给我“ 8”(-45度角变化或7 / 4pi)。对于y变化不为0的所有角度,我都会得到类似的结果。因此,基本上任何不是“ 1”或“ 5”的方向。
有人知道为什么会这样吗?
答案 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?