As zehelvion stated, you need to know when to begin slowing down. However, simply reaching the halfway point time-wise is not precise, especially if the acceleration is different from the deceleration. In fact working out the time just so we can calculate that is more tedious than using the distance.
The distance that you need to decelerate fully can be given by the following physics formula:
2ad = Vf^2 - Vi^2
a is the acceleration (or in this case, the deceleration or traction), d is the distance we need to work out, Vf is the final speed (in this case, it's 0), Vi is the speed before accelerating, in this case it's our normal velocity. After working out the formula (and considering that the deceleration is negative, but for the sake of simplicity, we will use a positive value in the code) gives us the following:
d = Vi^2 / 2a, which makes the code as following:
deaccDistance = velocity^2 / (2 * DECELERATION);
Lets define 'x', 'y' as the position of the chasing entity and 'targetX', 'targetY' as the position of the target. dt is the time that passed since the last frame. ACCELERATION, DECELERATION, TOPSPEED are constants
deltaX = targetX - x;
deltaY = targetY - y;
distance = Math.Sqrt(deltaX^2 + deltaY^2);
decelDistance = velocity ^ 2 / (2 * DECELERATION);
if (distance > decelDistance) //we are still far, continue accelerating (if possible)
{
velocity = Math.Min(velocity + ACCELERATION * dt, TOPSPEED);
}
else //we are about to reach the target, let's start decelerating.
{
velocity = Math.Max(velocity - DECELERATION * dt, 0);
}
cx += velocity * cosangle * dt;
cy += velocity * sinangle * dt;
If the target is stationary, you can calculate the cosangle and sinangle beforehand, otherwise you will need to calculate them on every frame.. for reference:
angle = Math.Atan2(deltaY,deltaX);
cosangle = Math.Cos(angle);
sinangle = Math.Sin(angle);
This would work, if the dt is a constant, however it will vary from a frame to another, so we have to add a check before the code:
if distance < (velocity * dt) then --we almost reached it, skip the rest
{
x = targetX;
y = targetY;
velocity = 0;
return
}
And that's pretty much it, you can add a variable named finished and call it as appropriate to be absolutely sure that it doesn't break, or make more checks to see if the lastdistance was bigger than the current distance and in that case you can snap the object to the target, but usually, this is not required.