Расчет столкновений в реальном времени - работа с задержкой во времени - PullRequest
3 голосов
/ 20 декабря 2011

Предположим:

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

  • вычисления могут быть рассчитаны только для каждого кадра

  • каждого кадра,Вы должны убедиться, что круги, которые "сталкиваются" / "столкнулись в течение времени между этим кадром и последним" с друг другом, будут "отскакивать", используя физические вычисления

  • Предположим,что за время между кадром x и кадром x + 1 три круга столкнутся друг с другом.Однако во время кадра x ни один из кругов не касается другого.В кадре x + 1 применяется то же самое (ни один не сталкивается). Я попытаюсь лучше проиллюстрировать это изображением:

enter image description here

вопрос:

Каковы хорошие способы отслеживания таких столкновений, чтобы столкновение не пропускалось из-за некоторой (неожиданной) большой задержки во времени между двумя кадрами?

Этот вопрос слишком долго звучал в моей голове ...

РЕДАКТИРОВАТЬ:

Всем, кто думает, что это сообщение ОТ: см.https://physics.stackexchange.com/questions/18515/calculating-collisions-in-realtime-dealing-with-a-delay-in-time перед тем, как голосовать за закрытие

Ответы [ 4 ]

2 голосов
/ 20 декабря 2011

Чтобы сделать это правильно:

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

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


Обновление, в ответ на комментарии: я хочу прояснить, что мой ответ игнорирует одно из ваших предположений - вы не можете точно обрабатывать столкновения, если вы делаете вид, что нет 'в любое время между границами кадра.Столкновения не происходят на границах кадра;в общем, столкновения произойдут между границами кадра, поэтому ваши вычисления должны отражать это.

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

posAB = posA - posB                [relative vector between circles A and B]
velAB = velA - velB                [relative velocity between circles A and B]
posAB(t) = posAB(0) + t * velAB    [relative vector as a function of time]
rAB = rA + rB                      [sum of radii of the two circles]
collision happens when distance(t) = abs(posAB(t)) == rAB
-> rAB^2 = | posAB(t) |^2 = | posAB(0) + t * velAB |^2
-> t^2 * |velAB|^2 + t * 2*posAB(0).velAB + |posAB(0)|^2 - rAB^2 == 0
solve quadratic equation for t:
   - if discriminant is negative, there is no collision.
   - if collision times are outside current timestep, there is no current collision.
   - otherwise, smallest t should be the correct collision time.
   - watch out for cases like 2 circles coming *out* of collision...

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

1 голос
/ 20 декабря 2011

Ключевыми словами обнаружения столкновений здесь являются «непрерывный» или «не непрерывный».

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

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

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

Что добавляет прерывательный механизм, чтобы избежать парной проверки всех объектов, так это использование некоторой структуры данных для отслеживания объектов, их общего положения и занятости в пространстве для обнаружения потенциальных перекрытий без необходимости проверить каждый объект против каждого объекта. Это называется broadphase в магазине. Вам определенно необходимо реализовать что-то подобное в конце концов, если вы начнете увеличивать количество объектов. Вы не указываете, какое «большое» количество кругов или на какой процессор вы нацеливаете, так что, надеюсь, вы можете пропустить это и сделать это простым способом для начала, но сложно сказать, если вы не опубликуете свой вариант использования.

Bottomline : Я бы выбрал испытанный и не проверенный тип непрерывного двигателя на достаточной физической частоте, чтобы избежать случая пропуска с высокой скоростью, и не беспокоиться о производительности. Если вы действительно заинтересованы в написании кода для игры и не хотите заботиться о деталях, вы можете просто использовать некоторые из существующих библиотек 2D-физики, например Chipmunk или Box2D * 1020. *. Я не знаком с их реализациями, но уверен, что они также являются хорошим способом изучения предмета, если вы изучаете код.

1 голос
/ 20 декабря 2011

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

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

x_a = x0_a + v_a*t
x_b = x0_b + v_b*t
d_ab = norm(x_a-x_b) = norm(x0_b-x0_a + (v_b-v_a)*t) = norm(dx + dv*t)

, если функция расстояния d_ab равна сумме радиусов r_a+r_b для любого t в течениешаг по времени, тогда у вас есть столкновение.Поэтому сначала проверяем, какие объекты сталкиваются (если есть), затем продолжаем с этой точки и повторяем анализ до тех пор, пока не будет достигнут конец временного шага.Довольно сложный, и все еще относится только к кругу / сферам.

1 голос
/ 20 декабря 2011

Идея оценивать вещи только в «кадрах», вероятно, неверна.

Один из самых старых шаблонов OO - это " Model-View-Controller " - который поощряет разъединение из того, что просматривается (модель) с как просматривается (View).

Физический движок работает с модельными объектами, и поэтому будет постоянно отслеживать взаимодействия между ними - поэтому, когда появляется представление и запрашивается положение и направление каждого круга в вашей "рамке x +1 ", он может легко ответить, исходя из того, сколько времени прошло с момента последнего запроса на просмотр.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...