Jaki jest najskuteczniejszy sposób znalezienia punktu przecięcia pocisku i mapy bitowej?

10

W odpowiedzi na moje wcześniejsze pytanie dotyczące znalezienia nachylenia terenu mapy bitowej 2D muszę teraz poznać najlepszy sposób znalezienia punktu na terenie 2D, w który trafił pocisk. Oczywiście widzę, czy jakieś piksele pod pociskiem przecinają teren, ale mówią, że przesunęły się dość głęboko w teren.

Jaki jest najlepszy sposób, aby cofnąć się, aby ustalić, gdzie początkowo się zderzył? Mógłbym przesunąć X pikseli jednocześnie do poprzedniej pozycji pocisku, ale jaka byłaby dobra wartość X? I czy jest mądrzejszy sposób? Może przesunięcie o połowę odległości, a potem o ćwierć itd.?

Iain
źródło
Zjawisko, które opisujesz, jest powszechnie nazywane „tunelowaniem”, a najlepszym sposobem na poradzenie sobie z nim jest wprowadzenie testu wobulacji - jak wspomniano poniżej zarówno TetraD, jak i JasonD.
jpaver
samo powiedzenie „test Sweep” w rzeczywistości mi nie pomaga. Jak to zrobić w terenie z mapą bitową?
Iain
Sugestia Jasona wydaje mi się najlepsza: jeden piksel na raz.
jpaver,

Odpowiedzi:

3

W przypadku testów zderzeniowych nie powinieneś przeprowadzać testów statycznych kleszcza za kleszczem, powinieneś wykonywać testy śledzenia / przeciągnięcia.

Istnieje wyczerpująca lista różnych formuł dla różnych rodzajów prymitywów: http://www.realtimerendering.com/intersections.html

To oczywiście zakładając, że możesz rozbić swój teren na pewien zestaw prymitywów, na których możesz testować (np. Segmenty linii). Można to zrobić na różne sposoby.

Zobacz także to pytanie (tylko nieznacznie powiązane): Jaki jest dobry algorytm do wykrywania kolizji między ruchomymi sferami?

Tetrad
źródło
Myślałem o zniszczalnym terenie z mapami bitowymi, jak w Worms. Czy możesz dynamicznie generować prymitywy z bitmapy, czy byłoby to zbyt szalone?
Iain
1
Jestem pewien, że możesz, ale może być łatwiej / szybciej wykonać testowanie piksel po pikselu dla dowolnej bitmapy.
Tetrad,
Z QUADTREE !! (więc to nie trwa wiecznie)
bobobobo 27.11.11
3

Wyszukiwanie binarne nie pomoże, jeśli masz cienkie fragmenty scenerii i szybko poruszające się pociski - możesz je przegapić.

Myślę, że najlepszą opcją jest przeciągnięcie linii z przodu pocisku wzdłuż ścieżki, którą podąża, piksel za jednym razem. Możesz najpierw sprawdzić granicę całego woluminu, aby uniknąć robienia tego na każdym kroku.

JasonD
źródło
Co to jest wyszukiwanie binarne?
Iain
1
Przepraszamy - wyszukiwanie binarne jest mniej więcej tym, o czym mówiłeś w pytaniu. Zaczynasz w środku i dzielisz przestrzeń wyszukiwania przez dwa, aż zbierzesz się w odpowiedzi. Jest optymalny w wielu przypadkach, ale w twoim przypadku nie zadziała (możesz całkowicie pominąć poprawną odpowiedź).
JasonD
3

Ponieważ pocisk prawdopodobnie nie przesunie ogromnej liczby pikseli na każdą klatkę (nie byłoby gładko na ekranie), nie widzę powodu, aby nie sprawdzać każdego piksela na ścieżce. Algorytm linii Bressenham jest twoim przyjacielem i upewnia się, że masz lokalną kopię bitmapy, ponieważ ogólnie nie chcesz mieć dostępu do pamięci wideo dla każdego piksela. Zakłada się, że teren mapy bitowej jest w pełni losowy (jak na zniszczenia robaków). Jeśli twój świat jest oparty na kafelkach, możesz pominąć każdy kafelek, o którym wiesz, że jest pusty, ale jak wspomniano wcześniej, chyba że masz ogromną liczbę pocisków do sprawdzenia, nie mogłem wymyślić platformy, która potrzebowałaby zbyt wolno aby przetestować piksel po pikselu, a nie będziesz musiał definiować swojego świata w prymitywach (klon robaków sprawiłby, że byłoby to trudne)

Kaj
źródło
tak, myślałem o terenie podobnym do robaków. Czy możesz dynamicznie podzielić je na kafelki, a następnie zaznaczyć puste kafelki, aby nie były zaznaczone? Gdyby było wiele pocisków naraz, może to by trochę przyspieszyło?
Iain
Czy myślisz, że powinienem przesuwać się piksel po pikselu, sprawdzając skrzyżowanie, zamiast cofać się?
Iain
Myślę, że wszystkie trzy odpowiedzi sugerują dalsze wyszukiwanie. Sprawdzanie wstecz nie zadziała, jeśli krok naprzód powoduje pominięcie niektórych scenerii.
JasonD
Tak, zdecydowanie do przodu.
Kaj,
1

Oprócz innych odpowiedzi możesz przyspieszyć tę czynność, jeśli chcesz zrobić małą księgowość dotyczącą „zbierania” wiązki pikseli w bloki o „znanym podobnym stanie”. Np. Możesz zapisać wysokość najwyższego kawałka terenu, więc możesz przyjąć za pewnik, że pocisk nie uderzy niczego, o ile jest powyżej tego. Możesz także zapisać wysokość najniższej przestrzeni „powietrznej”, abyś wiedział, że jeśli pocisk dotrze na tę wysokość, to musi coś uderzyć (chociaż może to być najlepiej wykorzystane jako kontrola zdrowia psychicznego). Idąc dalej, możesz przechowywać prostokąty reprezentujące obszary, które są wszystkim terenem i inne prostokąty, które są powietrzem, ale może to być więcej pracy niż wartości.

Ostatecznie najlepszą metodą będzie prawdopodobnie „przechowywanie wysokości każdej kolumny terenu”, a następnie po prostu obliczanie wysokości pocisku na każdym etapie jego ścieżki. Nie mogę rozmawiać z bardziej nowoczesnymi grami, ale wierzę, że kiedy stworzyłeś „jaskinię” w Spalonej Ziemi, to teren nad tą jaskinią spadł prosto w dół, nie pozostawiając żadnych nawisów. Jeśli chcesz zwisów, praca będzie nieco większa, ale będzie przedłużeniem tego podstawowego pomysłu. (Wskazówka: najpierw uruchom podstawowy pomysł!)

Ponieważ twój teren jest prawdopodobnie całkowicie arbitralny, nie ma skrótów. Nawet jeśli zmusisz teren do utworzenia splajnu lub czegoś takiego, będzie to denerwować, gdy zaczniesz go niszczyć, a testy przecięcia linii z splajnem są iteracyjne i niedoskonałe lub wyczerpujące i bezcelowo powolne dla twojego rodzaju problemu.

dash-tom-bang
źródło