#python #arrays #numpy #math #vector
#python #массивы #numpy #математика #вектор
Вопрос:
У меня есть функция, которая находит угол между вектором единичной окружности [1,0]
и вектором на единичной окружности.
import numpy as np
def angle(a):
b = [0,1]
if a[1] >= 0:
return round(np.degrees(np.arccos(np.dot(a, b)/ (np.linalg.norm(a) * np.linalg.norm(b)))), 2)
else:
return 180 round(np.degrees(np.arccos(np.dot(a, b)/ (np.linalg.norm(a) * np.linalg.norm(b)))), 2)
print(angle(np.array([1,0])))
90.0
print(angle(np.array([-4,2])))
63.43 # This value should be 150
print(angle(np.array([-1,0])))
90.0 # This value should be 180
print(angle(np.array([0,-1])))
360.0 # This value should be 270
- Как мне установить, что входные
a
данные всегда являются 2D-вектором? - Как мне изменить код, чтобы векторы ниже оси x (т. Е. Отрицательные значения y) отображали правильное значение?
Комментарии:
1. как вы хотите, чтобы были представлены векторы ниже оси x? -5 или 355?
2. Есть
arctan2
функция, которая делает то, что вы хотите сделать сangle
function .3. @anon01, представленный как 355, был бы идеальным
4. утверждение (тип (a) == np.ndarray) amp; утверждение (a.size == 2) может помочь с проверкой входных данных. Выдает ошибку, если эти условия не выполняются.
5. @QuangHoang как мне реализовать эту функцию в коде?
Ответ №1:
У вас неверный вектор x. Это должно быть
b = [1,0]
учитывая, что первая координата — это ось x, а вторая — ось y. Если вы поместите этот правильный вектор b, все вычисления будут работать так, как ожидалось.
Ответ №2:
Один из способов определить функцию, которая ожидает входные данные, — оставить оба в виде отдельных аргументов (это также исправляет некоторые ошибки и упрощает логику получения ваших значений угла):
def angle(x, y):
rad = np.arctan2(y, x)
degrees = np.int(rad*180/np.pi)
if degrees < 0:
degrees = 360 - degrees
return degrees
Кстати, atan2
имеет порядок ввода y, x
, который легко перепутать. Преимущество их указания по отдельности заключается в том, что вы можете помочь избежать этого. Если вы хотите сохранить входные данные в виде массива, что-то вроде этого поможет вам проверить длину:
def angle(a):
if len(a) != 2:
raise IndexError("vector a expected to be length 2")
x = a[0]
y = a[1]
rad = np.arctan2(y, x)
degrees = np.int(rad*180/np.pi)
if degrees < 0:
degrees = 360 - degrees
return degrees
Ответ №3:
Чтобы установить, что a всегда является 2D вектором, вы можете проверить его длину : if len(a) == 2
. вы можете дополнительно проверить, является ли это списком или кортежем с : if type(a) in [list, tuple] and len(a) == 2:
РЕДАКТИРОВАТЬ: мой плохой только что заметил, что в этом случае это на самом деле массивы numpy : if isinstance(x, np.ndarray) and x.shape[0] == 2
РЕДАКТИРОВАТЬ 2 : из комментариев : x.ndim == 2
звучит лучше.
Комментарии:
1. https://numpy.org/doc/stable/reference/generated/numpy.ndarray.ndim.html#numpy.ndarray.ndim