物理引擎的数值积分有哪些好算法
What are some good algorithms for numerical integration for a physics engine?
我已经在网上寻找了一段时间的物理引擎的集成方法,我正试图为一个有趣的代码编写(一定喜欢那里的书呆子气:p)。我找到了欧拉方法、RK4和Verlet(以及时间校正版本)。我也一直在尝试想出一些自己的方法。我想知道你是否知道其他你觉得直观或有用的东西。谢谢
编辑:谢谢你到目前为止的帮助。至于澄清:也许我的意思是数字积分。令人惊讶的是,在我所有的研究中,我还没有找到我想要做的事情的技术名称!也许描述我的具体问题会让我的问题更清楚。比方说,我想模拟一个球在圆形(或球形)引力场中移动。该球将遇到力矢量,该力矢量可用于计算球在特定刻度上所处点的相应加速度矢量。从你的物理课上,你知道速度=加速度*时间,但我的问题是,从技术上讲,球在那个点上只停留了一瞬间,在微积分中用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,这是相当准确的,但如果你让它变得更复杂,例如,使加速度随时间变化,算法会非常快地失去准确性。再次感谢!
您有一个二阶微分方程(ODE)x''=f(x,x',t)。x可以是一个向量,x’和x’’是相对于时间的一阶导数和二阶导数。在你的例子中,x是位置,x是速度,x是加速度。通常,通过引入X=X,Y=X',可以将二阶ODE转换为一阶ODE,从而获得
X'=YY'=f(X,Y)
然后你可以使用经典的方案来求解常微分方程,如Runge Kutta,Dormand Prince,Adams Bashforth。。。
其中许多方法都是在odeint中实现的,这很容易使用。
对常微分方程进行数值积分有许多不同的算法。请参阅维基百科上的这篇文章以获得概述。哪种算法是合适的在很大程度上取决于您试图解决的ODE的属性。Euler方法很少表现得很好,因为你通常需要一个很小的步长来实现对解决方案的良好近似(但这很容易实现,所以第一次尝试可能很好)。还有一些变体,比如向后的欧拉方法,可以做得更好一点。
龙格-库塔方法是一类广泛的方法,其中包括欧拉方法。随着方法阶数的增加,通常需要更少的时间步长才能达到相同的精度,但在每个时间步长执行计算变得越来越昂贵-RK4经常使用,因为它往往能达到良好的平衡。
在实践中,自适应步长技术通常用于控制时间步长以实现期望的精度。
ODE解算器有很多现有的实现,人们对此做了大量的工作-虽然你有兴趣了解它们是如何工作的是件好事,但这些解算器可能会变得非常复杂,所以如果你对自己的尝试结果不满意,那么最好研究现有的例程,比如GNU科学库中的例程。
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- 没有额外参数的函数的 GSL 数值积分
- 传递通用函数,用于梯形规则的数值积分
- gsl多变量数值积分
- 使用模块化算法将积分器转换为数组时出现问题
- 计算C 中的数值积分
- 为什么 STL 数值算法使用 'op' 而不是 'op='?
- 轮廓积分C++算法
- 确定给定数字 N 是否可以成为具有所有 3 个积分边的直角三角形的斜边的算法
- 数值积分:使模板函数只接受函数名或使用两个参数调用的函数
- lambda函数与gsl的数值积分
- 物理引擎的数值积分有哪些好算法
- 用c++在给定网格上进行数值积分,离散化为固定常数
- 梯形规则的数值积分c++
- 如何在R中使用Rcpp在c++中做数值积分
- 检验算法中的数值精度
- 计算乘数和除数值的优化算法