Kiedy masz do czynienia z problemami z indeksowaniem przestrzennym, tak naprawdę polecam zacząć od przestrzennego skrótu lub mojego osobistego ulubionego: zwykłej starej siatki.
... i najpierw zrozum jego słabości, zanim przejdziesz do struktur drzewa, które pozwalają na rzadkie reprezentacje.
Jedną z oczywistych słabości jest to, że możesz marnować pamięć na wiele pustych komórek (chociaż przyzwoicie zaimplementowana siatka nie powinna wymagać więcej niż 32-bitów na komórkę, chyba że faktycznie masz miliardy węzłów do wstawienia). Innym jest to, że jeśli masz elementy średniej wielkości, które są większe niż rozmiar komórki i często obejmują, powiedzmy, dziesiątki komórek, możesz zmarnować dużo pamięci, wstawiając te średniej wielkości elementy do znacznie większej liczby komórek niż idealna. Podobnie, gdy wykonujesz zapytania przestrzenne, być może będziesz musiał sprawdzić więcej komórek, czasem znacznie więcej niż idealne.
Ale jedyną rzeczą, którą należy dopracować za pomocą siatki, aby była jak najbardziej optymalna w stosunku do pewnych danych wejściowych, jest to cell size
, co nie pozostawia zbyt wiele do myślenia i majstrowania, i dlatego jest to moja przejdź do struktury danych dla problemów z indeksowaniem przestrzennym, dopóki nie znajdę powodów, aby go nie używać. Jest łatwa do wdrożenia i nie wymaga majstrowania przy niczym więcej niż jednym wejściu środowiska uruchomieniowego.
Możesz wiele wyciągnąć ze zwykłej starej siatki, a ja pokonałem wiele implementacji quad-tree i kd używanych w oprogramowaniu komercyjnym, zastępując je zwykłą starą siatką (choć niekoniecznie były to najlepiej zaimplementowane , ale autorzy spędzili o wiele więcej czasu niż 20 minut, które spędziłem na zrobieniu siatki). Oto krótka rzecz, którą wymyśliłem, aby odpowiedzieć na pytanie w innym miejscu za pomocą siatki do wykrywania kolizji (nawet nie tak naprawdę zoptymalizowanej, zaledwie kilka godzin pracy i musiałem spędzać większość czasu, ucząc się, jak działa wyszukiwanie ścieżek, aby odpowiedzieć na pytanie i po raz pierwszy wdrożyłem tego rodzaju wykrywanie kolizji):
Inną słabością siatek (ale są to ogólne słabości wielu struktur indeksowania przestrzennego) jest to, że jeśli wstawisz wiele zbieżnych lub nakładających się elementów, takich jak wiele punktów o tej samej pozycji, zostaną one wstawione do dokładnie tej samej komórki (s) ) i obniżyć wydajność podczas przechodzenia przez tę komórkę. Podobnie, jeśli wstawisz wiele masywnych elementów, które są znacznie, znacznie większe niż rozmiar komórki, będą chciały zostać wstawione do zestawu komórek i wykorzystują dużo pamięci, zmniejszając czas potrzebny na zapytania przestrzenne na całej planszy .
Jednak te dwa bezpośrednie problemy powyżej z przypadkowymi i masywnymi elementami są w rzeczywistości problematyczne dla wszystkich przestrzennych struktur indeksujących. Zwykła stara siatka faktycznie radzi sobie z tymi patologicznymi przypadkami nieco lepiej niż wiele innych, ponieważ przynajmniej nie chce rekurencyjnie dzielić komórki w kółko.
Kiedy zaczynasz od siatki i dążysz do czegoś w rodzaju drzewa czworokątnego lub drzewa KD, głównym problemem, który chcesz rozwiązać, jest problem z wstawieniem elementów do zbyt wielu komórek, posiadaniem zbyt wielu komórek i / lub konieczność sprawdzania zbyt wielu komórek za pomocą tego rodzaju gęstej reprezentacji.
Ale jeśli myślisz o quad-drzewie jako optymalizacji nad siatkąw przypadku konkretnych przypadków użycia nadal warto pomyśleć o „minimalnym rozmiarze komórki”, aby ograniczyć głębokość rekurencyjnego podziału węzłów drzewa czworokątnego. Gdy to zrobisz, najgorszy scenariusz drzewa czworokątnego będzie nadal rozkładał się w gęstą siatkę na liściach, tylko mniej wydajną niż siatka, ponieważ zajmie to logarytmiczny czas, aby przejść od korzenia do komórki siatki zamiast czas stały. Jednak myślenie o tym minimalnym rozmiarze komórki pozwoli uniknąć scenariusza nieskończonej pętli / rekurencji. W przypadku elementów masywnych istnieją również alternatywne warianty, takie jak luźne drzewa czworokątne, które niekoniecznie dzielą się równomiernie i mogą nakładać się na siebie bloków AABB dla węzłów potomnych. BVH są również interesujące jako struktury indeksowania przestrzennego, które nie dzielą równomiernie swoich węzłów. W przypadku elementów zbieżnych przeciwko strukturom drzewnym najważniejsze jest po prostu nałożenie ograniczenia na podział (lub, jak sugerowali inni, po prostu je odrzucić lub znaleźć sposób, aby traktować je tak, jakby nie przyczyniały się do unikalnej liczby elementów w liściu podczas określania, kiedy liść powinien się podzielić). Drzewo Kd może być również przydatne, jeśli spodziewasz się danych wejściowych z wieloma zbieżnymi elementami, ponieważ musisz wziąć pod uwagę tylko jeden wymiar przy określaniu, czy węzeł powinien podzielić medianę.