Алгоритм, щоб визначити, чи пов’язані два вокселі


11

Я шукаю хороші алгоритми для наступної проблеми: З огляду на 3D-сітку вокселів (яка може бути або порожньою, або заповненою), якщо я вибираю два суміжних вокселі, я хочу знати, чи вони пов'язані між собою інші вокселі.

Наприклад (для ілюстрації ситуації у 2D), де # - заповнений квадрат:

  1 2 3
a # # #
b # #
c # # #

Якщо я вибираю a3 і c3, я хочу визначити якомога швидше, чи вони підключені; якщо є шлях між а3 і с3 через заповнені пікселі. (Справжня ситуація, звичайно, в 3D-воксельній сітці.)

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

Який алгоритм я повинен використовувати?

Редагувати: виходячи з коментарів, я думаю, слід додати наступне: вміст вокселів не відомий заздалегідь, а також алгоритм необхідний для виявлення, чи видалення (випорожнення) вокселя призведе до розриву групи вокселів на дві або більше менших груп.


У вашому прикладі чи правильним шляхом від a3 до c3 буде такий c3->c2->b2->a2->a3:?

це правильно
Брам Вассен

Відповіді:


12

A * буде добре працювати. Пошук шляху - це те, що ви хочете, пошук найкоротшого шляху так само швидкий (або швидший), ніж пошук будь-якого шляху. У цій ситуації A *, ймовірно, є найбільш підходящим, якщо у вас є початкова і кінцева точка. це означає, що ви додали евристику для прискорення пошуку.

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

введіть тут опис зображення

Щоб отримати деякі оптимізації, перегляньте мою відповідь тут .


схоже, що це справді стріляє вперед, поки не вдарить про цю стіну, тоді вона наче повзе
GameDev-er

1
@ GameDev-er Так, це пов’язано з евристикою. Якби не було перешкод, це був би дуже швидкий пошук, майже пряма лінія.
MichaelHouse

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

9

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

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

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


1
Це правильна відповідь, але щоб ефективно її реалізувати, вона не повинна зберігатися як список. Додайте вказівник до кожного вокселя, який вказує на його "представницький воксель", який ви встановили за допомогою алгоритму об'єднання-пошуку. Це постійна вартість зберігання на воксель і в основному лінійна кількість ребер для обчислювальної вартості.
Ніл Г

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

1
Друга проблема полягає в тому, що алгоритм потрібен одразу після видалення одного вокселя, щоб визначити, чи розбита група, до якої вона входила, на менші групи через видалення цього вокселя.
Брам Вассен

@BramVaessen Якщо ви шукаєте всі парні відносини взаємозв'язку - і зокрема, чи розбиваються групи - то це дещо інша справа, ніж просто досяжність (хоча реалізація - це найпростіший спосіб вирішити цю проблему); Я б радив додати більше детальних відомостей про конкретні запитання про оригінальне запитання, оскільки це може дати кращі відповіді на "проблему, що стоїть за питанням".
Стівен Стадницький

Щоб зберегти його в чистоті, я поставив свою первісну проблему в іншому запитанні тут gamedev.stackexchange.com/questions/50953/…
Брам Вассен

4

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

Можливо, вам пощастить використовувати альтернативну евристику, яка розширює менше вузлів, таких як

f (p) = g (p) + w (p) * h (p)

де w> = 1. ви зменшуєте значення 'w', чим ближче досягаєте мети, тим самим надаючи більший пріоритет вартості шляху 'g', тим ближче до ви шукаєте воксель.

Я сподіваюся, що це допомагає!

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