Jak użyć iloczynu kropkowego, aby uzyskać kąt między dwoma wektorami?

16

Uczę się korzystać ze znormalizowanych wektorów w moich grach.

Nauczyłem się, że aby poznać kąt między dwoma wektorami, mogę użyć iloczynu. Daje mi to wartość od -1 do 1, gdzie

  • 1 oznacza, że ​​wektory są równoległe i skierowane w tym samym kierunku (kąt wynosi 180 stopni).
  • -1 oznacza, że ​​są one równoległe i skierowane w przeciwnych kierunkach (wciąż 180 stopni).
  • 0 oznacza, że ​​kąt między nimi wynosi 90 stopni.

Chcę wiedzieć, jak przekonwertować iloczyn kropkowy dwóch wektorów na rzeczywisty kąt w stopniach. Na przykład jeśli iloczyn iloczynu dwóch wektorów wynosi 0.28, jaki jest odpowiedni kąt między 0 a 360 stopni?

użytkownik3150201
źródło
1
Należy pamiętać, że zamierzone użycie produktu kropkowego działa tylko wtedy, gdy wektory początkowe są wektorami jednostkowymi.
sam hocevar
@SamHocevar Tak, o to mi chodziło.
user3150201
1
@ user3150201 Odpowiedź Alexa jest poprawna, ale należy również rozważyć, czy w ogóle należy uzyskać rzeczywisty kąt w stopniach. Jedynym przypadkiem, w którym mogę pomyśleć, gdzie jest to naprawdę konieczne, byłoby wyświetlenie czegoś w stopniach w interfejsie użytkownika. W przeciwnym razie prawdopodobnie jest niewiele aplikacji, w których nie można by pracować bezpośrednio z sinusami i cosinusami.
TravisG

Odpowiedzi:

22

dot(A,B) = |A| * |B| * cos(angle)
które można zmienić
angle = arccos(dot(A,B) / (|A|* |B|)).

Dzięki tej formule możesz znaleźć najmniejszy kąt między dwoma wektorami, który będzie wynosił od 0 do 180 stopni. Jeśli potrzebujesz między 0 a 360 stopni, to pytanie może ci pomóc.


Nawiasem mówiąc, kąt między dwoma równoległymi wektorami skierowanymi w tym samym kierunku powinien wynosić 0 stopni, a nie 180.

Alex
źródło
+1 dla „Nawiasem mówiąc, kąt między dwoma równoległymi wektorami skierowanymi w tym samym kierunku powinien wynosić 0 stopni, a nie 180.”
Tara,
8

Rozbuduję trochę komentarz TravisG i dam kolejną odpowiedź, wykorzystując fakt, że twoje pytanie miało znacznik „2D”.

Można uzyskać kąt między dwoma wektorami za pomocą iloczynu kropkowego, ale nie można uzyskać oznaczonego kąta między dwoma wektorami za pomocą tego kropki . Innymi słowy, jeśli chcesz obrócić postać z upływem czasu w kierunku punktu, iloczyn skalarny poda ci liczbę obrotów, ale nie kierunek. Istnieje jednak inna prosta formuła, która jest bardzo przydatna w połączeniu z iloczynem kropkowym. Nie tylko ty masz

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

Możesz też mieć inną formułę (której imię nadrobiłem dla politycznej poprawności):

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

gdzie jeśli A = (a, b), B = (x, y), to pseudoCross (A, B) jest zdefiniowany jako trzeci składnik iloczynu krzyżowego (a, b, 0) x (x, y, 0 ). Innymi słowy:

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

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

Pełny kąt ze angle=atanfull(-b*x+a*y,a*x+b*y)znakiem jest wtedy (funkcje atanfull lub atan2 wybaczają, jeśli przejdziesz w wartości nienormalizowane). Jeśli A i B są znormalizowane, to znaczy, że |A|=|B|=1są to po prostu:

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

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


Aby uzyskać głębsze wyjaśnienie, zwróć uwagę, że powyższe równania można wyrazić równaniem macierzowym:

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

A A i B można wyrazić a=cos(ang1), b=sin(ang1)na pewnej wartości ang1(nie angle). Dlatego macierz po lewej stronie jest macierzą obrotu, która obraca wektor (x, y) o wartość -ang1. Jest to równoważne z przejściem do układu odniesienia, w którym wektor jednostkowy „A” jest traktowany jako wektor / oś (1,0)! Zatem po prostu rysując koło jednostki / prawy trójkąt w tej ramce, możesz zobaczyć, dlaczego wektor wynikowy tego produktu jest (cos (kąt), sin (kąt)).

Jeśli napiszesz (a, b) i (x, y) w formie biegunowej i zastosujesz formułę różnicy kątów, cos(l)*cos(m)+sin(l)*sin(m)=cos(l-m)i sin(l)*cos(m)-cos(l)*sin(m)=sin(l-m)ponownie wyrazisz, że sinus / cosinus są podane przez ten produkt, ponieważ (lm) = kąt. Alternatywnie, te tożsamości można wykorzystać, aby zobaczyć, dlaczego podany wyżej iloczyn liniowy obraca wektor.

Wszystkie te tożsamości oznaczają, że rzadko potrzebujesz kątów. Ponieważ kąty mogą być dziwne - radian / stopnie, konwencje dla odwrotnego sinusa / cosinusa, fakt, że powtarzają się co 2 * pi - może to być w rzeczywistości bardziej przydatne i zaoszczędzić sporo logiki „if (ang <180)” itp.


źródło