首页 > 解决方案 > 如何使用中点法对粒子进行积分

问题描述

我正在使用 Euler 方法在物理引擎中对粒子进行数值积分。

float inverseMass;
Vector3 position, velocity;
Vector3 sumForces, gravity, inputForce;
void Particle::Integrate(float dt) {
   sumForces = (gravity+inputForce)*dt;
   Vector3 a = sumForces*inverseMass;
   velocity += a;
   position += velocity*dt;
}

我想用 Midpoint 方法实现一个更好的积分器。基于本课程https://www.cs.cmu.edu/~baraff/pbm/constraints.pdf,使用中点法,您采取完整的欧拉步骤,然后在中点评估粒子上的力,然后迈出一步使用该中点值。

在此处输入图像描述

我实施了第一步。

void Particle::Integrate(float dt) {
   //Take full Euler step
   Vector3 sumForces = (gravity+inputForce)*dt;
   Vector3 a = sumForces*inverseMass;
   Vector3 tempVelocity = a+velocity;
   Vector3 deltaX += tempVelocity*dt;

   Vector3 midpoint = deltaX + position;

}

我该如何从这里继续?如何计算中点的力?我只是在半时间步计算它,但是计算中点位置的目的是什么?

标签: c++integrationnumerical-methodsphysics-engine

解决方案


您必须考虑您的状态包含两个主要成分,位置 x 和速度 v。该方法必须针对完整状态统一制定,

dx1 = v*dt,           dv1 = acc(t,x,v)*dt
dx2 = (v+0.5*dv1)*dt, dv2 = acc(t+0.5*dt, x+0.5*dx1, v+0.5*dv1)*dt

x = x + dx2,          v = v+dv2.

写下第一性原理的公式后,您现在可以看到消除dx向量相对容易。因此仍有待计算

dv1 = acc(t,x,v)*dt,
dv2 = acc(t+0.5*dt, x+0.5*v*dt, v+0.5*dv1)*dt,
x = x + (v+0.5*dv1)*dt,
v = v + dv2

推荐阅读