Đầu tiên 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 đoạn đường dẫn chứ không phải là "dòng", vì các dòng mở rộng vô hạ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 toán góc (mà chạy từ trục X tích cực tại P1
với trục Y tích cực tại P1
).
angleInDegrees = arctan(deltaY/deltaX) * 180/PI
Nhưng arctan
có thể không lý tưởng, bởi vì cách chia khác biệt theo cách này sẽ xóa sự phân biệt cần thiết để phân biệt mà Quadrant góc là trong (xem dưới đây). Sử dụng sau đây thay vì 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 (22 Tháng Hai 2017): Nói chung, tuy nhiên, gọi atan2(deltaY,deltaX)
chỉ để có được một góc thích hợp cho cos
và sin
có thể thanh nha. Trong những trường hợp đó, bạn có thể thực hiện những việc sau thay thế:
- Điều trị
(deltaX, deltaY)
làm vector.
- Bình thường hóa vectơ đó thành vectơ đơn vị. Để làm như vậy, hãy chia
deltaX
và deltaY
theo chiều dài của vectơ (sqrt(deltaX*deltaX+deltaY*deltaY)
), trừ khi độ dài là 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ừ tích cực X đến trục Y dương tại P1
).
- Và
deltaY
giờ sẽ là sin của góc đó.
- Nếu chiều dài của vectơ là 0, nó sẽ không có một góc giữa nó và trục hoành (vì vậy nó sẽ không có sin và cosin có ý nghĩa).
EDIT (28 tháng 2 năm 2017): Mặc dù không bình thường (deltaX, deltaY)
:
- Các dấu hiệu của
deltaX
sẽ cho bạn biết cosin mô tả trong bước 3 là tích cực hay tiêu cực.
- Dấu hiệu của
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 Quadrant góc trong, liên quan đến trục X tích cực 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 độ).
An thực hiện bằng Python sử dụng radian (được cung cấp trên 19 tháng 7 năm 2015 bởi Eric Leschinski, người 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 qua. Xem https://en.wikipedia.org/wiki/Unit_circle
Nếu bạn thấy điều này và bạn đang sử dụng JavaScript nó là rất quan trọng đối với lưu ý rằng Math.sin và Toán.cos lấy radian để bạn không cần phải chuyển đổi kết quả thành độ! Vì vậy, bỏ qua * 180/PI bit. Tôi mất 4 giờ để tìm ra điều đó. :) – sidonaldson
Điều gì sẽ được sử dụng để tính toán góc dọc theo trục thẳng đứng? – ZeMoon
@akashg: '90 - angleInDegrees'? – jbaums