Jak obliczyć wektor przechwytywania?


11

Biorąc pod uwagę dwuwymiarową przestrzeń i 1 przyjazny statek kosmiczny, który stoi w miejscu, jeden przeciwnik porusza się NIE bezpośrednio na przyjazny statek o znanej rzeczywistej pozycji, prędkości i kierunku.

Przyjazny statek chce dostać się na zasięg ostrzału, aby walczyć z wrogiem.

Właściwie ustawiam tylko wektor bezpośredni na rzeczywistą pozycję poruszającego się statku i przeliczam go co każdą klatkę, co daje rodzaj „okrągłej” ścieżki lotu.

Chcę ustalić bezpośrednią i prostą ścieżkę do pozycji, którą przeciwnik (prawdopodobnie) będzie miał po osiągnięciu odległości strzelania, zakładając, że do tego czasu nie zmieni kursu.

Jako pierwsza i „prosta” implementacja wystarczyłoby założyć, że przyjaciel może przyspieszyć od 0 do maksimum w krótkim czasie.

Preferowana implementacja to taka, która bierze pod uwagę możliwości przyspieszania przyjaciela i wie, kiedy przechwycenie jest niemożliwe ze względu na prędkość. Powinien działać na każdą prędkość początkową, nie tylko z bezruchu. Plus byłby, gdyby nawet rozważał hamowanie (walka z prędkością światła jest bardzo nieefektywna energetycznie w danym wszechświecie)

Odpowiedzi:


5

Jeśli rozumiem twoje pytanie, nie chcesz, aby statek kierował się na cel, ale raczej lecieć w linii prostej, która przypadkowo przechwytuje cel. Tworzę grę w obronę wieży, która zasadniczo potrzebuje tej samej kuli, wieża chce wystrzelić broń, aby pocisk przechwycił poruszający się cel, o ile nie zmieni prędkości / kierunku. Sposób, w jaki to rozwiązałem, polegał na zastosowaniu równania kwadratowego. Oto pseudo kod:

Vector totarget =  target.position - tower.position;

float a = Vector.Dot(target.velocity, target.velocity) - (bullet.velocity * bullet.velocity);
float b = 2 * Vector.Dot(target.velocity, totarget);
float c = Vector.Dot(totarget, totarget);

float p = -b / (2 * a);
float q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a);

float t1 = p - q;
float t2 = p + q;
float t;

if (t1 > t2 && t2 > 0)
{
    t = t2;
}
else
{
    t = t1;
}

Vector aimSpot = target.position + target.velocity * t;
Vector bulletPath = aimSpot - tower.position;
float timeToImpact = bulletPath.Length() / bullet.speed;//speed must be in units per second

Przekonałem się, że to działa tak dobrze, że nie potrzebowałem wykrywania kolizji dla strzału ... Byłem w stanie liczyć na każdy strzał trafiony w dziesiątkę niezależnie od odległości / kierunku / prędkości celu, o ile te czynniki pozostały stabilne.


Z twojego opisu wydaje się, że tego szukam, przynajmniej prosty sposób zakładający natychmiastowe przyspieszenie do maksymalnej prędkości. Przyjrzę się temu wieczorem. Czy mam rację, że Vector.Dot zwraca produkt kropkowy do wektorów?
— NobbZ

Hmmm ... Zrobiłem to teraz w rubinie, ale wydaje się, że coś jest nie tak. Za każdym razem, gdy próbuję, pojawia się wyjątek, ponieważ wyrażenie w sqrt ocenia się na coś negatywnego i dlatego jest poza zakresem. Jak sobie z tym poradzić. Przepraszam za pytanie, ale mogę tylko tego użyć, ale nie rozumiem tu konceptów, dopóki ktoś nie da mi rady.
— NobbZ

Przykład pochodzi z tej książki: amazon.com/...
— Steve H

1
nie wiem, czy to pomaga, ale oto kod Pythona, który osiąga to samo. moddb.com/mods/wicmw/tutorials/…
— Steve H

OK, nadal nie rozumiem matematyki dziury za nią, ale dzięki kodowi python, dokumentacja powiedziała mi, że jeśli w sqrt jest wartość ujemna, to mój przyjaciel musi powoli nadrobić zaległości. Po poprawieniu wartości testowych otrzymuję wyniki. Dziękuję za pomoc.
— NobbZ

6

Sugeruję przyjrzeć się zachowaniom kierowania. Szczególnie pogoń . Kod źródłowy można znaleźć w implementacji OpenSteer lub poszukać książki takiej jak „ Programowanie sztucznej inteligencji gry przez przykład ” (ISBN 13: 978-1556220784)


pogoń wydaje się potrzebować wiedzy o celu i kieruje się nim, ale tak naprawdę nie znam celu. Wiem, gdzie jest teraz wróg, znam jego prędkość i kierunek. Teraz chcę wiedzieć, w jakim kierunku musi iść, aby przechwycić wroga w drodze do celu tak szybko i szybko, jak to możliwe. Jak wspomniano wcześniej, przyspieszenie można na początku zignorować, zaoszczędziłoby to nawet dużo czasu przetwarzania w porównaniu z rzeczywistą wersją ... W nowym modelu muszę przeliczyć tylko wtedy, gdy wróg strzela „zmianą kursu” - nie zawsze, dla każdego ” przeniósł się ”- tak jak teraz to robię.
— NobbZ,

Tak, to co opisujesz jest pościg. To nie zna cel .. to sprawia, że prognozy opiera się na „wrogów” aktualna pozycja, prędkość i kierunek
— bummzack

Potem źle zrozumiałem opis, przyjrzę mu się jutro.
— NobbZ

Właśnie skończyłem czytać dokument kilka minut temu, pogoń NIE jest tym, czego szukam. To jest jak moja rzeczywista implementacja, z wyjątkiem tego, że celuje w pozycję następnej klatki, wciąż muszę ponownie obliczać nowy kurs dla każdej klatki, a kurs powoduje pewną krzywą. Ale to, czego chcę, to bezpośrednia linia zakładająca, że ​​wróg nie zmieni prędkości ani kursu, dopóki oba się nie spotkają. Jeśli nadal nie jest to wystarczająco jasne, staram się rysować to, co chcę po pracy. Ale i tak dzięki za linki. Myślę, że mogę użyć tego gdzie indziej w projekcie.
— NobbZ

@NobbZ Przykro mi, moja odpowiedź nie była pomocna. Być może powinieneś odpowiednio zmodyfikować swoje pytanie, ponieważ stwierdzenia takie jak: „Wiem, że w przypadku zmiany prędkości lub kursu przeciwnika wszelkie obliczenia muszą zostać powtórzone” mogą być mylące… gdybyś to zrobił, musiałbyś „pogoń” za kierowaniem.
— bummzack
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.