Pertama-tama temukan perbedaan antara titik awal dan titik akhir (di sini, ini lebih merupakan segmen garis terarah, bukan "garis", karena garis memanjang tanpa batas dan tidak memulai pada titik tertentu).
deltaY = P2_y - P1_y
deltaX = P2_x - P1_x
Kemudian hitung sudutnya (yang berjalan dari sumbu X positif di P1
ke sumbu Y positif di P1
).
angleInDegrees = arctan(deltaY / deltaX) * 180 / PI
Tetapi arctan
mungkin tidak ideal, karena membagi perbedaan dengan cara ini akan menghapus perbedaan yang diperlukan untuk membedakan kuadran mana sudut berada (lihat di bawah). Gunakan yang berikut sebagai gantinya jika bahasa Anda menyertakan suatu atan2
fungsi:
angleInDegrees = atan2(deltaY, deltaX) * 180 / PI
EDIT (22 Februari 2017): Namun, secara umum, panggilan atan2(deltaY,deltaX)
hanya untuk mendapatkan sudut yang tepat cos
dan sin
mungkin tidak tepat. Dalam kasus tersebut, Anda dapat sering melakukan hal berikut sebagai gantinya:
- Perlakukan
(deltaX, deltaY)
sebagai vektor.
- Normalisasi vektor itu menjadi vektor satuan. Untuk melakukannya, bagi
deltaX
dan deltaY
dengan panjang vektor ( sqrt(deltaX*deltaX+deltaY*deltaY)
), kecuali panjangnya adalah 0.
- Setelah itu,
deltaX
sekarang akan menjadi cosinus sudut antara vektor dan sumbu horizontal (dalam arah dari X positif ke sumbu Y positif di P1
).
- Dan
deltaY
sekarang akan menjadi sinus sudut itu.
- Jika panjang vektor adalah 0, ia tidak akan memiliki sudut antara itu dan sumbu horizontal (sehingga tidak akan memiliki sinus dan kosinus yang berarti).
EDIT (28 Februari 2017): Bahkan tanpa menormalkan (deltaX, deltaY)
:
- Tanda
deltaX
akan memberi tahu Anda apakah kosinus yang dijelaskan pada langkah 3 positif atau negatif.
- Tanda
deltaY
akan memberi tahu Anda apakah sinus yang dijelaskan pada langkah 4 positif atau negatif.
- Tanda-tanda
deltaX
dan deltaY
akan memberi tahu Anda kuadran mana sudut berada, dalam kaitannya dengan sumbu X positif di P1
:
+deltaX
, +deltaY
: 0 hingga 90 derajat.
-deltaX
, +deltaY
: 90 hingga 180 derajat.
-deltaX
, -deltaY
: 180 hingga 270 derajat (-180 hingga -90 derajat).
+deltaX
, -deltaY
: 270 hingga 360 derajat (-90 hingga 0 derajat).
Implementasi di Python menggunakan radian (disediakan pada 19 Juli 2015 oleh Eric Leschinski, yang mengedit jawaban saya):
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)
Semua tes lulus. Lihat https://en.wikipedia.org/wiki/Unit_circle