Повністю динамічний KD-Tree проти квадрату?


11

Працюючи над своєю грою, я знаходжусь у точці, коли мені потрібно відстежувати всі підрозділи у світі, щоб я міг робити перевірки найближчих сусідів на бій. Це гра, схожа на RTS, із потенційно тисячами маленьких автоматизованих одиниць, що рухаються навколо.

Я розглядав KD-Дерева та Квадрат (особливо квадрати точок). Я все ще намагаюся дізнатися подробиці того, як вони працюють, але поки що «Квадратні точки» мають для мене найбільше сенсу. Однак у мене складається враження, що KD-Дерева швидше шукають, що важливо з кількістю очок, які у мене будуть на дереві.

З іншого боку, в моєму випадку я збираюся відстежувати величезну кількість одиниць, які завжди рухаються. Від кадру до кадру їх положення завжди будуть різними. Квадрати, мабуть, швидше відновляться, ніж KD-Дерева, але я не знаю, чи це застосовно, коли ви відновлюєте кожну точку на дереві.

Мені цікаво, чи було б краще в такому випадку просто брухтувати дерево кожен кадр і перебудувати його з нуля, а не намагатися перебалансувати кожну точку дерева? Якщо Quadtree швидше відновиться, чи це також означає, що його швидше будувати з нуля? Якщо це так, це може бути важливішим для продуктивності, ніж швидкість пошуку KD-Tree, залежно від того, скільки тягаря це створити дерево, але я не знаю ...

Відповіді:


12

KD-дерева, безумовно, недостатньо динамічні, щоб їх врахувати, чесно. Переміщення декількох одиниць може легко зажадати від вас відновити ціле дерево KD. Плюс, KD-дерево дуже ефективне для запитів, але не стільки для пошуку сусідів.

Квадрат є більш гнучким у часі, оскільки модифікація зберігається більш локально. Недоліком є ​​те, що якщо у вас на одному місці багато одиниць, які часто рухаються, це може занадто сильно розділитись і вимагати багато оновлень через рух одиниць. Ви можете встановити поріг, під яким не можуть відбуватися підрозділи. Але будьте обережні, що означає, що багато одиниць потенційно можуть знаходитися на одній листовій площі.

Якщо ви тільки зацікавлені в пошуку всіх одиниць в постійному радіусі r , вам не потрібні квадрати і kd-дерево відразу. Ви можете просто створити 2D масив комірок стороною довжини r і скласти свої одиниці в кожну клітинку відповідно до їх положення. Таким чином, у вас завжди є найгірший 9 комірок для пошуку. Тільки якщо ваша карта величезна , така сітка була б занадто великою для реалізації.

Є ще дві абсолютно різні структури, про які ми не говорили: ієрархічні AABB та локальна хеш-таблиця. Якщо походження кожного ієрархічного AABB описано стосовно батьківського AABB, то це має перевагу, що якщо велика група одиниць зберігає своє формування, то вам не потрібно оновлювати менші AABB, оскільки вони зберігають однакові відносні позиції. Звичайно, обертання пласта може спричинити багато оновлень; у цьому випадку використання інших обмежувальних томів, таких як сфери або орієнтовані обмежувальні коробки (ОББ), може бути більш ефективним.

Локально-чутливі хеш-таблиці дають лише приблизні рішення ефективно, тому я б не переймався ними.

Що б я зробив? Я, мабуть, почав би з простої сітки, і коли мені це потрібно, я би оновив її до квадрату, і якщо мені це потрібно, я з’єднаю її з обмежувальною ієрархією обсягу під деяким порогом: квадрати добре працюють на великих масштаб, відносні обмежувальні обсяги добре працюють в невеликому масштабі. Роблячи це поступово, мені не потрібно витрачати годину з самого початку, щоб отримати найкращу структуру даних негайно .


Дякую! Я не чув про ієрархічні 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?
коленда
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.