什么是一个物理引擎数值积分一些好的算法?

问题描述 投票:1回答:2

我一直在四处寻找在线,而现在整合了物理引擎,我想为乐趣代码的方法(爱是爱那里的nerdiness:P)。我发现欧拉法,RK4,并verlet的(以及时更正的版本)。我也一直在努力想出一些我自己的方法。如果你知道,你发现直觉或有帮助的任何其他的我不知道。谢谢。

编辑:感谢所有的帮助至今。至于澄清:也许我的意思是数值积分。出人意料的是,在我的研究,我还没有发现这么多的技术名称为我所试图做的!也许我的描述具体的问题将会使我的问题更加清晰。可以说,我想模拟一个球,通过一个圆形移动(或球形一次我实现了3D)的引力场。这个球会遇到可以用来计算点a对应的加速度矢量的球在该特定蜱力矢量。从你的物理课上,你知道,速度=加速度*时间,但我的问题是,球在技术上是上点只是瞬间,由DT演算数学上表示。很显然,我也不会在C使用一个无穷小的数目++,所以我必须近似使用瞬时整合的方法解决方案(一个学期,我在一些阅读听到,但我可能是完全错误的)或你认为什么是所谓的数值积分(你很可能右,所以我改了称呼)。

这是在实施数值积分的欧拉法我的(成功的)尝试:

    //For console output. Note: I know I could just put "using namespace std;" but I hate doing that.
    #include <iostream>
    using std::cout;
    using std::system;
    using std::endl;

    //Program entry
    int main (void)
    {
        //Variable decleration;
        double time = 0;
        double position = 0;
        double velocity = 0;
        double acceleration = 2;
        double dt = 0.000001; //Here is the "instantanious" change in time I was talking about.
        double count = 0; //I use count to make sure I am only displaying the data at whole numbers.

        //Each irritation of this loop is one tick
        while (true)
        {

            //This next bit is a simplified form of Euler's method. It is what I want to "upgrade"
            velocity += acceleration * dt;
            position += velocity * dt;

            if (count == 1/dt) //"count == 1/dt" will only return true if time is a whole number.
            {

                //Simple output to console
                cout << "Time: " << time << endl;
                cout << "Position: " << position << endl;
                cout << "------------------" << endl;
                system ("pause");

                count = 0; //To reset the counter.

            }

            //Update the counters "count" and "time"
            count++;
            time += dt;

        }
        return 1; //Program exit
    }

因为加速度是恒定的,这种差异实际上是可解(为什么我用它来测试,解决的办法是位置=时间^ 2,这是相当准确的,但如果你把它更多的是有点复杂,例如,使得加速随着时间的变化,该算法失去精确度也非常迅速。再次感谢!

c++ physics-engine
2个回答
2
投票

你有一个二阶微分方程(ODE)X ''= F(X,X”,T)。 x可以是一个矢量,并且x”和x‘’分别是第一和相对于所述时间的二阶导数。在你的情况,x是位置,X”是速度和X‘’是加速度。一般一个通过引入X = X变换这个二阶ODE成第一ODE,Y = x”和你获得

X '= Y Y'= F(X,Y)

然后你可以使用传统的方案解决像龙格 - 库塔,Dormand王子,亚当斯Bashforth常微分方程,...

许多这些方法在odeint这是相当好用实施。


1
投票

有用于数值积分,常微分方程许多不同的算法。见this Wikipedia article的概述。哪些算法适用于ODE你正在试图解决的性质强烈依赖。欧拉方法很少表现良好,在你经常需要一个非常小的步长,实现了很好的近似解(但这是很容易实现,所以可能是很好的第一次尝试)。有喜欢的后退欧拉方法的变化,这可以做的更好一点。

所述Runge-Kutta methods是一大类的方法,该方法包括欧拉方法。当你增加了该方法的顺序,你通常需要较少的时间步骤来实现相同的精度,但在每个时间段进行计算变得越来越昂贵 - RK4的使用非常普遍,因为它往往取得一个良好的平衡。

在实践中,adaptive step size技术通常用来控制时间步骤以实现期望的精度。

有ODE求解器,里面的人都投入了大量的工作中的许多现有实现 - 而这是件好事,你有兴趣知道他们是如何工作的,这些求解可以得到相当复杂,所以如果你不满意结果你从你自己的努力得到的,它可能是一个更好的主意,看看现有的程序,如those in the GNU Scientific Library.

© www.soinside.com 2019 - 2024. All rights reserved.