Bagaimana cara menggunakan produk titik untuk mendapatkan sudut antara dua vektor?

16

Saya belajar menggunakan vektor yang dinormalisasi dalam game saya.

Saya telah belajar bahwa untuk mengetahui sudut antara dua vektor, saya dapat menggunakan produk titik. Ini memberi saya nilai antara -1 dan 1, di mana

  • 1 berarti vektornya paralel dan menghadap ke arah yang sama (sudutnya 180 derajat).
  • -1 berarti mereka paralel dan menghadap ke arah yang berlawanan (masih 180 derajat).
  • 0 berarti sudut di antara mereka adalah 90 derajat.

Saya ingin tahu cara mengubah produk titik dari dua vektor, ke sudut aktual dalam derajat. Misalnya, jika produk titik dari dua vektor adalah 0.28, apa sudut yang sesuai, antara 0 dan 360 derajat?

pengguna3150201
sumber
1
Perhatikan bahwa tujuan penggunaan produk titik hanya berfungsi jika vektor awal adalah vektor satuan.
sam hocevar
@ SamHocevar Ya, itulah yang saya maksud.
user3150201
1
@ user3150201 Jawaban Alex benar, tetapi Anda juga harus mempertimbangkan apakah Anda perlu mendapatkan sudut yang sebenarnya dalam derajat sama sekali. Satu-satunya kasus di mana saya bisa memikirkan di mana ini benar-benar diperlukan adalah menampilkan sesuatu dalam derajat pada UI. Kalau tidak, mungkin ada beberapa aplikasi di mana Anda tidak dapat bekerja secara langsung dengan sinus dan cosinus.
TravisG

Jawaban:

22

dot(A,B) = |A| * |B| * cos(angle)
yang dapat diatur ulang menjadi
angle = arccos(dot(A,B) / (|A|* |B|)).

Dengan rumus ini, Anda dapat menemukan sudut terkecil antara dua vektor, yaitu antara 0 dan 180 derajat. Jika Anda membutuhkannya antara 0 dan 360 derajat , pertanyaan ini dapat membantu Anda.


Omong-omong, sudut antara dua vektor paralel yang menunjuk pada arah yang sama harus 0 derajat, bukan 180.

Alex
sumber
+1 untuk "Omong-omong, sudut antara dua vektor paralel yang menunjuk ke arah yang sama harus 0 derajat, bukan 180."
Tara
8

Saya akan sedikit memperluas komentar TravisG dan memberikan jawaban lain, memanfaatkan fakta bahwa pertanyaan Anda memiliki tag "2D".

Anda bisa mendapatkan sudut antara dua vektor menggunakan produk titik, tetapi Anda tidak bisa mendapatkan sudut yang ditandatangani antara dua vektor menggunakannya. Dengan kata lain, jika Anda ingin mengubah karakter dari waktu ke waktu menuju titik, produk titik akan memberi Anda berapa banyak untuk berubah tetapi tidak ke arah mana. Namun, ada rumus sederhana lainnya, yang sangat berguna ketika dikombinasikan dengan produk titik. Anda tidak hanya memiliki

dot(A,B) = |A| * |B| * cos(angle)

Anda juga dapat memiliki formula lain (yang namanya saya buat untuk kebenaran politik):

pseudoCross(A,B) = |A| * |B| * sin(angle)

di mana jika A = (a, b), B = (x, y), maka pseudoCross (A, B) didefinisikan sebagai komponen ketiga dari produk silang (a, b, 0) x (x, y, 0 ). Dengan kata lain:

a*x+b*y = |A| * |B| * cos(angle)

-b*x+a*y = |A| * |B| * sin(angle)

Sudut yang ditandatangani penuh kemudian angle=atanfull(-b*x+a*y,a*x+b*y)(fungsi atanfull atau atan2 memaafkan Anda jika Anda memberikan nilai yang tidak dinormalisasi). Jika A dan B dinormalisasi, yaitu, jika |A|=|B|=1, ini hanya:

a*x+b*y = cos(angle)

-b*x+a*y = sin(angle)


Untuk penjelasan yang lebih dalam, perhatikan bahwa persamaan di atas dapat diekspresikan oleh persamaan matriks:

[ a,b]   [x]   [cos(angle)]
[-b,a] * [y] = [sin(angle)]

Tapi a dan b dapat dinyatakan sebagai a=cos(ang1), b=sin(ang1), untuk beberapa nilai ang1(tidakangle ). Oleh karena itu, matriks di sebelah kiri adalah matriks rotasi yang memutar vektor (x, y) dengan jumlah -ang1. Ini sama dengan beralih ke kerangka acuan di mana vektor satuan "A" diperlakukan sebagai vektor / sumbu (1,0)! Jadi hanya dengan menggambar lingkaran satuan / segitiga siku-siku dalam bingkai ini, Anda dapat melihat mengapa vektor yang dihasilkan dari produk tersebut adalah (cos (sudut), sin (sudut)).

Jika Anda menulis (a, b) dan (x, y) dalam bentuk kutub, dan terapkan rumus perbedaan sudut cos(l)*cos(m)+sin(l)*sin(m)=cos(l-m)dansin(l)*cos(m)-cos(l)*sin(m)=sin(l-m) , Anda menyatakan kembali bahwa sinus / cosinus diberikan oleh produk ini, karena (lm) = sudut. Atau, identitas tersebut dapat digunakan untuk melihat mengapa produk linier yang diberikan di atas memutar vektor.

Semua identitas ini berarti Anda jarang membutuhkan sudut. Karena sudut bisa aneh - radian / derajat, konvensi untuk sinus / cosinus terbalik, fakta bahwa mereka mengulangi setiap 2 * pi - ini sebenarnya bisa lebih berguna dan menghemat banyak logika "jika (ang <180)" dll.


sumber