QuadTree: зберігати лише точки, або регіони?


9

Я розробляю квадрати для відстеження рухомих об’єктів для виявлення зіткнень. Кожен об’єкт має обмежувальну форму, скажімо, це всі кола. (Це 2D гра зверху вниз)

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

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

Зіткнення між об'єктами сусідніх вузлів

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

Який вузол повинен містити червоний об’єкт?

Дякую.

Відповіді:


4

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

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

Аналогічно, для запиту до регіону запит повинен переглядати всі вузли листя, до яких доторкається область, що торкається.

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


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

4

Ви повинні зберігати його в найменшому вузлі, який повністю містить його, навіть якщо це перевищує ємність (використовуйте контейнер, що змінює розмір).


2

Я додав би це як коментар у відповідь на відповідь @Nathan Reed, за винятком того, що він занадто великий, щоб бути коментарем, і, можливо, у будь-якому випадку гідний, щоб бути окремою відповіддю.

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

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

У нас був один крайній випадок, коли близько 100 об’єктів, усі з обмежуючими дисками, були згруповані в дуже близькій близькості. Це призвело до проблеми дуже глибокого шипа на дереві, тому що ми дійшли до того, що об’єктів було більше, ніж площа, покрита квадратурними вузлами, тому кожен новий об’єкт з'являвся у кількох вузлах, що призводить до масового підрозділу дерево, таким чином, сніговики проблему виходять з-під контролю.

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

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

Ваш фактичний пробіг може відрізнятися.

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