Разрешение столкновений

23

Я хорошо знаю, как проверять столкновения, но я не знаю, как правильно справиться со столкновением.

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

Но что, если я попытаюсь переместить два объекта, чтобы они не перекрывались. Это звучит как хорошая идея, но я понял, что если есть более двух объектов, это становится очень сложным. Что если я переместлю два объекта, и один из них столкнется с другими объектами, поэтому мне придется переместить их тоже, и они могут столкнуться со стенами и т. Д.

Я имею в виду 2D-игру сверху вниз, но я не думаю, что это имеет к этому какое-то отношение. Как обычно обрабатываются столкновения?

Этот вопрос задается от имени Wooh

CiscoIPPhone
источник
1
Можете ли вы уточнить тип игры? «Сверху вниз 2D» может означать много вещей: приключенческая игра в стиле Zelda, шутер с вертикальной прокруткой или игра в карманный бильярд. Все это будет иметь совершенно разные стандартные стили обработки столкновений!
Ян Шрайбер
2
Я не могу это уточнить. Вопрос не в том, что произойдет в результате столкновения, а в том, чтобы решить проблему множественного перекрытия. Я думаю, достаточно знать, что я отскакиваю друг от друга, и я хочу, чтобы они вели себя реалистично, чтобы ответить на этот вопрос.
CiscoIPPhone

Ответы:

16

Даниэль Кодичек подробно описывает эту тему в своей книге « Математика и физика для программистов» .

Kodicek делает две вещи для достижения естественного разрешения столкновений:

  • Его функция обнаружения столкновений рассчитывает точное время столкновения двух объектов.
  • Он пересчитывает новые скорости во время столкновения, поэтому объекты никогда не перекрываются.

Я загрузил демоверсию, основанную на обнаружении и разрешении столкновений Kodicek .

обновление: вот алгоритм обнаружения и разрешения столкновений, который очень похож на метод Kodicek. С исходным кодом . Я все еще рекомендую книгу Кодичека, поскольку его алгоритм реализован немного по-другому и гораздо более подробно объяснен.

Leftium
источник
1
Ваша демонстрационная ссылка не работает.
ashes999
@ ashes999: ссылка исправлена!
Leftium
Это алгоритм для кругов. Как насчет коробок?
Антон Чикин
@AntonChikin: алгоритм разрешения столкновений Kodicek принимает только три входа: массу, скорость и нормаль в точке столкновения. Kodicek всегда вычисляет нормаль в точке столкновения при обнаружении столкновений. Он объясняет много разных типов обнаружения столкновений, в том числе поле, поражающее другое поле. Просто подключите этот алгоритм обнаружения столкновений к алгоритму разрешения столкновений. Смотрите главы 8-10 книги Kodicek для полного объяснения. (Обратите внимание, что физика вращения требует больше математики, о чем также
пойдет речь
1
@ThomasHilbert: демонстрационный исходный код и исполняемые файлы Windows теперь доступны на leftium.com/asteroid
Leftium
6

Что если вы проверите столкновение до того, как объекты переместятся, а не после? Или, другими словами, вы отклоняете новую позицию, если объекты сталкиваются, повторно используя старую в этом случае?

псевдокод:

  tmpPosition1 = Obj1.position
  tmpPosition2 = Obj2.position
  updatePosition(Obj1)
  updatePosition(Obj2)
  if collided(Obj1,Obj2) then
      updateVelocities( Obj1, Obj2 )
      Obj1.position = tmpPosition1
      Obj2.position = tmpPosition2
  endif

Таким образом, объекты будут сталкиваться друг с другом, когда они собираются столкнуться , если ваш шаг обновления достаточно мал, игрок не должен заметить ничего странного в представлении.

CeeJay
источник
1
Это довольно раздражает, потому что вы не можете легко перемещаться параллельно объектам, потому что вы не можете двигаться вообще, если вы касаетесь других объектов.
Икке
Если вы не разрешить х и у по отдельности
instantaphex
6

Всякий раз, когда два объекта перекрываются, проверьте, движутся ли они друг к другу или от них. Делайте столкновения, только если они движутся навстречу друг другу.

С векторной математикой это довольно просто, просто посчитайте:

dot_product (B.position - A.position, A.velocity - B.velocity)

Если результат положительный, объекты движутся навстречу друг другу.

AAAAAAAAAAAA
источник
4

Я мог бы быть неправильно истолкован, но похоже, что вы задаете два вопроса: 1. каковы некоторые общие способы решения конфликтов, термин, который вы ищете, это «имитация на основе импульсов», и есть множество статей, которые Я могу сделать это лучше, чем я.

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

Для углового отклика, к счастью, наибольшие и наименьшие моменты инерции всегда можно уменьшить до двух ортогональных осей (в 2D), что означает, что матричное умножение будет работать в целом, и если вы выровняете их по осям X и Y, оно превратится в 2D вектор.

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

С этого момента вы в конечном итоге добавляете все больше и больше правил для управления аномальным поведением, например, ограничение максимального момента импульса, чтобы вещи не вращались как вершины и т. Д., Но это хорошее начало.

Сохраняйте это простым, если можете.

  1. Как вы решаете проблемы столкновения нескольких тел

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

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

Надеюсь это поможет. Если вам нужны математические примеры, дайте мне знать.

Аарон Брейди
источник
3

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

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

Это широкая тема, но, надеюсь, приведенная выше информация поможет вам начать.

Samaursa
источник
Таким образом, вместо предотвращения проникновения этот метод позволяет, но обеспечивает сопротивление, почти как объекты сжимаются?
CiscoIPPhone
Это обеспечивает сопротивление, да, сопротивление увеличивается, чем больше организм пытается проникнуть. На практике, если у вас достаточно низкое время дельты (например, 10 мс), оно не будет вызывать никаких проникновений. Однако реальным преимуществом этого метода является то, что когда у вас есть тела, которые проникли друг другу по разным причинам (позиция была изменена, они представляют собой твердые тела, объединенные в сеть, и их позиции были исправлены), и теперь их необходимо отделить, потому что без этой техники тела будет взрываться, а не постепенно отделяться.
Самаурса