гравитационное моделирование - PullRequest
8 голосов
/ 10 августа 2011

Я хочу смоделировать свободное падение и столкновение с землей (например, прыгающий мяч). Объект упадет в вакууме - сопротивление воздуха можно опустить. Столкновение с землей должно привести к некоторой потере энергии, поэтому в конечном итоге объект перестанет двигаться. Я использую JOGL для рендеринга точки, которая является моим падающим объектом. Гравитация постоянна (-9,8 м / с ^ 2).

Я нашел метод Эйлера для расчета новой позиции точки:

deltaTime = currentTime - previousTime;
vel += acc * deltaTime;
pos += vel * deltaTime;

но я делаю что-то не так. Точка отскакивает несколько раз, а затем движется вниз (очень медленно).

Вот псевдокод (начальный pos = (0.0f, 2.0f, 0.0f), начальный vel (0.0f, 0.0f, 0.0f), гравитация = -9.8f):

display()
{
     calculateDeltaTime();
     velocity.y += gravity * deltaTime;
     pos.y += velocity.y * deltaTime;

     if(pos.y < -2.0f) //a collision with the ground
     {
        velocity.y = velocity.y * energyLoss * -1.0f;
     }

}

Как лучше всего добиться реалистичного эффекта? Как метод Эйлера относится к уравнениям постоянного ускорения?

Ответы [ 2 ]

6 голосов
/ 10 августа 2011

Поскольку числа с плавающей запятой плохо округляются, вы никогда не достигнете скорости, фактически равной 0. Вы, вероятно, получите что-то вроде -0,00000000000001 или что-то подобное.

вам нужно сделать его 0.0, когда оно будет достаточно близко. (определите некоторую дельту.)

2 голосов
/ 11 августа 2011

Чтобы расширить мой комментарий выше и ответить Тобиас , я добавлю полный ответ здесь.

При первоначальном осмотре я определил, что вы быстро снижаете скорость. Проще говоря, соотношение между кинетической энергией и скоростью составляет E = m v^2 /2, поэтому после взятия производной по скорости вы получите

delta_E = m v delta_v

Затем, в зависимости от того, как определено energyloss, вы можете установить отношения между delta_E и energyloss. Например, в большинстве случаев energyloss = delta_E/E_initial, указанное выше соотношение можно упростить до

delta_v = energyloss*v_initial / 2

Это предполагает, что временной интервал мал, что позволяет вам заменить v в первом уравнении на v_initial, так что вы сможете сойти с рук за то, что вы делаете. Чтобы было ясно, delta_v вычитается из velocity.y внутри вашего блока столкновений вместо того, что у вас есть.

Что касается вопроса о добавлении сопротивления воздуха или нет, ответ - это зависит. Для малых начальных высот падения это не имеет значения, но может начать иметь значение с меньшими потерями энергии из-за отказов и более высоких точек падения. Для гладкой сферы диаметром 1 грамм 1 дюйм (2,54 см) я нанес разницу во времени между трением воздуха и без него в зависимости от высоты падения:

difference in time with and without air-drag vs. drop height

Для материалов с низкими потерями энергии (80-90+% удерживаемой энергии), я бы подумал добавить их для высоты падения 10 метров и выше. Но если бы капли были ниже 2-3 метров, я бы не стал беспокоиться.

Если кому-то понадобятся расчеты, я поделюсь ими.

...