完全に動的なKD-Tree対Quadtree?


11

私のゲームで作業しているときに、私は世界のすべてのユニットを追跡して、最近傍の戦闘をチェックできるようにする必要があります。これはRTSのようなゲームで、数千もの小さな自動化ユニットが動き回る可能性があります。

私はKD-TreesとQuadtrees(特にPoint Quadtrees)を調べてきました。私はまだそれらがどのように機能するかの詳細を学習しようとしていますが、これまでのところポイントクワッドツリーは私にとって最も理にかなっています。ただし、KD-Treeの方が検索が高速であるという印象を得ています。これは、ツリー内に持つポイントの数にとって重要です。

一方、私の場合は、常に動いている多数のユニットを追跡します。フレームごとに、それらの位置は常に異なります。四分木はKD-Treeよりも明らかに高速にリバランスしますが、ツリー内のすべてのポイントをリバランスするときにそれが当てはまるかどうかはわかりません。

この場合、ツリーのすべてのポイントのバランスを再調整するのではなく、各フレームのツリーをスクラップして最初から再構築する方がよいのではないかと思います。クワッドツリーの再バランスが速い場合、ゼロから構築する方が速いということですか?もしそうなら、それは、KD-Treeの検索速度よりもパフォーマンスにとってより重要かもしれません。ツリーを作成することの負担の大きさにもよりますが、私にはわかりません...

回答:


12

KDツリーは、正直なところ、検討するのに十分なほど動的ではありません。少数のユニットを移動すると、簡単にKD-Tree全体を再構築する必要があります。さらに、KDツリーはクエリには非常に効率的ですが、近隣探索にはそれほど効果的ではありません。

変更がよりローカルに保持されるため、四分木は時間の経過とともにより柔軟になります。不利な点は、頻繁に移動する1つの場所に多くのユニットがある場合、細分割が多すぎて、ユニットの移動により多くの更新が必要になる可能性があることです。下位分割が発生しないようなしきい値を設定できます。ただし、多くのユニットが同じリーフスクエアに配置される可能性があることを意味します。

ただし、一定の半径r内のすべての単位を見つけることにのみ関心がある場合は、四分木とkdツリーはすぐに必要ありません。長さrの辺のセルの2D配列を作成し、その位置に従って各セルにユニットを積み重ねることができます。このようにして、検索するセルは最低でも常に9つあります。マップが巨大な場合にのみ、そのようなグリッドは実装するには大きすぎます。

私たちが話していない、さらに完全に異なる2つの構造があります。階層AABBとローカル依存のハッシュテーブルです。各階層AABBの起点が親AABBに関連して記述されている場合、ユニットの大規模なグループがその形成を維持する場合、同じ相対的位置を維持するため、小さなAABBを更新する必要がないという利点があります。もちろん、フォーメーションを回転させると、多くの更新が発生する可能性があります。その場合、球体や方向性のあるバウンディングボックス(OBB)などの他のバウンディングボリュームを使用する方が効率的です。

ローカルセンシティブハッシュテーブルはおおよそのソリューションを効率的に提供するだけなので、私はそれらを気にしません。

どうしましょう ?おそらく単純なグリッドから始めて、必要に応じてそれをクアッドツリーにアップグレードし、必要に応じて、あるしきい値の下でそれをバウンディングボリューム階層と結合します。クアッドツリーは、大規模でうまく機能しますスケール、相対バウンディングボリュームは小さなスケールでうまく機能します。徐々に実行することで、すぐに最適なデータ構造を取得するために、最初から1時間を費やす必要はありません。


ありがとう!階層的なAABBやローカル依存のハッシュテーブルについて聞いたことがなかったので、将来について調べます。ここでは、単純なグリッドを使用し、必要に応じて拡張します。:)
Nairou 2014年

4

Lærneの提案は素晴らしいですが、AABBの動的境界ボリュームツリーも提案します。概念的には、ダイナミックバウンディングボリュームツリーは、AABBを渡して重複するペアを取得することにより、いつでも近くの要素をクエリできるノードのバランスツリーを保持します。ツリーはフレームごとに再構築されるわけではありません。代わりに、各ノードのAABBは、ツリーに配置されるとわずかに膨張し、ノードの実際のAABBが膨張したAABBに含まれなくなったときにのみツリーが再構築されます。私は物理エンジンでそれを使用し、それは素晴らしい働きをします。

Box2Dのソースコードは、すばらしい実装です。

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

ここにそれらの実装の良いレビューがあります:

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


ええ、それは多かれ少なかれ私が階層的なAABBによって意味したものでした、私はあまり正確ではありませんでした。ああ、そしてRTSesのユニットはしばしば機動性がありますが、フォーメーションにいます。したがって、親AABBノードを基準とした座標を使用すると、「インフレーション」エラーマージンがあり、非常に効率的です。
Lærne

Googleコードリンクを更新できますか?
kolenda
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.