Obecnie piszę symulację AI 2D, ale nie jestem całkowicie pewien, jak sprawdzić, czy pozycja agenta znajduje się w polu widzenia innego.
Obecnie moje partycjonowanie świata to proste partycjonowanie komórki-przestrzeni (siatka). Chcę użyć trójkąta do przedstawienia pola widzenia, ale jak mogę obliczyć komórki, które przecinają się z trójkątem?
Podobne do tego obrazu:
Czerwone obszary to komórki, które chcę obliczyć, sprawdzając, czy trójkąt przecina te komórki.
Z góry dziękuję.
EDYTOWAĆ:
Żeby dodać zamieszanie (a może nawet ułatwić). Każda komórka ma wektor minimalny i maksymalny, gdzie min to lewy dolny róg, a maksimum to prawy górny róg.
collision-detection
intersection
Ray Dey
źródło
źródło
Odpowiedzi:
Oblicz trzy rogi trójkąta Fov, obróć je, aby były skierowane we właściwą stronę i tak dalej, a następnie wykonaj jedną z następujących czynności:
1) wykonaj test punkt w trójkącie dla wszystkich potencjalnych celów
2) obliczyć ramkę graniczną tego trójkąta i wykonać test punkt-trójkąt dla wszystkich potencjalnych celów w komórkach w tej ramce granicznej - będzie to bardzo prosty kod do debugowania
Podobne podejście polega na użyciu kwadratu zamiast siatki i wykonaniu na nim skrzyżowań. Jeśli dostęp do kafelków O (1) przyspiesza cię, to po prostu testowanie wszystkich komórek w granicach trójkąta fov dla wewnątrz trójkąta powinno być tak szybkie, aby było natychmiastowe. Gdy patrzysz na inne opcje, zakładam, że nie, i że O (1) faktycznie bierze ogromny koszt braku pamięci podręcznej, gdy rzucasz swoją pamięć podręczną. Możesz oczywiście spojrzeć na instrukcje pobierania wstępnego, aby opisać swój spacer po obwiedni ...
3) „zrasteryzuj” ten trójkąt i sprawdź komórki, które „maluje” - prawdopodobnie najbardziej wydajny kod, ale być może tylko nieznacznie, ponieważ spekuluję, że wszystkie są zdominowane przez czasy braków w pamięci podręcznej i zależą od tego, jak złożone są twoje komórki i jak zajmowane są komórki oni są.
Alternatywnym podejściem jest renderowanie pola widzenia na bitmapę poza ekranem, a następnie odczytanie wartości pikseli dla każdego z obiektów; nie można „odmiksować farby”, ale przy ograniczonej liczbie obiektów i ostrożnie wybierając farbę można wywnioskować, kto widział kto. Podejście to jest podobne do tego, ile gier sprawdza to, co kliknął użytkownik - rysują scenę poza ekranem, używając jednolitych kolorów dla obszarów trafień. Procesory graficzne są bardzo szybkie przy wypełnianiu trójkątów ...
źródło
Kanonicznym rozwiązaniem w programach do renderowania oprogramowania (które muszą wykonywać ten dokładny algorytm za każdym razem, gdy rasteryzują trójkąt) jest, moim zdaniem, skanowanie tego trójkąta po jednym rzędzie pikseli. Lewą i prawą krawędź każdego rzędu obliczono, przechodząc bokami trójkąta za pomocą Bresenhama , a następnie wypełniając rząd między nimi.
Przeglądam wiele szczegółów, ale to podstawowy pomysł. Jeśli polujesz na „renderowanie oprogramowania” i „rasteryzację trójkątów”, prawdopodobnie znajdziesz więcej szczegółów. To dobrze rozwiązany problem. Twoja karta graficzna robi to miliony razy w ramce.
Jeśli chcesz bardziej roguelike rozwiązania, oto jak zaimplementowałem FOV w moim. Wygląda na to, że działa dość szybko. Zasadniczo jest to prosty rzucacz cieni, pracujący na oktanie jednocześnie, skanujący na zewnątrz odtwarzacza.
źródło
Używam odmiany algorytmu skanowania linii, aby rozwiązać dokładnie ten sam problem. Zacząłem od posortowania trzech punktów trójkąta według ich wysokości. Następnie w zasadzie sprawdzam, czy dwie krawędzie są po lewej, czy po prawej stronie. Po stronie z dwiema krawędziami musisz zaznaczyć rząd, w którym zmienisz, która krawędź ogranicza twoje rzędy. Po stronie z jedną krawędzią zawsze możesz tego użyć.
Zatem dla każdego wiersza wiem, które dwie krawędzie go ograniczają, i mogę obliczyć górną i dolną granicę w kierunku x. Brzmi dość skomplikowanie, ale ogranicza się do zaledwie kilku wierszy kodu. Upewnij się, że zajmujesz się specjalnym futerałem, w którym jedna krawędź jest całkowicie pozioma!
źródło
Co powiesz na utrzymanie zakresu kolumn dla każdego wiersza w trójkącie? Możesz ustawić minimalną i maksymalną kolumnę dla każdego wiersza, w którym znajduje się każdy punkt i gdzie każda linia trójkąta przecina poziomą linię oddzielającą wiersze.
Wynik:
źródło
W społeczności roguelike wykonano prace nad algorytmem, które zajmują się światłami FOV / LOS / oświetleniem w świecie opartym na kafelkach.
Być może na tej stronie znajdziesz coś, co pomoże rozwiązać Twój problem: http://roguebasin.roguelikedevelopment.org/index.php?title=Field_of_Vision
W szczególności „Permovive FOV” może być najbardziej odpowiedni w twojej sytuacji.
źródło