3

Дано направление вектора в таком формате:

  1. Направление ветра: проекция единичного вектора на ось X
  2. Направление ветра: проекция единичного вектора на ось Y

Как мне получить направление в градусах?

Получается что направление ветра это вектор (x, y) и необходимо найти угол между системой координат, т.е. вектором (0, 0)?

def __projection2angle(self, x,y):   
        delta_x = x - 0
        delta_y = y - 0
        rad = math.atan2(delta_y, delta_x)     
        deg =  rad * (180 / math.pi)
        if deg<=0:
            deg+=360
        elif deg>=360:
            deg-=360
        return deg

Что то я сомневаюсь.

Qwertiy
  • 123,725
  • Нормализовать лучше делением по модулю: deg = (deg + 360) % 360 – vp_arth May 24 '19 at 09:42
  • @vp_arth, чем лучше? – Qwertiy May 24 '19 at 09:54
  • deg>=360 - ни когда не выполнится. Остальное вроде верно. – Qwertiy May 24 '19 at 09:54
  • @Qwertiy, симпатичнее. Вкусовщина, конечно-же – vp_arth May 24 '19 at 09:55
  • atan2 вернёт значение от (-pi, pi). Поэтому, если к rad прибавить pi, он будет в (0, 2pi), а после `deg = rad (180 / math.pi)вdeg` будет значение из (0, 360) –  May 24 '19 at 10:53
  • @ⷶⷩⷮⷪⷩ, если прибавить пи (а не 2*пи), то получится неверный угол. – Qwertiy May 24 '19 at 12:20

2 Answers2

5

В целом вроде верно, но я бы сократил:

def angle(self, x, y):   
  deg = math.degrees(math.atan2(y, x))
  return deg if deg >= 0 else deg + 360

или ещё более красивый вариант:

def angle(x, y):
  deg = math.degrees(math.atan2(y, x))
  return deg % 360

Код полностью: https://ideone.com/c9MQJa и https://ideone.com/sGXhgr

import math

def angle(x, y):
  deg = math.degrees(math.atan2(y, x))
  return deg if deg >= 0 else deg + 360

print(angle( 1,  0)) #   0
print(angle( 1,  1)) #  45
print(angle( 0,  1)) #  90
print(angle(-1,  1)) # 135
print(angle(-1,  0)) # 180
print(angle(-1, -1)) # 225
print(angle( 0, -1)) # 270
print(angle( 1, -1)) # 315
Qwertiy
  • 123,725
  • Можно переписать return deg if deg >= 0 else deg + 360 в return deg % 360: https://ideone.com/sGXhgr В python это работает, см. дополнительно: https://ru.stackoverflow.com/questions/229375/Остаток-для-негативного-аргумента-ошибочен#comment229514_229503 – Андрей NOP May 29 '19 at 05:42
  • @АндрейNOP, дополнил. – Qwertiy May 29 '19 at 05:49
2

Найти угол между двумя векторами можно через dot product:

fi = arccos(dot(vec1,vec2));

тот же вариант :

fi = arccos(vec1*vec2/|vec1|*|vec2|),

где |val| это длина вектора.

То есть, если у вас есть вектора A и нужно найти угол между ним и осью x, тогда:

fi = arccos(dot(A,x));

calm27
  • 2,904
  • 2
    Чем atan2 не угодил? Про арккосинус не верю - он не весь круг возвращает. – Qwertiy May 24 '19 at 09:55
  • Верное замечание. Область значений арккосинуса [0, pi], т.е. половина круга, в то время как у atan2 (-pi, pi) –  May 24 '19 at 10:51
  • @raviga, мой вариант - как в вопросе автора. – Qwertiy May 24 '19 at 12:10
  • Впрочем, посмотрел повнимательнее и запостил. Вроде бы должно работать? UPDATE: Сам проверил - работает :) – Qwertiy May 24 '19 at 12:13