Сначала я начал пешеходный путь и сравнил два возможных поворота:
def nearest_signed(old, new):
angles = ((new - old)%360, (new - old)%360 - 360)
return min(angles, key=abs)
Мы проверяем угол по модулю 360 и его дополнение в другом направлении.
Вроде работает:
>>> nearest_signed(0, 359)
-1
>>> nearest_signed(359, 0)
1
>>> nearest_signed(180, 2)
-178
>>> nearest_signed(2, 180)
178
Теперь я хотел посмотреть, как это происходит, поэтому я составил график для каждой комбинации углов:
import numpy as np
matplotlib.pyplot as plt
news,olds = np.ogrid[:360, :360]
rights = (news - olds) % 360
lefts = rights - 360
take_rights = abs(rights) < abs(lefts)
nearest_signed = np.where(take_rights, rights, lefts)
fig,ax = plt.subplots()
cf = ax.contourf(news.ravel(), olds.ravel(), nearest_signed, cmap='viridis', levels=np.linspace(-180, 180, 100), vmin=-180, vmax=180)
ax.set_xlabel('new angle')
ax.set_ylabel('old angle')
cb = plt.colorbar(cf, boundaries=(-180, 180))
plt.show()
Теперь это делает очевидным, что простой модуль разности углов должен работать. И конечно же:
>>> np.array_equal((news - olds + 180) % 360 - 180, nearest_signed)
True
Это означает, что формула, которую вы ищете, это
(new - old + 180) % 360 - 180
Дайте или возьмите знак различия в вашем соглашении. Если вы считаете знаки вращения наоборот, просто переключите два угла:
(old - new + 180) % 360 - 180