Pracuję nad sztuczną inteligencją ruchu, w której nie ma przeszkód, a ruch jest ograniczony do płaszczyzny XY. Obliczam dwa wektory, v , kierunek skierowania statku 1 oraz w , wektor wskazujący od pozycji statku 1 do statku 2.
Następnie obliczam kąt między tymi dwoma wektorami za pomocą wzoru
arccos((v · w) / (|v| · |w|))
Problem, który mam, polega na tym, że arccos
zwraca tylko wartości od 0 ° do 180 °. To uniemożliwia ustalenie, czy powinienem skręcić w lewo, czy w prawo, aby stawić czoła drugiemu statkowi.
Czy jest na to lepszy sposób?
Mathf.DeltaAngle()
.Odpowiedzi:
O wiele szybsze jest stosowanie produktów krzyżowych 2d. Nie wymaga kosztownej funkcji wyzwalania.
Jeśli nadal potrzebujesz rzeczywistych kątów, polecam użyć
atan2
.atan2
da ci kąt bezwzględny dowolnego wektora. Aby uzyskać względny kąt między dowolnym wektorem, oblicz ich kąty bezwzględne i użyj prostego odejmowania.źródło
arccos
. W ten sposób użyjesz tylko jednej funkcji wyzwalania, ale nadal będziesz mieć aktualny kąt. Jednak odradzam tę optymalizację, dopóki nie upewnisz się, że śledzenie kąta AI ma zauważalny wpływ na wydajność twojej gry.if( cross == -0.0f )
vsif( cross == 0.0f )
wygląda wyjątkowo krucho.Użyj arcsin produktu krzyżowego 2D (tj. Komponentu z wektora produktu krzyżowego). To da ci od -90 do 90, co pozwoli ci wiedzieć, czy iść w lewo, czy w prawo.
Bądź ostrożny, ponieważ krzyż A nie jest tym samym krzyżem B
Inną strategią (ale prawdopodobnie nie tak prostą) jest obliczenie „nagłówka” dwóch wektorów za pomocą atan2, a następnie ustalenie, czy A wskazujący na X stopni musi iść w lewo, czy w prawo, aby przejść do B wskazującego na y stopni.
źródło
Użyj wektorów, aby przekierować statek. Tak działają „zachowania kierownicze” - nigdy nie trzeba obliczać kąta, wystarczy użyć wektorów. Jest to obliczeniowo znacznie tańsze.
Wektor
w
(wektor ze statku 1 na statek 2) to wszystkie potrzebne informacje. Zmodyfikuj wektor prędkości statku 1 lub wektor przyspieszenia statku 1 (lub nawet wektor kursu bezpośrednio), używając wersji ważonejw
.Wielkość , jak daleko statku 1 jest poza oczywiście (jak źle v nie zgadza się z wag) można znaleźć za pomocą (
1 - dot(v,w)
)dot(v,w)
jest zmaksymalizowane, kiedy dokładniev
iw
ustawia się w kolejce)1 - dot(v,w)
) Daje przy 0v
iw
całkowicie wyrównana, pod warunkiem,v
iw
normalizuje)źródło
Istnieje prosty sposób na znalezienie bezwzględnego kąta wektora poprzez normalną geometrię.
na przykład wektor V = 2i - 3j;
wartość bezwzględna współczynnika x = 2;
wartość bezwzględna współczynnika y = 3;
kąt = atan (2/3); [kąt będzie między 0 a 90]
W oparciu o kąt kwadrantu zostanie zmieniony.
jeżeli (x współczynnik <0 i y współczynnik> 0) to kąt = kąt 180;
jeżeli (x współczynnik <0 i y współczynnik <0) to kąt = 180 + kąt;
jeżeli (x współczynnik> 0 i y współczynnik <0) to kąt = kąt 360;
jeśli (x współczynnik> 0 i y współczynnik> 0) to kąt = kąt;
po znalezieniu kąta pierwszego i drugiego wektora po prostu odejmij pierwszy kąt wektorowy od drugiego wektora. Wtedy uzyskasz kąt bezwzględny między dwoma wektorami.
źródło
Może powinienem napisać nieco inne pytanie i sam na nie odpowiedzieć; to najbliższe pytanie, jakie mogłem znaleźć, do tego, które miałem.
Robię prace 2D na kanwie HTML, gdzie mam kąty obrotu w radianach, a nie w wektorach. Potrzebowałem „kąta skrętu” (ta), aby przejść z „aktualnego kursu” (h) do „docelowego kursu” (t).
Oto moje rozwiązanie:
źródło