简单的物理为基础的运动 [英] Simple physics-based movement

查看:160
本文介绍了简单的物理为基础的运动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个2D游戏,我试图用一些基本的物理code加速的对象的最高速度。

下面是伪code吧:

 
常量浮点加速= 0.02f;
常量浮动摩擦= 0.8f; //值始终0.0..1.0
      浮动速度= 0;
      浮动位置= 0;

移动()
{
   速度+ =加速;
   速度* =摩擦;
   位置+ =速度;
}
 

这是一种不依赖于大规模的或实际的摩擦非常简单的方法(在 - code摩擦只是行动反对运动的通用力)。它的工作原理以及速度* =摩擦;部分保留从去过去的某一点的速度。然而,正是这种最高速度和它的加速度和摩擦的地方我有点失去了联系。

我想要做的是设置一个最高速度,而所需的时间才能实现它,然后用它们来获得加速和摩擦值。

即,

 
常量浮max_velocity = 2.0;
const int的蜱; = 120; //如果我的游戏运行在60 FPS,我想一个
                                //移动物体在达到max_velocity
                                //恰好2秒。
常量浮点加速=?
常量浮动摩擦=?
 

解决方案

重型EDITS

我觉得这个问题很有趣,因为我最近做了上拖造型抛运动的一些工作。

第一点:您使用的是明确基本更新位置和速度/前进欧拉迭代凡州每一个新的价值应该是旧值的函数。在这种情况下,你应该更新位置的第一的,然后更新速度。

第2点:还有更逼真的物理模型阻力摩擦的影响。一个模型(由亚当·利斯建议)涉及阻力正比于速度(被称为斯托克斯阻力,这一般适用于低速的情况下)。所述一个予previously建议涉及曳力成比例的速度(称为二次拖动,其通常适用于高速的情况下)的的。我将针对每一个关于你如何推导公式为最大速度,并有效地达到最大速度所需的时间。我放弃了完整的推导,因为它们是相当复杂的。


斯托克斯阻力:

方程式用于更新速度将是:

 速度+ =加速 - 摩擦*速度
 

这将重新presents以下微分方程:

 的dv / dt = A  -  F * V
 

使用这个积分表,我们就可以找到解决方案(假设v = 0在t = 0):

  V =(A / F) - (A / F)* EXP(-f * T)
 

的最大(即终端)的速度时发生吨>> 0,使得第二项在方程中是非常接近于零和

  v_max = A / F
 

对于达到最大速度所需的时间,请注意,方程从未真正地达到它,而是渐进线朝向它。然而,当指数的参数等于-5,速度为约98%的最大速度,可能是足够接近考虑相等。然后,您可以将时间逼近最大速度为:

  t_max = 5 /˚F
 

您就可以使用这两个方程组的求解对于 F 一个所希望的 VMAX TMAX


二次阻力:

方程式用于更新速度将是:

 速度+ =加速 - 摩擦*速度*速度
 

这将重新presents以下微分方程:

 的dv / dt = A  -  F * V ^ 2
 

使用这个积分表,我们就可以找到解决方案(假设v = 0在t = 0):

  V =的sqrt(A / F)*(EXP(2 * SQRT(A * F)* T) -  1)/(EXP(2 * SQRT(A * F) *吨)+1)
 

的最大(即终端)的速度时发生吨>> 0,因此,指数项比1大得多和式接近:

  v_max =开方(A / F)
 

对于达到最大速度所需的时间,请注意,方程从未真正地达到它,而是渐进线朝向它。然而,当指数的参数等于5,速度为99%左右,最大速度,可能是足够接近考虑相等。然后,您可以将时间逼近最大速度为:

  t_max = 2.5 / SQRT(A * F)
 

这也等价于:

  t_max = 2.5 /(F * v_max)
 

有关所需的 VMAX TMAX ,第二个公式 TMAX 会告诉你什么的 F 应,然后你就可以插上,在该方程的 VMAX 即可获得价值


这似乎有点大材小用,但这些其实都是一些模拟阻力最简单的方法!任何人谁的真正的希望看到的集成步骤可以拍我的电子邮件,我会送他们到你。他们是有点太参与在这里键入。

另一个点:我没有立刻意识到这一点,但速度的更新是没有必要了,如果你不是用我推导出的 V(t)的公式。如果你只是模拟从静止加速,并且要保持的时间轨迹,因为加速度开始了,code看起来是这样的:

 位置+ = velocity_function(timeSinceStart)
 

,其中velocity_function是两个公式的 V(T),你将不再需要的速度变量之一。在一般情况下,有一个权衡在这里:计算 V(T)可能会比简单的更新速度与迭代计划(由于指数计算)计算更昂贵,但它是保证维持稳定和有界的。在某些情况下(如试图获得一个很短的 TMAX ),迭代会变得不稳定,吹起来,一个共同的问题,向前欧拉方法。然而,维持对变量的数值范围(如0℃; F < 1),应prevent这些不稳定性

另外,如果你感觉有点自虐,您可以整合公式 V(T),以获得一个封闭的形式解决方案的 P(T),因而减少了需要进行牛顿迭代干脆。我将离开这个给别人尝试。 =)

I'm working on a 2D game where I'm trying to accelerate an object to a top speed using some basic physics code.

Here's the pseudocode for it:


const float acceleration = 0.02f;
const float friction     = 0.8f;  // value is always 0.0..1.0
      float velocity     = 0;
      float position     = 0;

move()
{
   velocity += acceleration;
   velocity *= friction;
   position += velocity;
}

This is a very simplified approach that doesn't rely on mass or actual friction (the in-code friction is just a generic force acting against movement). It works well as the "velocity *= friction;" part keeps the velocity from going past a certain point. However, it's this top speed and its relationship to the acceleration and friction where I'm a bit lost.

What I'd like to do is set a top speed, and the amount of time it takes to reach it, then use them to derive the acceleration and friction values.

i.e.,


const float max_velocity = 2.0; 
const int   ticks;       = 120; // If my game runs at 60 FPS, I'd like a 
                                // moving object to reach max_velocity in 
                                // exactly 2 seconds.
const float acceleration = ?
const float friction     = ?

解决方案

HEAVY EDITS

I found this question very interesting since I had recently done some work on modeling projectile motion with drag.

Point 1: You are essentially updating the position and velocity using an explicit/forward Euler iteration where each new value for the states should be a function of the old values. In such a case, you should be updating the position first, then updating the velocity.

Point 2: There are more realistic physics models for the effect of drag friction. One model (suggested by Adam Liss) involves a drag force that is proportional to the velocity (known as Stokes' drag, which generally applies to low velocity situations). The one I previously suggested involves a drag force that is proportional to the square of the velocity (known as quadratic drag, which generally applies to high velocity situations). I'll address each one with regard to how you would deduce formulas for the maximum velocity and the time required to effectively reach the maximum velocity. I'll forego the complete derivations since they are rather involved.


Stokes' drag:

The equation for updating the velocity would be:

velocity += acceleration - friction*velocity

which represents the following differential equation:

dv/dt = a - f*v

Using the first entry in this integral table, we can find the solution (assuming v = 0 at t = 0):

v = (a/f) - (a/f)*exp(-f*t)

The maximum (i.e. terminal) velocity occurs when t >> 0, so that the second term in the equation is very close to zero and:

v_max = a/f

Regarding the time needed to reach the maximum velocity, note that the equation never truly reaches it, but instead asymptotes towards it. However, when the argument of the exponential equals -5, the velocity is around 98% of the maximum velocity, probably close enough to consider it equal. You can then approximate the time to maximum velocity as:

t_max = 5/f

You can then use these two equations to solve for f and a given a desired vmax and tmax.


Quadratic drag:

The equation for updating the velocity would be:

velocity += acceleration - friction*velocity*velocity

which represents the following differential equation:

dv/dt = a - f*v^2

Using the first entry in this integral table, we can find the solution (assuming v = 0 at t = 0):

v = sqrt(a/f)*(exp(2*sqrt(a*f)*t) - 1)/(exp(2*sqrt(a*f)*t) + 1)

The maximum (i.e. terminal) velocity occurs when t >> 0, so that the exponential terms are much greater than 1 and the equation approaches:

v_max = sqrt(a/f)

Regarding the time needed to reach the maximum velocity, note that the equation never truly reaches it, but instead asymptotes towards it. However, when the argument of the exponential equals 5, the velocity is around 99% of the maximum velocity, probably close enough to consider it equal. You can then approximate the time to maximum velocity as:

t_max = 2.5/sqrt(a*f)

which is also equivalent to:

t_max = 2.5/(f*v_max)

For a desired vmax and tmax, the second equation for tmax will tell you what f should be, and then you can plug that in to the equation for vmax to get the value for a.


This seems like a bit of overkill, but these are actually some of the simplest ways to model drag! Anyone who really wants to see the integration steps can shoot me an email and I'll send them to you. They are a bit too involved to type here.

Another Point: I didn't immediately realize this, but the updating of the velocity is not necessary anymore if you instead use the formulas I derived for v(t). If you are simply modeling acceleration from rest, and you are keeping track of the time since the acceleration began, the code would look something like:

position += velocity_function(timeSinceStart)

where "velocity_function" is one of the two formulas for v(t) and you would no longer need a velocity variable. In general, there is a trade-off here: calculating v(t) may be more computationally expensive than simply updating velocity with an iterative scheme (due to the exponential terms), but it is guaranteed to remain stable and bounded. Under certain conditions (like trying to get a very short tmax), the iteration can become unstable and blow-up, a common problem with the forward Euler method. However, maintaining limits on the variables (like 0 < f < 1), should prevent these instabilities.

In addition, if you're feeling somewhat masochistic, you may be able to integrate the formula for v(t) to get a closed form solution for p(t), thus foregoing the need for a Newton iteration altogether. I'll leave this for others to attempt. =)

这篇关于简单的物理为基础的运动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆