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?
2d
mathematics
vector
geometry
użytkownik3150201
źródło
źródło
Odpowiedzi:
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.
źródło
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|=1
są 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 A i B można wyrazić
a=cos(ang1)
,b=sin(ang1)
na pewnej wartościang1
(nieangle
). 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)
isin(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