ก่อนอื่นให้ค้นหาความแตกต่างระหว่างจุดเริ่มต้นและจุดสิ้นสุด (ที่นี่คือส่วนของเส้นตรงที่กำกับไม่ใช่ "เส้น" เนื่องจากเส้นขยายออกไปเรื่อย ๆ และไม่เริ่มที่จุดใดจุดหนึ่ง)
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
แก้ไข (22 กุมภาพันธ์ 2017): อย่างไรก็ตามโดยทั่วไปการโทรatan2(deltaY,deltaX)
เพียงเพื่อให้ได้มุมที่เหมาะสมcos
และsin
อาจไม่เหมาะสม ในกรณีดังกล่าวคุณสามารถทำสิ่งต่อไปนี้แทน:
- ถือว่า
(deltaX, deltaY)
เป็นเวกเตอร์
- ทำให้เวกเตอร์นั้นเป็นเวกเตอร์มาตรฐาน หากต้องการทำเช่นนั้นให้หาร
deltaX
และหารdeltaY
ด้วยความยาวของเวกเตอร์ ( sqrt(deltaX*deltaX+deltaY*deltaY)
) ยกเว้นความยาวเท่ากับ 0
- หลังจากนั้น
deltaX
จะเป็นโคไซน์ของมุมระหว่างเวกเตอร์และแกนนอน (ในทิศทางจากบวก X ถึงแกน Y บวกที่P1
)
- และ
deltaY
ตอนนี้จะเป็นไซน์ของมุมนั้น
- หากความยาวของเวกเตอร์เท่ากับ 0 มันจะไม่มีมุมระหว่างมันกับแกนนอน (ดังนั้นมันจะไม่มีไซน์และโคไซน์ที่มีความหมาย)
แก้ไข (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 กรกฎาคม 2558 โดย Eric Leschinski ผู้แก้ไขคำตอบของฉัน):
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