Нечетное поведение из тригонометрических функций - PullRequest
0 голосов
/ 14 января 2019

Я работаю над прототипом игровой механики, который хочу реализовать в будущем, и столкнулся с каким-то странным поведением, работая с тригонометрическими функциями Python. Я подумал, что триггерные функции Python работают иначе, чем Java, к которому я привык, но я не могу найти никакой документации или свидетельств, подтверждающих это.

Проблема в том, что я пытаюсь закодировать маленькие жесты в виде чисел, представляющих направление, в котором они сместились:

Diagram 1

И затем эти числа представляют собой строку, обозначающую направления, по которым пользователь перемещал мышь для создания каждого сегмента чертежа. Затем я могу использовать алгоритм расстояния Левенштейна, чтобы определить наиболее близкое соответствие с заранее определенными «чертежами».

Путаница возникает из-за того, что я, похоже, не получаю правильные значения тета от метода 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, представляющих направления, в которых эти отрезки линии "двигались". Однако я заметил странные результаты, когда некоторые углы кажутся «перевернутыми», например:

Angle

Если жест в этом направлении должен дать мне число «2» для обозначения изменения угла на 45 градусов, вместо этого оно дает мне «8» (изменение угла на -45 градусов или 7 / 4pi). Я получаю аналогичные результаты для всех углов, где изменение y не равно 0. Так что в основном любое направление, которое не является «1» или «5».

Кто-нибудь знает, почему это происходит?

...