Выбрать угол в диапазоне

Я хотел бы проверить, какие углы в массиве numpy находятся в пределах заданной альфа +/- дельты. Некоторые проблемы возникают, когда диапазон пересекает 0 или 360.

Если я проигнорирую граничные случаи, я мог бы сделать:

import numpy as np
def angleInRange(X,alpha,delta):
    return  (alpha - delta <= X) & (X <= alpha + delta)

Если я протестирую его с X = np.array([0, 5, 180, 355, 360]), я получу

>>> print(angleInRange(X,170,30))
[False False  True False False]     # Correct
>>> print(angleInRange(X,10 ,30))
[ True  True False False False]     # 355 and 360 are not selected
>>> print(angleInRange(X,350,30))
[False False False  True  True]     # 0 and 5 are not selected

Если я хочу получить правильный результат, мне нужно сделать что-то вроде

def angleInRange(X,alpha,delta):
    test = (   ((alpha       - delta <= X) & (X <= alpha       + delta))
             | ((alpha + 360 - delta <= X) & (X <= 360                ))
             | ((                  0 <= X) & (X <= alpha - 360 + delta))
           )

    return test

который уступает:

>>> print(angleInRange(X,170,30))
[False False  True False False]
>>> print(angleInRange(X,10 ,30))
[ True  True False True True ]
>>> print(angleInRange(X,350,30))
[True True False  True  True]

Это правильно, но есть ли более питонический и менее громоздкий способ добиться этого? Может ли здесь помочь оператор по модулю (%)?

не используйте & используйте and

Jean-François Fabre 31.10.2018 13:09

Возможный дубликат Вычисление угла между двумя углами

epsilonmajorquezero 31.10.2018 14:12

Что касается | и & вместо or и and: факт в том, что X может быть либо массивом numpy, либо серией pandas. Хотя первые работают для обоих, or и and (а также цепное сравнение) не работают с пандами.

Luca 31.10.2018 17:06
2
3
169
2

Ответы 2

В вашем случае логично использовать цепные сравнения (a < X and X < b становится a < X < b) и логические операторы, которые замыкают (| и & проверяют как левый, так и правый операнды, даже если окончательный результат известен только с левым операндом, вместо этого используйте or и and):

test =   ((alpha       - delta <= X <= alpha       + delta)
         or (alpha + 360 - delta <= X <= 360                )
         or (                  0 <= X <= alpha - 360 + delta))

Вероятно, вам помогут Эта почта или этот другой.

В основном таким образом вы используете свойство цикличности по модулю и углов:

def angleInRange(X, alpha, delta):
    anglediff = (X - alpha + 180 + 360) % 360 - 180
    return (-delta <= anglediff <= delta)

Хорошо, я сделаю это в следующий раз, но мне это кажется чем-то вроде изобретения велосипеда :)

epsilonmajorquezero 31.10.2018 14:19

Другие вопросы по теме