控制加速度直到达到位置的算法

Dam*_*ian 9 algorithm math physics

我有一个移动点(在一个维度上),我需要它顺利移动.所以我认为它的速度必须是一个连续的函数,我需要控制加速度然后计算它的速度和位置.

该算法对我来说似乎并不明显,但我想这一定是一个常见问题,我只是找不到解决方案.

笔记:

  • 物体的最终目的地可能会在移动时发生变化,无论如何移动都需要平滑.
  • 我想一个天真的实现会产生弹跳,我需要避免这种情况.

Ale*_*eem 26

这是使用"临界阻尼弹簧"的完美候选者.

从概念上讲,您可以使用弹簧或弹性片将点连接到目标点.弹簧受到阻尼,因此你没有"弹跳".您可以通过更改名为"SpringConstant"的常量来控制系统响应的速度.这基本上是弹性片的强度.

基本上你将两个力量施加到该位置,然后随着时间的推移将其整合.第一个力是弹簧施加的力,Fs = SpringConstant*DistanceToTarget.第二个是阻尼力,Fd = -CurrentVelocity*2*sqrt(SpringConstant).

CurrentVelocity构成系统状态的一部分,可以初始化为零.

在每个步骤中,您将这两个力的总和乘以时间步长.这使您可以更改CurrentVelocity的值.再将它乘以时间步长,它将为您提供位移.

我们将其添加到该点的实际位置.

在C++代码中:

float CriticallyDampedSpring( float a_Target,
                              float a_Current,
                              float & a_Velocity,
                              float a_TimeStep )
{
    float currentToTarget = a_Target - a_Current;
    float springForce = currentToTarget * SPRING_CONSTANT;
    float dampingForce = -a_Velocity * 2 * sqrt( SPRING_CONSTANT );
    float force = springForce + dampingForce;
    a_Velocity += force * a_TimeStep;
    float displacement = a_Velocity * a_TimeStep;
    return a_Current + displacement;
}
Run Code Online (Sandbox Code Playgroud)

在系统中我使用大约5的值是开始试验弹簧常数值的好点.设置得太高会导致反应太快,太低会导致反应太慢.

注意,你可能最好创建一个保持速度状态的类,而不是一遍又一遍地将它传递给函数.

我希望这是有帮助的,祝你好运:)

编辑:如果它对其他人有用,很容易将其应用于2或3维.在这种情况下,您可以为每个维度单独应用一次CriticallyDampedSpring.根据您想要的运动,您可能会发现在极坐标(对于2D)或球面坐标(对于3D)中工作更好.

  • @brunodeleo 代码的问题在于您没有分别跟踪每个维度的速度。也就是说,您需要一个velocityX 和一个velocityY。 (2认同)