算法来控制加速度,直到一个位置到达加速度、算法、位置

2023-09-11 03:34:14 作者:-情债╮請结账°

我有一个点,移动(一维),我需要它来平滑移动。因此,我认为,它的速度已经是一个连续函数,我需要控制加速度,然后计算出它的速度和位置。

I have a point that moves (in one dimension), and I need it to move smoothly. So I think that it's velocity has to be a continuous function and I need to control the acceleration and then calculate it's velocity and position.

该算法似乎并没有明显的东西给我,但我想这一定是一个普遍的问题,我只是无法找到解决办法。

The algorithm doesn't seem something obvious to me, but I guess this must be a common problem, I just can't find the solution.

注:

的对象的最终目的地可以改变,而它的移动和运动需要无论如何是光滑的。 我想,一个天真的实施将产生反弹,而我需要避免的。

推荐答案

这是使用临界阻尼弹簧完美的候选人。

This is a perfect candidate for using a "critically damped spring".

在概念上你连接点到目标点与弹簧的弹力,或片。弹簧阻尼,使你没有'反弹'。您可以控制​​系统如何迅速作出反应,通过改变一个名为SpringConstant不变。这实质上是多么强烈的一块弹性的。

Conceptually you attach the point to the target point with a spring, or piece of elastic. The spring is damped so that you get no 'bouncing'. You can control how fast the system reacts by changing a constant called the "SpringConstant". This is essentially how strong the piece of elastic is.

基本上你申请两个力的位置,然后整合这一段时间。第一力是施加由弹簧,FS = SpringConstant * DistanceToTarget。第二是阻尼力方面,FD = -CurrentVelocity * 2 * SQRT(SpringConstant)。

Basically you apply two forces to the position, then integrate this over time. The first force is that applied by the spring, Fs = SpringConstant * DistanceToTarget. The second is the damping force, Fd = -CurrentVelocity * 2 * sqrt( SpringConstant ).

的系统的状态的CurrentVelocity形式的部分,并且可以被初始化至零。

The CurrentVelocity forms part of the state of the system, and can be initialised to zero.

在每一步,你的时间步长乘这两股力量的总和。这使您CurrentVelocity值的变化。再乘以这个由时间步长,它会给你的位移。

In each step, you multiply the sum of these two forces by the time step. This gives you the change of the value of the CurrentVelocity. Multiply this by the time step again and it will give you the displacement.

我们将它添加到该点的实际位置。

We add this to the actual position of the point.

在C ++中code:

In C++ code:

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;
}

在系统中我的工作有大约5的值是一个好点开始与弹簧常数的数值试验。设置得太高会导致过快的反应,和过低的点会作何反应过慢。

In systems I was working with a value of around 5 was a good point to start experimenting with the value of the spring constant. Set it too high will result in too fast a reaction, and too low the point will react too slowly.

请注意,你可能是最好做一个类,保持速度的状态,而不是不得不一遍又一遍地把它传递到函数。

Note, you might be best to make a class that keeps the velocity state rather than have to pass it into the function over and over.

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

I hope this is helpful, good luck :)

编辑:如果这是对别人有用的,可以很容易地应用此为2或3的尺寸。在这种情况下,你可以应用CriticallyDampedSpring一次单独为每个维度。根据你想要的运动,你可能会发现它更好地在极坐标(二维),或者球坐标(三维)工作。

In case it's useful for others, it's easy to apply this to 2 or 3 dimensions. In this case you can just apply the CriticallyDampedSpring independently once for each dimension. Depending on the motion you want you might find it better to work in polar coordinates (for 2D), or spherical coordinates (for 3D).