Quando você está lidando com problemas de indexação espacial, recomendo começar com um hash espacial ou o meu favorito: a grade antiga simples.
... e entenda suas fraquezas antes de passar para estruturas em árvore que permitem representações esparsas.
Uma das fraquezas óbvias é que você pode desperdiçar memória em muitas células vazias (embora uma grade implementada decentemente não exija mais de 32 bits por célula, a menos que você tenha bilhões de nós para inserir). Outra é que, se você possui elementos de tamanho moderado, maiores que o tamanho de uma célula e geralmente abrangem, digamos, dezenas de células, pode gastar muita memória inserindo esses elementos de tamanho médio em muito mais células do que o ideal. Da mesma forma, quando você faz consultas espaciais, pode ser necessário verificar mais células, às vezes muito mais, do que o ideal.
Mas a única coisa que precisa de uma grade para torná-la a mais otimizada possível contra uma determinada entrada é cell size
, o que não deixa muito para você pensar e mexer, e é por isso que é a minha estrutura de dados preferida para problemas de indexação espacial até encontrar razões para não usá-lo. É muito simples de implementar e não exige que você mexa em nada além de uma única entrada de tempo de execução.
Você pode tirar muito proveito de uma grade antiga simples e, na verdade, derrotei muitas implementações de árvore quádrupla e kd usadas em software comercial, substituindo-as por uma grade antiga simples (embora elas não fossem necessariamente as melhores implementadas , mas os autores gastaram muito mais tempo do que os 20 minutos que gastei para criar uma grade). Aqui está uma coisinha rápida que preparei para responder a uma pergunta em outro lugar usando uma grade para detecção de colisão (nem mesmo realmente otimizada, apenas algumas horas de trabalho, e eu tive que gastar a maior parte do tempo aprendendo como o pathfinding funciona para responder à pergunta e também foi a primeira vez que implementei esse tipo de detecção de colisão):
Outra fraqueza das grades (mas são fraquezas gerais para muitas estruturas de indexação espacial) é que, se você inserir muitos elementos coincidentes ou sobrepostos, como muitos pontos com a mesma posição, eles serão inseridos na mesma célula (s) ) e degradam o desempenho ao atravessar essa célula. Da mesma forma, se você inserir muitos elementos maciços muito, muito maiores que o tamanho da célula, eles desejarão ser inseridos em um bando de células e usarão muita memória e degradarão o tempo necessário para consultas espaciais em todo o quadro .
No entanto, esses dois problemas imediatos acima, com elementos coincidentes e maciços, são realmente problemáticos para todas as estruturas de indexação espacial. Na verdade, a grade antiga lida com esses casos patológicos um pouco melhor do que muitos outros, pois pelo menos não deseja subdividir recursivamente as células repetidamente.
Quando você começa com a grade e trabalha em direção a algo como uma árvore quádrupla ou KD, o principal problema que você deseja resolver é o problema com os elementos sendo inseridos em muitas células, com muitas células e / ou ter que verificar muitas células com esse tipo de representação densa.
Mas se você pensar em um quad-tree como uma otimização em uma gradepara casos de uso específicos, é útil ainda pensar na idéia de um "tamanho mínimo de célula" para limitar a profundidade da subdivisão recursiva dos nós das quatro árvores. Quando você faz isso, o pior cenário da quad-árvore ainda se degradará na grade densa nas folhas, apenas menos eficiente que a grade, pois exigirá tempo logarítmico para percorrer o caminho da raiz à célula da grade em vez de tempo constante. No entanto, pensar nesse tamanho mínimo de célula evitará o cenário de loop / recursão infinito. Para elementos maciços, também existem algumas variantes alternativas, como quad-trees soltas que não necessariamente se dividem igualmente e poderiam ter AABBs para nós filhos que se sobrepõem. BVHs também são interessantes como estruturas de indexação espacial que não subdividem uniformemente seus nós. Para elementos coincidentes contra estruturas de árvores, o principal é simplesmente impor um limite à subdivisão (ou, como outros sugeriram, apenas rejeitá-las ou encontrar uma maneira de tratá-las como se não estivessem contribuindo para o número único de elementos em uma folha ao determinar quando a folha deve subdividir). Uma árvore Kd também pode ser útil se você antecipar entradas com muitos elementos coincidentes, pois é necessário considerar apenas uma dimensão ao determinar se um nó deve dividir a mediana.