완전 동적 KD- 트리 대 쿼드 트리?


11

게임을 할 때 전 세계의 모든 유닛을 추적해야 가장 가까운 이웃 전투를 확인할 수 있습니다. RTS와 유사한 게임으로 수천 개의 소형 자동화 장치가 움직일 수 있습니다.

KD-Trees 및 Quadtrees (특히 Point Quadtrees)를 살펴 보았습니다. 나는 여전히 작동 방식에 대한 세부 사항을 배우려고 노력하고 있지만 지금까지 Point Quadtrees가 가장 적합합니다. 그러나 KD-Trees가 더 빨리 검색된다는 인상을 받았습니다. 이는 트리에서 가질 수있는 포인트 수에서 중요합니다.

반면에 제 경우에는 항상 움직이는 많은 유닛을 추적하려고합니다 . 프레임마다 위치는 항상 다릅니다. 쿼드 트리는 KD- 트리보다 리 밸런싱 속도가 더 빠르지 만 트리의 모든 지점을 재조정 할 때 적용 가능한지 잘 모르겠습니다 .

이 경우 트리의 모든 단일 지점을 재조정하려고하는 대신 각 프레임을 트리에서 스크랩하고 처음부터 다시 작성하는 것이 더 나은지 궁금합니다. 쿼드 트리가 재조정이 더 빠르면 처음부터 더 빨리 구축하는 것입니까? 그렇다면 트리를 만드는 데 얼마나 많은 부담이 있는지에 따라 KD-Tree의 검색 속도보다 성능이 더 중요 할 수 있지만 모르겠습니다 ...

답변:


12

KD- 트리는 정직하게 고려할만큼 역동적이지 않습니다. 일부 장치를 이동하면 전체 KD-Tree를 쉽게 재구성해야합니다. 또한 KD 트리는 쿼리에 매우 효율적이지만 인접 검색에는 그다지 효과적이지 않습니다.

수정 사항이 더 로컬에 유지되므로 쿼드 트리는 시간이 지남에 따라 더 유연합니다. 단점은 한 장소에 자주 이동하는 유닛이 많은 경우 유닛이 너무 세분화되어 유닛 이동으로 인해 많은 업데이트가 필요하다는 것입니다. 세분화가 발생하지 않는 임계 값을 설정할 수 있습니다. 그러나 많은 단위가 잠재적으로 동일한 잎 사각형에있을 수 있음을 의미합니다.

그러나 일정한 반경 r 내에서 모든 단위를 찾는 데 관심이 있다면 quadtree 및 kd-tree가 필요하지 않습니다. 길이가 r 인 셀의 2D 배열을 간단히 생성 하고 위치에 따라 각 셀에 단위를 쌓을 수 있습니다. 이렇게하면 항상 검색 할 최악의 셀이 9 개가됩니다. 지도가 거대한 경우에만 이러한 그리드가 구현하기에는 너무 큽니다.

우리가 언급하지 않은 완전히 다른 두 가지 구조가 있습니다 : 계층 적 AABB와 로컬-민감 해시 테이블. 각 계층 AABB의 원점이 상위 AABB와 관련하여 설명되는 경우, 큰 단위 그룹이 구성을 유지하는 경우 동일한 상대 위치를 유지하므로 더 작은 AABB를 업데이트 할 필요가 없다는 이점이 있습니다. 물론, 포메이션을 회전하면 많은 업데이트가 발생할 수 있으며,이 경우 구 또는 OBB ( Oriented Bounding Box) 와 같은 다른 바운딩 볼륨을 사용하는 것이 더 효율적일 수 있습니다.

로컬에 민감한 해시 테이블은 대략적인 솔루션 만 효율적으로 제공하므로 걱정하지 않아도됩니다.

어떻게해야합니까? 아마도 간단한 그리드로 시작하고 필요할 때 쿼드 트리로 업그레이드하고 필요한 경우 임계 값 아래에서 경계 볼륨 계층 구조와 결합합니다. 쿼드 트리는 크게 작동합니다. 스케일, 상대 경계 볼륨은 소규모로 잘 작동합니다. 점진적으로하면 최고의 데이터 구조를 즉시 얻기 위해 처음부터 시간을 소비 할 필요가 없습니다 .


감사! 계층 적 AABB와 로컬 감지 해시 테이블에 대해 들어 본 적이 없으므로 앞으로 살펴볼 것입니다. 지금은 간단한 그리드로 가고 있으며 필요에 따라 확장 할 것입니다. :)
Nairou

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.