Просторовий поділ - це завжди O (N ^ 2) у гіршому випадку, і саме в цьому полягає складність інформатики.
Однак існують алгоритми, які працюють у лінійному часі O (N) . Усі вони засновані на якійсь лінії розгортки.
В основному потрібно об'єкти сортувати за однією координатою. Скажімо, X. Якщо ви виконуєте сортування кожного разу перед виявленням зіткнення, складність буде O (N * logN). Трюк полягає в сортуванні лише тоді, коли ви додаєте об'єкти на сцену і пізніше, коли щось на сцені змінюється. Сортування після руху не є тривіальним. Дивіться зв'язаний папір нижче алгоритм, який приймає рух і все ще працює в лінійний час.
Потім ви підмітаєте зліва направо. Кожен раз, коли лінія розгортки перетинає початок об'єкта, ви поміщаєте його у тимчасовий список. Кожен раз, коли ваша лінія розгортки виходить з об'єкта, ви виймаєте її зі списку. Ви вважаєте зіткнення лише всередині цього тимчасового списку.
Наївна лінія розгортки - це O (N ^ 2) і в гіршому випадку (ви робите, що всі об'єкти охоплюють всю карту зліва направо), але ви можете зробити її O (N), зробивши її розумнішою (див. Посилання нижче). Дійсно хороший алгоритм буде досить складним.
Це проста схема, як працює лінія розгортки:
Лінія прошивається зліва направо. Об'єкти сортуються за X координатою.
- Випадок перший: спочатку перевіряються два об'єкти. Нічого іншого не має значення.
- Випадок другий: Спочатку об'єкт перевіряли і його немає у списку. Два і три перевіряються.
- Випадок третій: Навіть якщо цей об'єкт стикається, ми не перевіряємо.
- Випадок четвертий: Тому що ми перевіряємо в цьому випадку!
Такі алгоритми мають складність O (C * N) = O (N).
Джерело: Два роки курсів обчислювальної геометрії.
При виявленні зіткнень це, як правило, називається Sweep і Prune , але сімейство розгортки ліній алгоритмів корисно в багатьох інших сферах.
Далі рекомендується прочитати, що, на мою думку, виходить за рамки цього питання, але, тим не менш, цікаво: Ефективні великомасштабні методи розгортки та підрізання з введенням та видаленням AABB - У цьому документі представлений вдосконалений алгоритм зачистки та підрізання, який використовує обмежувальні вікна, орієнтовані на осі (AABB ) з сортуванням, що враховує рух. Алгоритм, представлений у статті, працює у лінійному часі.
Тепер зауважимо, що це найкращий теоретичний алгоритм . Це не означає, що воно використовується. На практиці алгоритм O (N ^ 2) з просторовим поділом матиме кращу швидкість роботи в типовому випадку (близьку до O (N)) та деяку додаткову вимогу до пам'яті. Це тому, що константа C в O (C * N) може бути дуже високою! Оскільки у нас зазвичай достатньо пам'яті, а типові випадки мають об’єкти рівномірно розподілені в просторі - такий алгоритм виконує КРАЩЕ. Але O (N) - це відповідь на початкове запитання.