Trước tiên, hãy tìm sự khác biệt giữa điểm bắt đầu và điểm kết thúc (ở đây, đây là phần của một đoạn đường có hướng, không phải là "đường", vì các đường kéo dài vô tận và không bắt đầu tại một điểm cụ thể).
deltaY = P2_y - P1_y
deltaX = P2_x - P1_x
Sau đó tính góc (chạy từ trục X dương P1
sang trục Y dương tại P1
).
angleInDegrees = arctan(deltaY / deltaX) * 180 / PI
Nhưng arctan
có thể không lý tưởng, bởi vì phân chia sự khác biệt theo cách này sẽ xóa đi sự khác biệt cần thiết để phân biệt góc phần tư nằm trong góc nào (xem bên dưới). Sử dụng sau đây nếu ngôn ngữ của bạn bao gồm một atan2
chức năng:
angleInDegrees = atan2(deltaY, deltaX) * 180 / PI
EDIT (ngày 22 tháng 2 năm 2017): Tuy nhiên, nói chung, gọi atan2(deltaY,deltaX)
chỉ để có được góc thích hợp cho cos
và sin
có thể không phù hợp . Trong những trường hợp đó, bạn thường có thể làm như sau:
- Coi
(deltaX, deltaY)
như một vectơ
- Bình thường hóa vectơ đó thành một vectơ đơn vị. Để làm như vậy, chia
deltaX
và deltaY
cho chiều dài của vectơ ( sqrt(deltaX*deltaX+deltaY*deltaY)
), trừ khi độ dài bằng 0.
- Sau đó,
deltaX
bây giờ sẽ là cosin của góc giữa vectơ và trục hoành (theo hướng từ X dương đến trục Y dương tại P1
).
- Và
deltaY
bây giờ sẽ là sin của góc đó.
- Nếu độ dài của vectơ bằng 0, nó sẽ không có góc giữa nó và trục hoành (vì vậy nó sẽ không có sin và cos có ý nghĩa).
EDIT (28 tháng 2 năm 2017): Ngay cả khi không bình thường hóa (deltaX, deltaY)
:
- Dấu hiệu
deltaX
sẽ cho bạn biết liệu cosin được mô tả trong bước 3 là dương hay âm.
- Dấu hiệu
deltaY
sẽ cho bạn biết liệu sin được mô tả trong bước 4 là dương hay âm.
- Các dấu hiệu của
deltaX
và deltaY
sẽ cho bạn biết góc phần tư nằm trong góc nào, liên quan đến trục X dương tại P1
:
+deltaX
, +deltaY
: 0 đến 90 độ.
-deltaX
, +deltaY
: 90 đến 180 độ.
-deltaX
, -deltaY
: 180 đến 270 độ (-180 đến -90 độ).
+deltaX
, -deltaY
: 270 đến 360 độ (-90 đến 0 độ).
Một triển khai trong Python sử dụng radian (được cung cấp vào ngày 19 tháng 7 năm 2015 bởi Eric Leschinski, người đã chỉnh sửa câu trả lời của tôi):
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)
Tất cả các bài kiểm tra vượt qua. Xem https://en.wikipedia.org/wiki/Unit_circle