Равноускоренное движение и дискретизация по dt
Когда есть постоянное ускорение, появляется квадрат времени — и первая расплата за дискретность.
Равноускоренное движение — движение с постоянным ускорением $a$, при котором скорость растёт линейно, а координата — квадратично по времени.
Точная формула
Если ускорение $a$ постоянно, то скорость в любой момент равна $v = v_0 + a t$, а координата описывается классической формулой кинематики:
$$x = x_0 + v_0 t + \frac{a t^2}{2}.$$
Эта формула — точное решение: она получается интегрированием постоянного ускорения дважды. Член $\frac{a t^2}{2}$ — это «накопленный вклад» растущей скорости. Именно из-за него падающий камень за вторую секунду пролетает больше, чем за первую. Свободное падение — частный случай: $a = g \approx 9.8$ м/с².
Та же задача по шагам
Теперь смоделируем падение из покоя ($v_0 = 0$, $x_0 = 0$) пошагово и сравним с точным $x = \frac{g t^2}{2}$. Возьмём $g = 9.8$ и шаг $\Delta t = 0.1$.
g = 9.8
x = 0.0
v = 0.0
dt = 0.1
for n in range(5):
x = x + v * dt # сначала двигаем по старой скорости
v = v + g * dt # потом обновляем скорость
t = (n + 1) * dt
exact = g * t * t / 2
print(f"t={t:.1f} sim={x:.3f} exact={exact:.3f}")
Вывод:
t=0.1 sim=0.000 exact=0.049 t=0.2 sim=0.098 exact=0.196 t=0.3 sim=0.294 exact=0.441 t=0.4 sim=0.588 exact=0.784 t=0.5 sim=0.980 exact=1.225
Симуляция систематически отстаёт от точного значения. К моменту $t = 0.5$ с накопилась заметная разница: $0.98$ против $1.225$. Это не ошибка в коде — это ошибка дискретизации. Мы на каждом шаге двигали тело по скорости, которая была в начале шага, хотя на самом деле она внутри шага росла.
Откуда берётся отставание
В нашем порядке («сначала $x$, потом $v$») координата всегда использует устаревшую, заниженную скорость. Аналитически за первый шаг тело должно пройти $\frac{g \Delta t^2}{2} = 0.049$ м, а наш код выдал $0$, потому что в начале скорость была нулевой. Каждый шаг добавляет систематическую недостачу, и они копятся.
Уменьшим шаг — ошибка уменьшится. Для явного метода Эйлера глобальная ошибка пропорциональна $\Delta t$: вдвое меньший шаг даёт примерно вдвое меньшую ошибку. Это «первый порядок точности». В следующем разделе мы увидим методы, где ошибка падает как $\Delta t^2$, и они куда выгоднее.
Как работает под капотом
Точное решение можно представить как сумму бесконечного числа бесконечно малых вкладов — интеграл. Симуляция заменяет интеграл конечной суммой прямоугольников (это и есть метод Эйлера). Прямоугольник, построенный по левому краю интервала, недооценивает площадь под растущей функцией скорости — отсюда отставание. Если бы мы строили прямоугольник по правому краю (обновляли $v$ до сдвига $x$), то, наоборот, обгоняли бы точное решение. Истина лежит посередине, и хорошие методы это используют.
Полезный приём для проверки кода: если у задачи есть аналитическое решение, всегда сравнивайте с ним. Расхождение, которое уменьшается при уменьшении $\Delta t$, — это нормальная ошибка дискретизации. Расхождение, которое не уменьшается, — это баг.
Частые ошибки
- Считать отставание багом. Это закономерное свойство метода Эйлера, а не опечатка.
- Сравнивать с точным решением там, где его нет. Формула $x_0+v_0t+\frac{at^2}{2}$ верна только при постоянном $a$. Как только сила зависит от положения (пружина, гравитация), точной формулы такого вида уже нет — остаётся численное решение.
- Путать порядок обновления. «Сначала $x$, потом $v$» и «сначала $v$, потом $x$» дают разные интеграторы с разными свойствами — об этом весь следующий раздел.
Итог
- При постоянном $a$ точное решение: $x = x_0 + v_0 t + \frac{a t^2}{2}$.
- Пошаговая симуляция отстаёт — это ошибка дискретизации, не баг.
- Для явного Эйлера ошибка пропорциональна $\Delta t$ (первый порядок).
- Сравнение с аналитикой — лучший способ проверить корректность движка.