Я делаю игру, основанную на 2D сетке, где некоторые ячейки проходимы, а некоторые нет. Динамические объекты могут двигаться непрерывно, независимо от сетки, но должны сталкиваться с непроходимыми ячейками.
Я написал алгоритм трассировки луча по сетке, который дает мне все ячейки, которые пересекает луч. Однако фактический объект не имеет точечного размера; В настоящее время я представляю их как круги. Но я не могу найти эффективный алгоритм для отслеживания движущегося круга. Вот картина того, что мне нужно:
Числа показывают, в каком порядке круг сталкивается с ячейками сетки. Кто-нибудь знает алгоритм, чтобы найти эти столкновения? Желательно в C #.
Обновление Круг может быть больше, чем одна ячейка сетки.
c#
collision-detection
algorithm
grid
Ничего
источник
источник
Ответы:
Я думаю, что ваш рисунок немного вводит в заблуждение, потому что вы выбираете рисовать штрихи из точки на окружности, касающейся вашего направления движения. Я вижу, что столкновения с краями вашей сетки происходят, когда точки TOP и LEFT вашего круга касаются края.
Пусть C - ваш центр, а r - радиус, поэтому P ' = C + ( r , 0) и P " = C + (0, r).
Если D - ваш вектор направления (версор), у вас есть две линии:
R '= D · t + P' ,
R "= D · t + P"
Вам просто нужно найти пересечение этих линий с линиями уравнения:
y = i и y = i, которые являются краями вашей сетки!
Решение легко, потому что вы должны просто рассмотреть x или y компонент R 'и R ". Вы найдете значение t s для каждой вставки и точки для thous t s, просто отсортируйте эти точки по t, и вы сделаны.
Я полагаю, что вы легко можете сказать, на какую клетку попала, если знаете точку пересечения.
Это работает, если r <1 (ширина и высота ячейки).
Это работает и для других случаев, просто делая некоторые соображения о P ' и P " . Мы выбираем TOP и LEFT, потому что направление, BOTTOM и RIGHT должны рассматриваться для противоположного направления, вы понимаете, почему.
Теперь посмотрите на это изображение:
Круг больше, чем одна ячейка, и мы предполагаем, что он движется в том же направлении, что и ваш рисунок. P1 - первая точка, которая будет касаться, P2 - вторая, P3 бесполезна, потому что находится в нижней половине. Что вам нужно сделать, это отлить лучи из P1 и P2, как мы видели ранее, и сделать то же самое для вертикальных линий.
В общем, у вас будут другие стартовые точки, помимо ТОПа и ЛЕВЫХ, с которых вы будете стрелять лучами, чем больше ваш круг, тем больше лучей будет наложено.
Честно говоря, вы можете избегать попадания всех этих лучей в геометрическую форму, но это может усложнить понимание.
источник
Если вы хотите использовать свой алгоритм столкновения лучей, вы можете выбрать восемь точек на каждом круге (с шагом 45 градусов, выровненных по квадратной сетке) и использовать столкновение лучей между соответствующими точками (т. Е. Сверху одного из них). круг к вершине другого). Объединение всех этих лучевых столкновений - это совокупность пересеченных ячеек.
Вероятно, вы могли бы немного улучшить это - например, используя отрезок линии от центра одного круга к центру другого, но вытянутый с обеих сторон радиусом круга, а также параллельные отрезки на любая сторона на концах кругов.
источник
Я не говорю, что это идеальная аналогия, но вы можете подумать об алгоритме линии Брезенхэма . Модификация этого алгоритма или одного из его расширений может быть полезной, особенно если вы связываете его с некоторыми другими постами и комментариями. Как правило, этот алгоритм не связан с упорядочением, но я думаю, что вы сможете добавить это довольно тривиально.
источник