Простая физика Эйлера, странное поведение - PullRequest
0 голосов
/ 18 июля 2011

У меня есть этот простой интегратор Эйлера.Для нахождения точного времени столкновения он также должен обрабатывать отрицательные значения dt (я делю время кадра и симулирую обратно при обнаружении столкновения).

По некоторым причинам

someBody.update(1.0);
someBody.update(-0.3);
someBody.update(-0.3);
someBody.update(0.6);

дает результаты, отличные от:

someBody.update(1.0);

Это может быть потому, что я использую эйлер вместо RK4 или verlet?

Вот код для интегратора:

void Body::update(double dt)
{
    if (dt > 0) velocity += acceleration * (dt*dt);
    else velocity -= acceleration * (dt*dt);
    pos += velocity * dt;
    rotation += angularVelocity * dt;
}

Большое спасибо!

Maarten

Ответы [ 3 ]

3 голосов
/ 18 июля 2011

Причина в математике. Давайте сосредоточимся на velocity переменной:

Если вы позвоните:

someBody.update(1.0)

вы получите:

velocity += acceleration * 1

Но если вы позвоните:

someBody.update(1.0);
someBody.update(-0.3);
someBody.update(-0.3);
someBody.update(0.6);

вы получите:

velocity += acceleration * (1 - 0.3^2 - 0.32^2 + 0.6^2)

(что дает velocity += acceleration * 1.18)

Вы должны иметь просто velocity += acceleration * dt;

0 голосов
/ 20 июля 2011

Спасибо, ускорение было действительно неправильным.

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

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

Хотя я думаю, что эти ошибки не будут так сильно складываться.Приблизительно в 50 кадрах прыгающий объект поднимается со своей полной высоты (100) примерно до половины этой высоты.Приблизительно в 200 кадрах это все еще на полу.Когда я не вызываю несколько обновлений в кадре, все нормально.

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

0 голосов
/ 18 июля 2011

Возможно накопление ошибок с плавающей точкой в ​​Body :: update.Пример: 1 + 2 + 3 + 4 = 10, но 1.0 + 2.0 + 3.0 + 4.0 = что-то еще.

Самое простое решение - округлить результаты после каждого основного шага вычисления.

...