я рисую угол в питоне
вот код
x = [0,0.5,1]
y = [0,0.5,0]
plt.scatter(x,y)
plt.plot(x,y)
plt.show()
Есть ли способ программно проверить, является ли угол прямым?
Вы можете вычислить угол между двумя векторами следующим образом: сначала получите два вектора v1
и v2
, а затем используйте np.arccos()
, который возвращает угол в радианах. Преобразуйте его в градусы, чтобы проверить, равен ли он 90 градусам. Формулы для вычисления угла между двумя векторами можно найти на этом Вики-ссылка
import numpy as np
x = np.array([0,0.5,1])
y = np.array([0,0.5,0])
vecs = np.vstack((x, y))
v1 = vecs[:, 1] - vecs[:, 0]
v2 = vecs[:, 2] - vecs[:, 1]
angle_rad = np.arccos(np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2)))
angle_deg = np.rad2deg(angle_rad)
# 90.0
Вы можете попытаться вычислить угол, но проще проверить, применима ли теорема Пифагора. Для этого вам нужно рассчитать размер трех ребер, а затем проверить, соответствует ли A^2 + B^2 ~= C^2
Три поверхности?
Три грани. Исправленный.
Да, есть.
x = [0,0.5,1]
y = [0,0.5,0]
points = [np.array(point) for point in zip(x,y)]
a, b, c = points
ba = a - b
bc = c - b
cosine_angle = np.dot(ba, bc) / (np.linalg.norm(ba) * np.linalg.norm(bc))
angle_rad = np.arccos(cosine_angle)
angle_deg = np.rad2deg(angle_rad)
print(angle_deg) # 90.0
Обратите внимание, что np.dot(ba, bc)
равно 0, когда угол b прямой. Вам не нужно вычислять сам угол (или норму векторов).
Самый простой способ — проверить, равен ли скалярное произведение векторов 0.
В вашем случае вы просто вычисляете:
v1 = ( (x[1]-x[0]), (y[1]-y[0]) ) <- (0.5, 0.5)
v2 = ( (x[2]-x[1]), (y[2]-y[1]) ) <- (0.5, -0.5)
dot_product = v1[0]*v2[0] + v1[1]*v2[1] <- 0.5² - 0.5² = 0
Другие ответы на самом деле не заботятся ни о возможных неточностях и ошибках усечения, ни об эффективности.
Вместо точного сравнения с 90 ° (или 0 ° в случае скалярного произведения) разумнее проверить небольшую разницу углов с 90 ° (соответственно 0 °).
Также разумно избегать делений, квадратных корней и тригонометрических функций. Метод перекрестного произведения является одним из самых привлекательных.
Вычислите векторное произведение сторон угла и их квадратов длин и сравните с заранее рассчитанным допуском:
(ABx . BCy - ABy . BCx)² ≥ α.(ABx² + ABy²).(BCx² + BCy²)
с α = cos²δ
, где δ
— угловой допуск.
Спасибо! есть ли руководство по установке значения δ?
@singularli: это зависит от качества ваших данных и вашего приложения.
Это справедливое замечание. Используя число с плавающей запятой, вы не можете гарантировать, что вектор ортогонален. В этом случае, я думаю, мы перейдем к дробной арифметике.
@MichaelDoubez: что вы подразумеваете под дробная арифметика?
Извините, я имею в виду арифметику рациональных чисел: ограничение векторов для выражения в Q и использование модуля дроби.
Я использую плавание в своей оплачиваемой работе, но диапазон значений известен, и мы можем заставить его работать. В случае определения того, являются ли векторы ортогональными, вы можете утверждать, что компьютер не может дать 100% точность, если у вас неточное представление. Даже при сравнении эпсилон, как вы предлагаете, вы можете получить ложные срабатывания.
Да, вы можете найти угол между 3 точками
(0.0,0.0),(0.5,0.5),(1.0,0.0)
. Может быть, посмотрите здесь: math.stackexchange.com/questions/361412/…