Runge-Kutta(RK4)集成了游戏物理

时间:2009-11-03 15:37:02

标签: math integration physics

Gaffer on Games有great article关于使用RK4 integration更好的游戏物理。实现很简单,但背后的数学让我感到困惑。我从概念层面理解衍生物和积分,但很长一段时间没有操纵方程式。

这是Gaffer实施的主要内容:

void integrate(State &state, float t, float dt)
{
     Derivative a = evaluate(state, t, 0.0f, Derivative());
     Derivative b = evaluate(state, t+dt*0.5f, dt*0.5f, a);
     Derivative c = evaluate(state, t+dt*0.5f, dt*0.5f, b);
     Derivative d = evaluate(state, t+dt, dt, c);

     const float dxdt = 1.0f/6.0f * (a.dx + 2.0f*(b.dx + c.dx) + d.dx);
     const float dvdt = 1.0f/6.0f * (a.dv + 2.0f*(b.dv + c.dv) + d.dv)

     state.x = state.x + dxdt * dt;
     state.v = state.v + dvdt * dt;
}

任何人都能用简单的语言解释RK4的工作原理吗?具体来说,为什么我们在0.0f0.5f0.5f1.0f?对衍生工具求平均值。如何将平均导数推广到第4阶不同于进行简单的euler积分一个较小的时间步长?


在阅读下面接受的答案和其他几篇文章后,我掌握了RK4的工作原理。回答我自己的问题:

任何人都可以用简单的语言解释RK4的工作原理吗?

  

RK4充分利用了这一事实   我们可以得到更好的近似值   如果我们使用它的功能   高阶导数而不是   只是一阶或二阶导数。   这就是Taylor series的原因   收敛比欧拉快得多   近似。 (看看   动画在右侧   页)

具体来说,为什么我们在0.0f0.5f0.5f1.0f平均衍生品?

  

Runge-Kutta方法是一个   近似函数   样品衍生物有几点   在一个时间步之内,不像泰勒   系列只采样衍生物   单点。取样后   这些衍生品我们需要知道如何   称重每个样品得到   最接近的可能。一个   这样做的简单方法就是选择   与...重合的常数   泰勒系列,这是怎么回事   Runge-Kutta方程的常数   确定了。

     

This article让它更加清晰   我。请注意(15)是怎样的泰勒   系列扩展而(17)是   Runge-Kutta推导。

如果将衍生物平均到4阶不同于如何使用较小的时间步长进行简单的euler积分?

  

数学上,它收敛很多   比做许多欧拉更快   近似。当然,够了   欧拉近似我们可以获得平等   精度为RK4,但计算结果   所需的电力并不合理   欧拉。

3 个答案:

答案 0 :(得分:33)

就实际数学而言,这可能有点过于简单,但它是Runge Kutta整合的直观指南。

在某个时间t1给出一些数量,我们想知道另一个时间t2的数量。使用一阶微分方程,我们可以知道t1处该数量的变化率。我们无从谈及其他任何事情;剩下的就是猜测。

Euler积分是最简单的猜测方法:使用t1处精确已知的变化率,从t1线性推断到t2。这通常会给出错误的答案。如果t2远离t1,则此线性外推将无法匹配理想答案中的任何曲率。如果我们从t1到t2采取许多小步骤,我们就会遇到减去相似值的问题。舍入错误将破坏结果。

所以我们改进了猜测。一种方法是继续进行线性外推,然后希望它与真理不太相似,使用微分方程计算t2处的变化率估计值。这与t1处的(准确)变化率平均,更好地表示t1t2之间的真实答案的典型斜率。我们使用它来进行从t1t2的新线性外推。我们不应该采用简单的平均值,或者在t1给予更多权重,而不用数学来估计误差,但这里有一个选择。无论如何,这是比欧拉给出的更好的答案。

或许更好,将我们的初始线性外推到t1t2之间的某个时间点,并使用微分方程计算那里的变化率。这给出了与刚才描述的平均值大致相同的答案。然后使用它进行从t1t2的线性推断,因为我们的目的是在t2找到数量。这是中点算法。

您可以想象使用变化率的中点估计来对t1到中点的数量进行另一次线性推断。通过微分方程,我们可以更好地估计那里的斜率。使用此功能,我们将从t1一直推断到我们想要答案的t2。这是Runge Kutta算法。

我们可以对中点进行第三次推断吗?当然,这不是非法的,但详细的分析表明改进正在减少,因此其他错误来源主导了最终结果。

Runge Kutta将微分方程应用于初始点t1,两次应用于中点,一次应用于最终点t2。中间点是一个选择问题。可以使用t1t2之间的其他点来进行斜率的改进估计。例如,我们可以使用t1,这是指向t2的三分之一,另一个是t2的两分之二,以及t2。四种衍生物的平均权重将不同。在实践中,这并没有真正的帮助,但可能在测试中占有一席之地,因为它应该给出相同的答案,但会提供一组不同的舍入错误。

答案 1 :(得分:2)

关于你的问题为什么:我记得曾经写过一个布料模拟器,其中布是一系列在节点处相互连接的弹簧。在模拟器中,弹簧施加的力与弹簧拉伸的距离成比例。该力导致节点处的加速度,这导致移动节点的速度,该节点拉伸弹簧。有两个积分(积分加速度来获得速度,积分速度来获得位置)如果它们不准确,则错误滚雪球:太多的加速度会导致太大的速度导致过多的拉伸,从而导致更多的加速度,使得整个系统不稳定。

没有图形很难解释,但我会尝试:假设你有f(t),其中f(0)= 10,f(1)= 20,f(2)= 30。

f(t)在0 <0的区间内的适当积分。 t&lt; 1会在这段时间内给出f(t)图下的曲面。

矩形规则积分近似于具有矩形的表面,其中宽度是时间上的Δ,并且长度是f(t)的新值,因此在区间0&lt; t&lt; 1,它将产生20 * 1 = 20,并在下一个间隔1

现在,如果您要绘制这些点并在其中绘制一条线,您将看到它实际上是三角形,表面为30(单位),因此Euler积分不足。

为了更准确地估计表面(积分),可以采用较小的t间隔,例如在f(0),f(0.5),f(1),f(1.5)和f(2)处进行评估)。

如果您仍然关注我,那么RK4方法就是估算t0

(但正如其他人所说,请阅读维基百科文章以获得更详细的解释.RK4属于numerical integration

答案 2 :(得分:2)

RK4在最简单的意义上是制作一个近似函数,它基于4个导数并指向每个时间步长:您在起始点A的初始条件,基于您时间步骤的数据点A的第一个近似斜率B / 2和A的斜率,第三个近似值C,它具有B处斜率的校正值,以反映函数的形状变化,最后是基于C点校正斜率的最终斜率。

因此,基本上这种方法可以让你使用一个起点,一个平均中点进行计算,该中点在两个部分内置校正以调整形状,以及一个双重校正的终点。这使得每个数据点的有效贡献为1/6 1/3 1/3和1/6,因此大部分答案都是基于对函数形状的校正。

事实证明,RK近似的顺序(Euler被认为是RK1)对应于其精度如何随着较小的时间步长而缩放。

RK1近似值之间的关系是线性的,因此精度的10倍可以获得大约10倍的收敛效果。

对于RK4,精度的10倍可以使收敛效率提高10 ^ 4倍。因此,当您的计算时间在RK4中线性增加时,它会以多项式增加您的精度。