Обработка столкновений между круговыми и линейными сегментами

Я реализую небольшую игру, и у меня возникают проблемы с правильной работой физики. В этой игре есть один шар (круг, который перемещается от кадра к кадру и может менять радиус) и несколько стен (отрезки линий, которые также меняются и перемещаются от кадра к кадру). Я могу правильно определять столкновения, и заставить мяч отскакивать в правильном направлении не проблема.

Трудности возникают в ситуациях, когда мяч пересекает линию в одном кадре, затем снова пересекает ее в следующем кадре, вызывая двойной отскок. Я мог бы переместить мяч обратно по нормали к линии, пока он не окажется в допустимом положении, но это вызывает действительно странное поведение, когда рассматриваемая линия ударяется вдоль ее оси (представьте, что мяч для пинг-понга падает на вертикальную зубочистку и внезапно смещаясь в сторону так, чтобы она оказалась на одной стороне зубочистки...). Есть также несколько проблем, когда мяч пересекает более одной линии в данном кадре (представьте, что четыре линии вместе образуют прямоугольник, а мяч пересекает угол указанного прямоугольника) — в каком направлении он должен отскакивать? В каком направлении он должен смещаться?

На самом деле у меня нет конкретного вопроса, но я ищу советы или несколько полезных руководств. Все 2D, которые мне пока удалось найти, покрывают только пересечения прямоугольников.

Я использую XNA, если это имеет значение.

Спасибо,
Кэмерон.


person Cameron    schedule 07.12.2009    source источник
comment
Вы проверили физический движок Farseer? codeplex.com/FarseerPhysics   -  person Martin    schedule 07.12.2009
comment
На самом деле, я только что скачал его вскоре после того, как задал свой вопрос. Я собираюсь попробовать - пока все выглядит хорошо (я читал документацию)!   -  person Cameron    schedule 07.12.2009
comment
В конце концов, я не смог заставить движок делать то, что хотел, а документации не хватало, поэтому я вернулся к своему собственному физическому движку и улучшил его, используя некоторые из приведенных ниже предложений.   -  person Cameron    schedule 16.12.2009


Ответы (2)


Это универсальная проблема для большинства физических библиотек. Если вы погуглите «глубину проникновения» (вместе с «физикой», я предлагаю, или вы можете найти что-то совершенно другое: D), вы обнаружите, что даже эти библиотеки используют такие приемы, как ваши.

Для этого есть два решения:

Самый дешевый — увеличить частоту обновлений. Перемещайте объекты на 10 меньших шагов вместо одного большого, и у вас будет меньше проникновения, поэтому фиксация путем смещения шара от стены будет менее заметной.

Дорогостоящим является непрерывное обнаружение столкновений. Существуют алгоритмы, которые могут сказать вам, что движущийся и неподвижный объект пересекутся в определенный момент времени. Погуглите «пересечение прямоугольника с закругленной сферой», чтобы найти некоторые из них.

Затем вы можете обновить так: мяч должен переместиться на 1,0 единицы. Проверить на столкновение. Столкновение происходит через 0,25 единицы, поэтому переместите мяч на 0,25 единицы, рассчитайте вектор отражения (чтобы мяч отскочил от стены), повторите проверку столкновения с оставшимися 0,75 единицами (пока не узнаете конечное положение мяча). Это позволяет полностью избежать проникновения, и даже если ваш мяч движется так быстро, что обычно перескакивает через стену за одно обновление, столкновение будет обнаружено.

person Cygon    schedule 10.12.2009
comment
Спасибо за ответ! Я обязательно погуглю то, что вы предложили, когда у меня будет больше времени. Мне удалось устранить большинство изгибов в моей физике, интерполируя положения всего, начиная с последнего кадра, и заканчивая текущим, на очень небольшой процент (ровно достаточно, чтобы заставить мяч сместиться на один пиксель) до тех пор, пока не было обнаружено столкновение (эффективность была второстепенная цель). - person Cameron; 16.12.2009

Общепринято, что из-за временного шага ваши столкновения будут пересекаться за допустимой точкой между обновлениями.

По сути, вы должны интерполировать обратно к точке между последним и текущим кадром, где действительно произошло столкновение, переместить объект обратно в эту точку, а затем рассчитать силы и т. д.

person Joel Martinez    schedule 08.12.2009
comment
Я думаю, что большинство проблем, с которыми я сталкиваюсь, можно решить, найдя начальное столкновение, вместо того, чтобы заставлять мяч сталкиваться с каждым объектом, с которым он пересекается в данном кадре. - person Cameron; 09.12.2009