Спочатку знайдіть різницю між початковою і кінцевою точкою (тут це скоріше відрізок направленої лінії, а не "лінія", оскільки лінії проходять нескінченно і не починаються в конкретній точці).
deltaY = P2_y - P1_y
deltaX = P2_x - P1_x
Потім обчисліть кут (який іде від позитивної осі X на P1
позитивну вісь Y у P1
).
angleInDegrees = arctan(deltaY / deltaX) * 180 / PI
Але це arctan
може бути не ідеально, тому що поділяючи відмінності таким чином, вилучите відмінність, необхідну для розрізнення того, в якому квадранті кут знаходиться (див. Нижче). Використовуйте наступне, якщо ваша мова містить atan2
функцію:
angleInDegrees = atan2(deltaY, deltaX) * 180 / PI
EDIT (22 лютого 2017 р.): Однак, загалом, закликати atan2(deltaY,deltaX)
просто отримати відповідний кут cos
і sin
може бути неелегантним. У цих випадках ви можете часто робити наступні дії:
- Трактуйте
(deltaX, deltaY)
як вектор.
- Нормалізуйте цей вектор на одиничний вектор. Для цього поділіть
deltaX
і deltaY
на довжину вектора ( sqrt(deltaX*deltaX+deltaY*deltaY)
), якщо довжина не дорівнює 0.
- Після цього
deltaX
тепер буде косинус кута між вектором та горизонтальною віссю (у напрямку від позитивного X до позитивної осі Y at P1
).
- І
deltaY
тепер буде синусом цього кута.
- Якщо довжина вектора дорівнює 0, то він не матиме кута між нею та горизонтальною віссю (тому у нього не буде значущого синуса та косинуса).
EDIT (28 лютого 2017 р.): Навіть без нормалізації (deltaX, deltaY)
:
- Знак
deltaX
сигналу підкаже, чи є косинус, описаний у кроці 3, позитивним чи негативним.
- Знак
deltaY
сигналу підкаже, чи є синус, описаний у кроці 4, позитивним чи негативним.
- Знаки
deltaX
та deltaY
підкажуть, у якому квадранті знаходиться кут, щодо позитивної осі X у P1
:
+deltaX
, +deltaY
: Від 0 до 90 градусів.
-deltaX
, +deltaY
: Від 90 до 180 градусів.
-deltaX
, -deltaY
: Від 180 до 270 градусів (-180 до -90 градусів).
+deltaX
, -deltaY
: Від 270 до 360 градусів (-90 до 0 градусів).
Впровадження в Python з використанням радіанів (надано 19 липня 2015 року Еріком Лещинським, який редагував мою відповідь):
from math import *
def angle_trunc(a):
while a < 0.0:
a += pi * 2
return a
def getAngleBetweenPoints(x_orig, y_orig, x_landmark, y_landmark):
deltaY = y_landmark - y_orig
deltaX = x_landmark - x_orig
return angle_trunc(atan2(deltaY, deltaX))
angle = getAngleBetweenPoints(5, 2, 1,4)
assert angle >= 0, "angle must be >= 0"
angle = getAngleBetweenPoints(1, 1, 2, 1)
assert angle == 0, "expecting angle to be 0"
angle = getAngleBetweenPoints(2, 1, 1, 1)
assert abs(pi - angle) <= 0.01, "expecting angle to be pi, it is: " + str(angle)
angle = getAngleBetweenPoints(2, 1, 2, 3)
assert abs(angle - pi/2) <= 0.01, "expecting angle to be pi/2, it is: " + str(angle)
angle = getAngleBetweenPoints(2, 1, 2, 0)
assert abs(angle - (pi+pi/2)) <= 0.01, "expecting angle to be pi+pi/2, it is: " + str(angle)
angle = getAngleBetweenPoints(1, 1, 2, 2)
assert abs(angle - (pi/4)) <= 0.01, "expecting angle to be pi/4, it is: " + str(angle)
angle = getAngleBetweenPoints(-1, -1, -2, -2)
assert abs(angle - (pi+pi/4)) <= 0.01, "expecting angle to be pi+pi/4, it is: " + str(angle)
angle = getAngleBetweenPoints(-1, -1, -1, 2)
assert abs(angle - (pi/2)) <= 0.01, "expecting angle to be pi/2, it is: " + str(angle)
Всі тести проходять. Дивіться https://en.wikipedia.org/wiki/Unit_circle