【问题标题】:NSV, Euler Integration ConfusionNSV,欧拉积分混淆
【发布时间】:2011-06-22 20:19:40
【问题描述】:

我正在努力理解这些集成方法,但我完全糊涂了。

代码如下:

public void update_euler(float timeDelta){
    vPos.y += vVelocity.y * timeDelta; 
    vVelocity.y += gravity.y * timeDelta;
}


public void update_nsv(float timeDelta){    
    vVelocity.y += gravity.y*timeDelta;
    vPos.y += vVelocity.y * timeDelta; 
}


public void onDrawFrame(GL10 gl) {      
    currentTime = System.currentTimeMillis();
    float timeDelta = currentTime - startTime;
    startTime = currentTime;
    timeDelta *= 1.0f/1000;;

//  update_RK4(timeDelta);
//  update_nsv(timeDelta);
//  update_euler(timeDelta);
//  update_velocity_verlet(timeDelta);
}

首先,我只是想确保我做对了这些。

我正在模拟一个完全弹性的球弹跳,所以在弹跳时我只是反转速度。

欧拉方法,球每次反弹时反弹得更高。这是由于我的代码中的错误还是由于方法的不准确。我读过欧拉积分你会随着时间的推移失去能量。好吧,我正在获得它,但我不知道为什么。

nsv 方法:我不太明白这与 Eular 方法有何不同,但无论如何,球在每次反弹时反弹得更低。它正在失去能量,我读过这并不意味着 nsv 方法会发生这种情况。为什么我会失去能量?

(velocity verlet 和 RK4 方法按我的预期工作)。

我觉得我缺乏关于这个主题的基本信息,但我不知道是什么。

我确实意识到我的时间步长不足,更新它以使用静态时间步长运行物理会阻止我失去/获得能量,但我试图了解发生了什么。

任何帮助将不胜感激。

【问题讨论】:

    标签: math language-agnostic physics game-physics


    【解决方案1】:

    要为@Beta 的答案添加另一个选项,如果您平均这两种方法,您的错误应该会消失(除了处理实际反弹的问题)。

    public void update_avg(float timeDelta){    
        vVelocity.y += gravity.y*timeDelta/2;
        vPos.y += vVelocity.y * timeDelta; 
        vVelocity.y += gravity.y*timeDelta/2;
    }
    

    我在这里所做的是将速度更新为间隔内的平均速度,然后根据该速度更新位置,然后将速度更新为间隔结束时的速度。

    如果您要建模更复杂的场景,请考虑使用Runge-Kutta Method 求解y' = f(x, y) 形式的微分方程。 (请注意,这里y 可以是一组不同的变量。所以在你的情况下,你会有d(position, velocity)/dt = (velocity, -gravity)。我给你的代码与该方法的二阶版本相同。

    【讨论】:

    • 这实际上相当于将timeDelta除以2,并交替使用欧拉和nsv。
    • @Beta:是的。但是通过数学计算,结果与 2 级的 Runge-Kutta 相同。
    • 想一想,这也是精确解:dx = vt + at^2/2
    • @Beta:这就是我说错误应该消失的原因。 :-) 但是,将值投影到区间的一半,然后使用它来更新整个区间的所有内容的想法是 2 次的 Runge-Kutta。如果解决方案是二次多项式(在这种情况下),那么将导致找到确切的答案。否则你的错误将是O(h**3)
    【解决方案2】:

    在现实生活中,球向上运动并减速,到达顶点(远地点),其速度瞬间为零,然后向下运动并加速。在任何时间间隔内,它都在与势能(高)交换动能(快)。

    在欧拉方法中,它在区间内以恒定速度移动,然后在区间结束时突然改变其速度。因此,在向上的旅程中,它以高速上升,然后减速,获得的高度超出了应有的高度。在向下的那条腿上,它缓慢地向下爬行,几乎没有失去高度,然后加速。

    在 nsv 方法中,情况正好相反:在上升过程中它“过早”失去速度并且不会变得非常高,在下降过程中它匆忙到达地面而没有增加太多速度。

    这两种方法的极限相同,timeDelta 归零。 (如果该声明没有意义,请不要担心,这只是微积分。)如果您将timeDelta 设为小,效果应该会消失。或者您可以使用能量作为主要变量,而不是 {position, velocity},但数学会稍微复杂一些。

    【讨论】:

      【解决方案3】:

      集成将人工阻尼引入系统。我相信你可以通过对积分方案进行傅里叶分析来确定多少,但我必须在细节上刷新我的记忆。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-29
        相关资源
        最近更新 更多