2D альтернативи просторового розподілу просторовим хешам і квадратам


11

Я намагався реалізувати алгоритм просторового розподілу у своїй грі, але і просторові хеші, і квадри не є тим, що я шукаю.

Мій рівень не повинен мати обмеження (лише обмеження Int32). Мені потрібен алгоритм просторового розподілу, який не потребує "Ширина рівня" та "Рівень висоти".

У мене багато рухомих фізичних об’єктів. Мені потрібен алгоритм, щоб бути досить швидким для підтримки 500+ об'єктів.

Будь-яка альтернатива?

Відповіді:


13

Динамічне дерево

Box2D - це добре оптимізований двигун, розроблений досвідченим фізичним / ігровим програмістом . Спочатку Box2D використовував хеш-сітку, яка вимагала фіксованої висоти та ширини.

Коли Ерін перейшов до кращого алгоритму широкої фази, він пішов з btDbvt Натанаеля Прессона. Це широка фаза, яку використовує Фізика кулі. Ерін модифікував і оптимізував алгоритм для 2d.

Ви можете прочитати надзвичайно високий рівень у керівництві Box2D (§4.11 або шукати Динамічне дерево).

Ось виняток із документації в коді (що дуже добре, враховуючи, що це не частина публічного API).

Динамічне дерево AABB широкої фази, натхнене btDbvt Натанаеля Прессона. Динамічне дерево впорядковує дані у двійкове дерево для прискорення запитів, таких як запити томів та передавачі променів. Листя - це проксі з AABB. У дереві ми розширюємо проксі-сервер AABB на b2_fatAABBFactor, щоб проксі-сервер AABB був більшим за клієнтський об’єкт. Це дозволяє клієнтському об’єкту рухатися невеликими розмірами, не викликаючи оновлення дерева.

Вузли об'єднані і переміщуються, тому ми використовуємо індекси вузлів, а не покажчики.

Я розумію алгоритм Динамічного дерева. Динамічне дерево - це схрещування між класичним бічним деревом avl та квадратом. Кінцевим ефектом є квадратне дерево, яке розбиває кожен вузол навпіл, а лінія розбиття не фіксована (дві половини не мають однакового розміру, як квадратичне дерево). AVL надходить, тому що квадрати з динамічними розщепленнями можуть перероджуватися до суттєво списку (O (n) швидкості пошуку). AVL використовується для перебалансування підтрубків, щоб забезпечити швидкість пошуку O lg (N).

Найкращим кодом є MIT, тому сміливо копіюйте / отримуйте / безсоромно красти / тощо.


Виглядає ... складно! Я, однак, погляну на це. Хтось запропонував мені використовувати техніку "підмітання та підрізання" або "сортування та підмітання", але я не зміг знайти нічого про реалізацію C # або .NET. Я знайшов приклад c ++, але він заплутаний, і він не спрацював (я намагався його реалізувати все одно). Як ви думаєте, SAP було б легше впровадити? Чи є реалізація .NET?
Вітторіо Ромео

8

Це дуже близько до аналогічного питання, яке задають тут у Gamedev, але якщо ви переймаєтесь продуктивністю, а не зберіганням файлів, можливо, моя відповідь буде вам кориснішою . Я включу сюди основну частину для повноти, але оригінальна відповідь дає трохи більше глибини, якщо ви хочете заглянути в неї.

Я зіткнувся з подібною проблемою і вирішив створити власну структуру для обробки даних. Він заснований вільно на квадраті, але має нескінченну (принаймні велику, як Інт) розширюваність у всіх напрямках. Він був розроблений для обробки даних на основі сітки, які розширилися від центральної точки, як це робить Minecraft зараз. Це просторовий об'єм пам’яті та дуже швидкий.

Мій код можна знайти тут . Код повний, перевірений (одиничні та навантажувальні випробування) та досить оптимізований. Внутрішня робота поки що не надто добре зафіксована, але всі публічні методи такі, що слід використовувати. Якщо хтось вирішить спробувати його, не соромтесь звертатися до мене з питаннями чи коментарями.


1

Під час роботи з відносно невеликою кількістю (<декількох тисяч) дрібних об'єктів (більшість об'єктів недостатньо великі, щоб потенційно стикатися з безліччю інших об'єктів), я виявляю, що простий список упорядкованих по осі орієнтованих обмежувальних коробок (AABBs) працює в порядку x досить добре. Я просто кладу об’єкти в список, потім кожен кадр після переміщення об'єктів, я швидко сортую список за значенням x, а потім проходжу один прохід через список, перевіряючи близькість AABB. Для кожного об'єкта я перевіряю його щодо об'єктів, що випереджають його у списку, поки я не дойду до кінця списку, або до об'єкта, який знаходиться поза діапазоном x; тобто значення x для лівого краю є> x значення правого краю об'єкта, який тестується. Він, в основному, динамічно розділяє простір на фрагменти розміром AABB-x шириною, що перекриваються часом. Це '


0

Можливо, алгоритм r-дерева саме те, що ви шукаєте.

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


Я спробував реалізацію C #, і продуктивність виявилася занадто поганою при "видаленні та додаванні об'єктів на їх новій позиції".
Вітторіо Ромео

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.