Árvore KD totalmente dinâmica vs. Quadtree?

11

No meu jogo, estou no ponto em que preciso rastrear todas as unidades do mundo para poder fazer verificações de vizinhos mais próximos em combate. Este é um jogo semelhante ao RTS, com potencialmente milhares de pequenas unidades automatizadas em movimento.

Eu estive olhando para KD-Trees e Quadtrees (especialmente Point Quadtrees). Ainda estou tentando aprender os detalhes de como eles funcionam, mas até agora os Point Quadtrees estão fazendo mais sentido para mim. No entanto, estou tendo a impressão de que as árvores KD são mais rápidas de pesquisar, o que é importante com o número de pontos que terei na árvore.

Por outro lado, no meu caso, vou rastrear um grande número de unidades que estão sempre em movimento. De quadro a quadro, suas posições sempre serão diferentes. Aparentemente, os quadtrees são mais rápidos em reequilibrar que as KD-Trees, mas não sei se isso é aplicável quando você está reequilibrando todos os pontos da árvore.

Gostaria de saber se seria melhor, neste caso, apenas desfazer a árvore em cada quadro e reconstruí-lo do zero, em vez de tentar reequilibrar todos os pontos da árvore? Se um Quadtree é mais rápido para reequilibrar, isso também significa que é mais rápido construir do zero? Nesse caso, isso pode ser mais importante para o desempenho do que a velocidade de pesquisa do KD-Tree, dependendo de quanto custa criar a árvore, mas eu não sei ...

Nairou
fonte

Respostas:

12

As árvores KD definitivamente não são dinâmicas o suficiente para serem consideradas, honestamente. Mover algumas unidades pode facilmente exigir que você reconstrua toda a KD-Tree. Além disso, uma árvore KD é muito eficiente para consultas, mas não tanto para pesquisas de vizinhos.

Um quadtree é mais flexível ao longo do tempo, pois as modificações são mantidas mais localmente. A desvantagem é que, se você tiver muitas unidades em um local que se movem com frequência, isso pode se subdividir demais e exigir muitas atualizações devido ao movimento das unidades. Você pode definir um limite no qual nenhuma subdivisão pode ocorrer. Mas cuidado, isso implica que muitas unidades podem estar no mesmo quadrado da folha.

Se, no entanto, você estiver interessado apenas em encontrar todas as unidades em um raio constante r , não precisará do quadtree e do kd-tree imediatamente. Você pode simplesmente criar uma matriz 2D de células do lado do comprimento r e empilhar suas unidades em cada célula de acordo com sua posição. Dessa forma, você sempre tem no máximo 9 células para pesquisar. Somente se o seu mapa for enorme , essa grade seria muito grande para implementar.

Há duas estruturas completamente diferentes das quais não falamos: AABBs hierárquicos e tabela de hash sensível ao local. Se a origem de cada AABB hierárquico for descrita em relação ao AABB pai, há uma vantagem de que, se um grande grupo de unidades mantiver sua formação, não será necessário atualizar os AABBs menores, pois eles mantêm as mesmas posições relativas. Obviamente, girar a formação pode causar muitas atualizações; nesse caso, o uso de outros volumes delimitadores, como esferas ou caixas delimitadoras orientadas (OBB), pode ser mais eficiente.

As tabelas de hash sensíveis ao local fornecem apenas soluções aproximadas com eficiência, para que eu não me incomode com elas.

O que eu faria ? Provavelmente começaria com uma grade simples e, quando necessário, atualizá-la para um quadtree e, se precisar, combinarei com uma hierarquia de volume delimitadora sob algum limite: os quadtrees funcionam bem em geral escala, volumes delimitadores relativos funcionam bem em pequena escala. Fazendo isso gradualmente, não preciso gastar uma hora desde o início para obter a melhor estrutura de dados imediatamente .

Lærne
fonte
Obrigado! Eu não tinha ouvido falar de AABBs hierárquicos e tabelas de hash sensíveis ao local; vou procurá-los no futuro. Por enquanto, vou com uma grade simples e expandirei se necessário, como você mencionou. :)
Nairou
4

As sugestões de Lærne são ótimas, mas eu também sugeriria uma árvore de volume delimitador dinâmico de AABBs. Conceitualmente, a árvore de volume delimitador dinâmico mantém uma árvore de nós equilibrada que pode ser consultada a qualquer momento para elementos próximos, passando em um AABB e recuperando um par sobreposto. A árvore não é reconstruída a cada quadro. Em vez disso, o AABB de cada nó é levemente inflado quando colocado na árvore, e a árvore é reconstruída apenas quando o AABB real do nó não está mais contido no AABB inflado. Eu o uso no meu mecanismo de física e funciona muito bem.

O código fonte do Box2D possui uma ótima implementação.

https://github.com/erincatto/Box2D/blob/master/Box2D/Box2D/Collision/b2DynamicTree.h

Aqui está uma boa revisão de sua implementação:

http://www.randygaul.net/2013/08/06/dynamic-aabb-tree/

Steven
fonte
Sim, isso é mais ou menos o que eu quis dizer com AABB hierárquico, não fui muito preciso. Ah, e na unidade RTSes geralmente são móveis, mas em formações. Portanto, o uso de coordenadas em relação ao nó AABB pai pode ser bastante eficiente, com a margem de erro "inflação".
03
Você pode atualizar o link do código do Google?
Kolenda