В принципе, правильная шкала времени зависит от того, что испытывает игрок. Вы хотите, чтобы он был точным в течение нескольких недель, и чтобы игрок взаимодействовал с ним в режиме реального времени? Это гораздо сложнее, чем заставить его работать в течение нескольких недель, которые игрок испытывает во многих случаях в режиме реального времени ( то есть одна секунда опыта игрока составляет одну неделю в реальном времени).
mklingen
если вы моделируете движения облаков или термодинамические переменные в ячейках шириной в сотни метров, то с точностью до 10 минут это разумно. но твердое тело в обычных масштабах, не слишком много. какое приложение?
v.oddou
Приложение представляет собой «догоняющий» механизм, в котором выполняется моделирование с момента запуска последней загрузки (части мира), игровая логика полностью основана на обратном вызове, где обратные вызовы являются таймерами или обратными вызовами столкновений, я хочу иметь возможность запустить физику до следующего таймер обратного вызова эффективно, и имитация физики имеет дело с вызовом коллизий обратного вызова. Столкновения относительно маловероятны, но я бы хотел, чтобы обратные вызовы столкновений имели доступное игровое (физическое) состояние во время столкновения.
fread2281
Ответы:
5
Вы, вероятно, будете использовать постоянное ускорение для этих больших промежутков времени (которое может быть нулевым ускорением). Производная постоянного ускорения по времени равна 0. Это означает, что она не изменяется по времени, поэтому не имеет значения, насколько велико ваше дельта-время.
Эта небольшая интеграция по времени дает уравнения, которые вам нужны.
a = a
v = at + v0
s =.5at^2+ v0*t + s0
Где: a = ускорение, v = скорость, v0 = начальная скорость, s = позиция, s0 = начальная позиция, t = время
Используя эту стратегию, вы можете использовать промежутки времени от миллисекунд до недель, если хотите. Комбинируя их будет заботиться о в v0и s0параметров уравнения.
Для обработки столкновений вам нужно будет реализовать стратегии, аналогичные тем, которые используются для высокоскоростных небольших объектов . Сначала вычисляется новая позиция, используя приведенное выше уравнение, а затем перемещается между старой и новой позицией для всех объектов. Поскольку любой из этих объектов мог пересекаться друг с другом (минуты или дни раньше), это может быть очень сложным. Скорее всего, поскольку у вас такое большое время дельты, надеюсь, у вас будет достаточно времени для обработки этих потенциальных коллизий.
Я обновил ответ, чтобы включить стратегии обработки коллизий.
MichaelHouse
это неверно Интеграция Эйлера, как известно, отклоняется для постоянных интегрирований, а Верле (или RK2, RK4) - нет.
v.oddou
@ v.oddou Учитывая, что эти симуляции предназначены для игр, я не думаю, что требуемая точность необходима. Дополнительная сложность и сложность добавления коллизий для Verlet делает интеграцию Эйлера превосходным выбором.
MichaelHouse
2
Давайте возьмем пример с гравитацией.
В приведенной ниже функции предположим, что у нас есть переменные-члены класса для положения и скорости. Нам нужно обновлять их из-за силы тяжести каждые dt секунд.
void update(float dt ){
acceleration = G * m / r^2;
velocity = velocity + acceleration * dt;
position = position + velocity * dt;}
По мере того, как dtвсе меньше и меньше, наше моделирование становится все более и более точным (хотя, если dtстановится слишком маленьким, мы можем столкнуться с ошибками точности при добавлении крошечных чисел к большим числам).
По сути, вы должны решить, какой максимум dtможет выдержать ваша симуляция, чтобы получить достаточно хорошие результаты. А если dtвходящее слишком велико, просто разбейте симуляцию на более мелкие шаги, где каждый шаг - это максимум, dtкоторый вы допускаете.
void update(float dt ){
acceleration = G * m / r^2;
velocity = velocity + acceleration * dt;
position = position + velocity * dt;}// this is the function we call. The above function is a helper to this function.void updateLargeDt(float dt ){constfloat timeStep =0.1;while( dt > timeStep ){
update( timeStep );
dt -= timeStep ;}
update( dt );// update with whatever dt is left over from above}
Таким образом, с помощью этой стратегии вы можете просто приспособиться timeStep к любой точности воспроизведения (сделать ее секундой, минутой, часом или чем угодно, чтобы получить точное представление о физике).
В большинстве игр, как правило, используется простой метод прямого интегрирования Эйлера (то есть, интегрировать скорость в позицию во времени и интегрировать ускорение в скорость). К сожалению, метод Эйлера подходит только для очень маленьких временных масштабов и коротких периодов.
Существуют более сложные методы, которые более точны в течение очень длительного периода времени. Возможно, самым популярным и простым в реализации является Runge-Kutte-4 . RK4 определяет позицию в будущем, отбирая четыре позиции и скорости в прошлом и интерполируя. Он имеет тенденцию быть намного более точным, чем метод Эйлера, в более длительных временных масштабах, но является более дорогостоящим в вычислительном отношении.
Например, если вы хотите вычислить физику реальной орбитальной планеты, обновляемой каждые несколько дней в режиме реального времени, метод Эйлера заставит планету взлететь в космос после нескольких орбит из-за числовых ошибок. RK4, как правило, будет сохранять орбиту планеты примерно в одной и той же форме много тысяч раз, прежде чем накапливать слишком много ошибок.
Однако реализация коллизий в RK4 может быть очень сложной ...
Ответы:
Вы, вероятно, будете использовать постоянное ускорение для этих больших промежутков времени (которое может быть нулевым ускорением). Производная постоянного ускорения по времени равна 0. Это означает, что она не изменяется по времени, поэтому не имеет значения, насколько велико ваше дельта-время.
Эта небольшая интеграция по времени дает уравнения, которые вам нужны.
Где: a = ускорение, v = скорость, v0 = начальная скорость, s = позиция, s0 = начальная позиция, t = время
Используя эту стратегию, вы можете использовать промежутки времени от миллисекунд до недель, если хотите. Комбинируя их будет заботиться о в
v0
иs0
параметров уравнения.Для обработки столкновений вам нужно будет реализовать стратегии, аналогичные тем, которые используются для высокоскоростных небольших объектов . Сначала вычисляется новая позиция, используя приведенное выше уравнение, а затем перемещается между старой и новой позицией для всех объектов. Поскольку любой из этих объектов мог пересекаться друг с другом (минуты или дни раньше), это может быть очень сложным. Скорее всего, поскольку у вас такое большое время дельты, надеюсь, у вас будет достаточно времени для обработки этих потенциальных коллизий.
источник
Давайте возьмем пример с гравитацией.
В приведенной ниже функции предположим, что у нас есть переменные-члены класса для положения и скорости. Нам нужно обновлять их из-за силы тяжести каждые dt секунд.
По мере того, как
dt
все меньше и меньше, наше моделирование становится все более и более точным (хотя, еслиdt
становится слишком маленьким, мы можем столкнуться с ошибками точности при добавлении крошечных чисел к большим числам).По сути, вы должны решить, какой максимум
dt
может выдержать ваша симуляция, чтобы получить достаточно хорошие результаты. А еслиdt
входящее слишком велико, просто разбейте симуляцию на более мелкие шаги, где каждый шаг - это максимум,dt
который вы допускаете.Таким образом, с помощью этой стратегии вы можете просто приспособиться
timeStep
к любой точности воспроизведения (сделать ее секундой, минутой, часом или чем угодно, чтобы получить точное представление о физике).источник
В большинстве игр, как правило, используется простой метод прямого интегрирования Эйлера (то есть, интегрировать скорость в позицию во времени и интегрировать ускорение в скорость). К сожалению, метод Эйлера подходит только для очень маленьких временных масштабов и коротких периодов.
Существуют более сложные методы, которые более точны в течение очень длительного периода времени. Возможно, самым популярным и простым в реализации является Runge-Kutte-4 . RK4 определяет позицию в будущем, отбирая четыре позиции и скорости в прошлом и интерполируя. Он имеет тенденцию быть намного более точным, чем метод Эйлера, в более длительных временных масштабах, но является более дорогостоящим в вычислительном отношении.
Например, если вы хотите вычислить физику реальной орбитальной планеты, обновляемой каждые несколько дней в режиме реального времени, метод Эйлера заставит планету взлететь в космос после нескольких орбит из-за числовых ошибок. RK4, как правило, будет сохранять орбиту планеты примерно в одной и той же форме много тысяч раз, прежде чем накапливать слишком много ошибок.
Однако реализация коллизий в RK4 может быть очень сложной ...
источник