0
\$\begingroup\$

I have two points A and B. I want to perform a smooth deceleration from A stopping at B over time t. The only thing I managed to do so far was a lerp, which isn't right of course because it's unnatural. I also tried multiplying the velocity by some factor (0.9 or similar), but then I don't know how to choose the factor such that the end point B is reached (or as near to it as some epsilon value seems reasonable).

Does anyone have something relatively simple that I could use? I can read C++ and C# code.

\$\endgroup\$
1
\$\begingroup\$

Compute the ratio x in [0,1] of the current animation time and the animation duration t. Then use something like sqrtf(x) to decelerate. Compute the current position C = A + x * (B - A). You can make it decelerate more rapidly by using e.g. powf(x, f) with f = 1.0f / 3 or smaller.

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Thanks. Do you mean multiply subtract (decelerate) by sqrtf(t) * velocity? \$\endgroup\$ – Robinson Aug 6 '14 at 10:01
  • \$\begingroup\$ First of all, I fixed the variable naming in my response because it was a little misleading that I used t differently than you did in your question. \$\endgroup\$ – Raginmari Aug 6 '14 at 10:56
  • \$\begingroup\$ The only thing you need is your points A and B and the time it takes to get from A to B. In regular intervals, you compute x as described in my response and compute your current position C between A and B. \$\endgroup\$ – Raginmari Aug 6 '14 at 11:02
  • \$\begingroup\$ OK I finished my implementation (it's a virtual surface that pans and "bounces", kind-of like a mobile phone or slate surface) and it works great. Prefer the powf function to sqrt however. Thanks a lot. \$\endgroup\$ – Robinson Aug 6 '14 at 16:26
1
\$\begingroup\$

I would use the "Arrive" behavior from Millington's book Artificial Intelligence for Games.

It's important to say that you need to constantly update positionB in order for it to work correctly.

float targetRadius = 0.1f;
float timeToTarget = 0.1f;
float maxSpeed = 10.0f;

Vector3 positionA;
Vector3 positionB;
Vector3 agentVelocity;

// calculation for slow radius given the initial
// distance between the two positions
Vector3 dist = positionB - positionA;
float slowRadius = dist.Length();

public Vector3 GetVelocity ()
{
    Vector3 velocity = new Vector3();
    Vector3 direction = positionB - positionA;
    float distance = direction.Lenght();
    float targetSpeed;
    if (distance < targetRadius)
        return velocity;
    if (distance > slowRadius)
        targetSpeed = maxSpeed;
    else
        targetSpeed = maxSpeed * distance / slowRadius;
    velocity = direction;
    velocity.Normalize();
    velocity *= targetSpeed;
    velocity -= agentVelocity;
    velocity /= timeToTarget;
    return velocity;
}
|improve this answer|||||
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.