# Smooth decelerate, interpolation?

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.

## 2 Answers

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.

• Thanks. Do you mean multiply subtract (decelerate) by sqrtf(t) * velocity? Commented Aug 6, 2014 at 10:01
• 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. Commented Aug 6, 2014 at 10:56
• 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. Commented Aug 6, 2014 at 11:02
• 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. Commented Aug 6, 2014 at 16:26

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