Я работаю над прототипом игровой механики, который хочу реализовать в будущем, и столкнулся с каким-то странным поведением, работая с тригонометрическими функциями Python. Я подумал, что триггерные функции Python работают иначе, чем Java, к которому я привык, но я не могу найти никакой документации или свидетельств, подтверждающих это.
Проблема в том, что я пытаюсь закодировать маленькие жесты в виде чисел, представляющих направление, в котором они сместились:
И затем эти числа представляют собой строку, обозначающую направления, по которым пользователь перемещал мышь для создания каждого сегмента чертежа. Затем я могу использовать алгоритм расстояния Левенштейна, чтобы определить наиболее близкое соответствие с заранее определенными «чертежами».
Путаница возникает из-за того, что я, похоже, не получаю правильные значения тета от метода atan2. Система координат PyGame - это стандартная верхняя левая (0,0) точка начала координат, причем y увеличивается вниз. Чтобы вычислить тета для двух точек, я делаю:
theta = math.atan2((p2[1] - p1[1]), (p2[0] - p1[0]))
theta = ((theta + (math.pi * 2)) % (math.pi * 2))
После того, как пользователь закончил рисовать жест, он представляется в виде серии точек и определяется расстояние между ними. Я перебираю эти точки и сравниваю их с точкой перед ними в списке, чтобы получить тета-значение этого отрезка, а затем кодирую его как число 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».
Кто-нибудь знает, почему это происходит?