Метод для вычисления угла между двумя векторами, выбрасывающими ошибку, если векторы идентичны? - PullRequest
2 голосов
/ 02 марта 2020

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

Метод выглядит следующим образом:

def CalculateAngleBetweenVector(vector, vector2):

    dp = np.dot(vector, vector2)

    maga = math.sqrt((vector[0] ** 2) + vector[1] ** 2 + vector[2] ** 2)
    magb = math.sqrt((vector2[0] ** 2) + vector2[1] ** 2 + vector2[2] ** 2)
    magc = maga * magb

    dpmag = dp / magc

    angleindeg = ((math.acos(dpmag)) * 180) / math.pi

    return angleindeg

В настоящее время у меня есть два идентичных вектора, которые собираются проверить что-то еще и понял этот метод ошибки, когда я делаю. Два вектора:

[ 0.38154065 -0.38688849 -0.83949034]

Метод, который я использую для определения векторов единиц для входов:

UnitVector = Vector / np.linalg.norm(Vector)

Просто если что-то здесь не так.

Любая помощь очень ценится.

Спасибо

edit:

извините, вектор идет на самом деле (0.38154065, -0.38688849, -0.83949034) Я только что скопировал строку печати терминала. Ошибка - математическая ошибка домена.

edit2:

Error traceback:

Traceback (most recent call last):
  File "file path info that contains personal info Documents/com~apple~CloudDocs/WORK/Code1/CompareAnglesBetweenProteinAndMembane.py", line 261, in <module>
    angle = CalculateAngleBetweenVector(ProteinRotatedUV, MemRotatedUV)
  File "file path info that contains personal info Documents/com~apple~CloudDocs/WORK/Code1/CompareAnglesBetweenProteinAndMembane.py", line 167, in CalculateAngleBetweenVector
    angleindeg = ((math.acos(dpmag)) * 180) / math.pi
ValueError: math domain error

1 Ответ

1 голос
/ 02 марта 2020

Как обсуждалось в комментариях, проблема связана с ошибками округления в арифметике с плавающей точкой (аргумент для acos немного вне диапазона).

Я бы рассмотрел следующие изменения:

  1. Используйте более простую формулу
angle = acos(dot(A,B) / (|A|* |B|))

Если аргумент arccos немного выше 1.0 или ниже -1.0, просто округлите его. Вам не нужно делать это, если аргумент находится в диапазоне.

Нормализация помогает, только если векторы близки к [0,0,0] или имеют очень большие записи - расчет более численно стабилен. Если это не так в вашем приложении, рассмотрите возможность удаления нормализации.

...