переменный временной шаг и ускорение - PullRequest
3 голосов
/ 16 января 2011

Чтобы переместить объекты с переменным шагом по времени, я просто должен сделать:

ship.position += ship.velocity * deltaTime;

Но когда я пытаюсь это сделать с помощью:

ship.velocity += ship.power * deltaTime;

, я получаю разные результаты с разными временными шагами,Как я могу это исправить?

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

Я моделирую объект, падающий на землю на одной оси с единственной фиксированной силой (гравитацией), действующей на него.

Ответы [ 6 ]

8 голосов
/ 16 января 2011
ship.position = ship.position + ship.velocity * deltaTime + 0.5 * ship.power * deltaTime ^ 2;
ship.velocity += ship.power * deltaTime;

http://www.ugrad.math.ubc.ca/coursedoc/math101/notes/applications/velocity.html

Скоростная часть ваших уравнений верна, и они должны обновляться на каждом временном шаге.

Все это предполагает, что у вас есть постоянная мощность (ускорение) в течение deltaTime, как указано Велисарием.

4 голосов
/ 16 января 2011

То, что вы делаете (математически), это оценка интегралов. В первом случае линейное приближение является точным, поскольку у вас есть линейная зависимость.

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

Редактировать

Ответ Брайана верен, пока сила корабля остается постоянной, а вы перерасчитываете скорость корабля на каждом шаге Это действительно интегральное уравнение для постоянного ускоренного движения.

1 голос
/ 16 января 2011

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

1 голос
/ 16 января 2011

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

0 голосов
/ 18 января 2011

В своем коде вы используете setInterval (moveBoxes, 20) для обновления блоков, а затем используете (new Date ()). GetTime ()) для вычисления deltaT. Это несколько избыточно, потому что вы могли бы использовать число 20 для прямого вычисления deltaT.

Лучше написать код, чтобы вы использовали одно и то же значение для deltaT на каждом временном шаге. (Другими словами, deltaT не должен зависеть от значения (new Date ()). GetTime ())). Таким образом, ваш код становится воспроизводимым, и вам легче писать модульные тесты.

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

Кстати. Я думаю, что следующий код

if(box.x < 0) {
        box.x = 0;
        box.vx *= -1;
    }

Может быть заменено на

if(box.x < 0) {
        box.x *= -1 ;
        box.vx *= -1;
    }

Удачи в проекте - и, пожалуйста, включите примеры кода в первую версию вашего вопроса, когда вы в следующий раз зададите: -)

0 голосов
/ 16 января 2011

Вы можете использовать Интеграция Verlet для расчета положения и скорости объекта. Ускорение можно рассчитать по a = m * F, где m - масса, а F - сила. Это один из самых простых алгоритмов

...