Физическое моделирование дает (очень) неточные позиции для простого исчисления траекторий

Я хочу внедрить физический движок в игру, чтобы вычислять траектории тел с приложенными к ним силами.Этот механизм будет рассчитывать каждое состояние объекта на основе его предыдущего состояния.Конечно, это означает много вычислений между двумя единицами времени, чтобы быть достаточно точным.Чтобы сделать это правильно, я сначала хотел узнать, насколько велики различия между этим методом получения позиций и кинематическими уравнениями.Итак, я сделал этот код, который хранит позиции (x, y, z), заданные симуляциями и уравнениями в файле.Проблема в том, что с простыми числами (например, с простым падением гравитационного поля -9,81) я получил хорошие позиции, но с большими (и довольно случайными) числами я получаю неточные позиции.Это проблема с плавающей запятой?Вот результаты с относительными ошибками.(Примечание: оси меток на французском, Temps = Time).диаграммыЧерный + пунктир: значения из кинематических уравненийКрасный: 100 очков в секундуОранжевый: 1000 очков в секундуЗеленый: 10000 очков в секунду
4 голоса | спросил T0T0R 19 J000000Wednesday17 2017, 23:15:08

1 ответ


0
Это не проблема с плавающей запятой.На самом деле, даже если вы используете точную арифметику, вы увидите ту же проблему.Эта ошибка является фундаментальной для самой числовой интеграции, конкретного метода, который вы используете, и ODE, который вы решаете.В этом случае вы используете схему интеграции, известную как Форвард Эйлер.Это, вероятно, самый простой подход к решению ODE первого порядка.Конечно, это оставляет некоторые нежелательные черты.Для одного это вводит ошибку на каждом шаге.Размер ошибки: ---- +: = 0 =: + ---- .Это означает, что ошибка в течение одного временного шага примерно пропорциональна квадрату размера временного шага.Таким образом, если вы сократите размер временного шага пополам, примерно вы уменьшите инкрементную ошибку до 1/4 значения.Но так как вы уменьшаете шаг по времени, вы должны сделать больше шагов, чтобы смоделировать такое же количество времени.Таким образом, вы добавляете больше, но меньше ошибок.Вот почему накопленная ошибка ---- +: = 1 =: + ---- .Так что на самом деле в течение всего смоделированного времени, если вы сделаете временные шаги, которые в два раза меньше, вы получите половину кумулятивной ошибки.В конечном счете, эта кумулятивная ошибка - это то, что вы видите.И вы можете видеть на графике ошибок, что конечная ошибка уменьшается примерно в 10 раз каждый раз, когда вы увеличиваете количество временных шагов в 10 раз: потому что временной шаг в 10 раз меньше, поэтому общая ошибка заканчиваетсяпримерно в 10 раз меньше.Другая проблема заключается в том, что Форвард Эйлер демонстрирует так называемую условную устойчивость.Это означает, что накопленная ошибка может расти без ограничений в определенных случаях.Чтобы понять почему, давайте посмотрим на простой ODE:Где k некоторая постоянная.Точное решение этого ODE: ---- +: = 3 =: + ---- .Так что, пока k положительно, ---- +: = 4 =: + ---- должно стремиться к ---- +: = 5 =: + ---- с увеличением времени.Однако, если мы попытаемся приблизить это с помощью Форвард Эйлера, мы получим что-то похожее на это:Это простое рекуррентное отношение, которое мы можем решить:Теперь мы знаем точное решение от десятков до 0, так как ---- +: = 8 =: + ---- становится больше.Но прямое решение Эйлера делает это, только если ---- +: = 9 =: + ---- .Обратите внимание, что это выражение зависит от размера шага, а также от условия ---- +: = 10 =: + ---- из нашего ODE.Если ---- +: = 11 =: + ---- действительно очень большой, нам нужен действительно очень маленький временной шаг, чтобы не допустить взрыва решения.Вот почему он обладает так называемой условной стабильностью: стабильность решения зависит от временного шага.Есть также ряд других вопросов, но это широкая тема, и я не могу охватить все в одном ответе.
ответил Kyle 20 J000000Thursday17 2017, 00:16:53

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132