Какой хороший, простой 2D-алгоритм обнаружения столкновений?

Я разрабатываю обучающий учебник для детектирования столкновений для молодых людей, поэтому я хочу, чтобы это было максимально простым, чтобы было легче объяснить.

Требования очень просты. Мир 2D и содержит только прямоугольники (произвольных размеров). BSP и даже quadtrees кажется, что это будет излишним (опять же, акцент делается на простоте), но мне хотелось бы что-то более эффективное, чем грубое форсирование через все n (n-1)/2 возможных столкновений.

2D, только прямоугольники и простые.

Может ли кто-нибудь указать на алгоритм, который я могу найти? Является ли алгоритм квадранта тем, что я ищу?

EDIT: Кроме того, прямоугольники никогда не будут повернуты (я сохраняю это просто). И чтобы дать вам представление о том, в каком масштабе я работаю, будет порядка нескольких сотен прямоугольников, работающих на вашем типичном пользовательском ноутбуке/рабочем столе (менее 5 лет), реализованном в Python с Pygame.

Ответы

Ответ 1

По моему опыту, все алгоритмы широкополосного обнаружения столкновений относительно тонкие и трудно понятны. Учитывая, насколько дешевым является тестирование на прямоугольник-столкновение, я бы структурировал урок с использованием алгоритма n ^ 2, а затем в качестве материала бонуса, возможно, представил идею пространственной индексации. Имея менее сотни прямоугольников, я готов поспорить, что тупой способ достаточно быстрый.

Квадрат был бы хорош для ваших целей, но помните, что когда вы имеете дело с нетонами, вы должны поместить прямоугольник в node, который содержит все квадранты, которые он пересекает. Затем, тестируя что-то, что в низком node, вы должны протестировать все исправления в этом node и во всех его предках!

Вы также можете рассмотреть алгоритм сортировки и развертки, так как то, что у вас уже есть, ограничено по оси рамками.

Ответ 2

Одна простая стратегия, ускорившая обнаружение в ранней попытке простой 2D-игры, состояла в том, чтобы сохранить список, отсортированный по более длинному размеру. Фаза столкновения состояла примерно из этого:

for i in 0..n
   j = i+1
   while rect[j].left < rect[i].right
       check for collision in y
       j=j+1
   endwhile 
endfor

Ответ 3

Вот простой алгоритм, который немного ускорит работу и будет работать с прямоугольниками, выровненными по оси.

Выберите одну из осей как "отсортированную ось". Для этого описания я скажу, что ось X отсортирована. Укажите каждый прямоугольник как два узла, "enter" node и "exit" node на отсортированной оси. Узлы ввода должны всегда иметь меньшее значение на оси, чем выходные узлы.

Создайте отсортированный список всех точек входа и выхода.

Пройдите отсортированный список. Когда вы нажмете каждый "enter" node, добавьте его в список "введенных" прямоугольников, а затем выполните обнаружение столкновения грубой силы против всех остальных узлов в "введенном" списке. Когда вы нажмете каждый "выход" node, удалите его из "введенного" списка.

Затем вы можете пройти через программу, в которой сам "введенный" список сортируется по оси Y с помощью точек "enter" и "exit" на оси Y.