pla*_*cel 5 math numerical-methods numerical-integration game-physics verlet-integration
Johnathan Dummer在网上有一个常用的verlet-integration公式,叫做Time-Corrected Verlet.但是我已经阅读了几个论坛帖子,人们在某些条件下会得到奇怪或意想不到的结果.
x1 = x + (x – x0) * dt / dt0 + a * dt^2
Run Code Online (Sandbox Code Playgroud)
还有一个stackoverflow答案,它说明了Dummer的时间校正公式被打破了,并且海报将他自己的推导作为正确的推导.
x1 = x + (x – x0) * dt / dt0 + a * dt * (dt + dt0) / 2
Run Code Online (Sandbox Code Playgroud)
嗯,达默的公式真的坏了吗?如果是的话,海报的推导更好吗?
PS:Dummer x1 = x - x0 + a * dt^2
在他的网站上使用verlet集成公式而不是正确的,这也很奇怪x1 = 2x - x0 + a * dt^2
.
维基百科页面Verlet集成 - 非恒定时间差异表示两个公式,没有引用.我自己没有检查过这个推导,但第二个改进公式的推理看起来很合理.
我已经下载了Dummer的电子表格并修改了其中一个公式以使用更正.结果要好得多.
确切的结果是黄色的,我们看到只使用具有波动帧速率的普通Verlet算法是不好的.Dummer的时间正确的红色变量非常好,但有点偏.具有改进校正的深绿色版本要好得多.
对于具有二次解决方案的重力射弹,您可能会发现改进后的版本是精确的.当学位变得更高时,它将与真实路径不同,可能值得测试,看看我们是否仍然得到更好的近似值.
对sin曲线进行相同的计算表明改进的方法要好得多.时间正确的Verlet正在漂移很多.改进版本更好,只有一点点的确切答案.
对于PS.请注意,如果在TCV公式中设置dt = dt0
x1 = x + (x – x0) * dt / dt0 + a * dt^2
Run Code Online (Sandbox Code Playgroud)
你得到
x1 = x + x – x0 + a * dt^2
= 2 x – x0 + a * dt^2
Run Code Online (Sandbox Code Playgroud)
原始的Verlet公式.
真正的推导是基于泰勒公式
x(t-h0) = x(t) - x'(t)*h0 + 0.5*x''(t)*h0^2 + O(h0^3)
x(t+h1) = x(t) + x'(t)*h1 + 0.5*x''(t)*h1^2 + O(h1^3)
Run Code Online (Sandbox Code Playgroud)
现在x'(t)
从这两个公式中消除得到一个类似 Verlet 的公式
h0*x(t+h1) + h1*x(t-h0) = (h0+h1)*x(t) + 0.5*a(t)*h0*h1*(h0+h1) +O(h^3)
Run Code Online (Sandbox Code Playgroud)
这使得传播公式
x(t+h1) = (1+h1/h0)*x(t) - h1/h0*x(t-h0) + 0.5*a(t)*h1*(h0+h1)
= x(t) + (x(t)-x(t-h0))*h1/h0 + 0.5*a(t)*h1*(h0+h1)
Run Code Online (Sandbox Code Playgroud)
因此修正后的公式确实是正确的。
请注意,如果您使用速度 Verlet 步骤
Verlet(dt) {
v += a * 0.5*dt
x += v*dt
a = acceleration(x)
v += a * 0.5*dt
}
Run Code Online (Sandbox Code Playgroud)
那么每一步都是独立辛的,因此步之间步长的变化是绝对没有问题的。
请注意,Verlet 和其他类似的辛方案相对于 Runge-Kutta 方法等的主要优点关键取决于使用固定步骤。详细地说,在数值方法下基本恒定的修正能量函数(以及除运动的二次常数以外的其他常数)是对精确能量的修正,其中差值随步长缩放。因此,当改变步长时,不同的修改会给出恒定的能量。因此,步长的频繁变化允许能量水平的任意变化。