# Deceleration via Lerping

I have written some code that creates a very nice uniform angular acceleration for an object moving around a circle. It effectively uses linear interpolation but ramps the interpolant such that the change is non-linear, hence the acceleration. The code is:

// Set the parameters to define the acceleration
float accelerationTime = 3f;
float startAngle = 0;
float endAngle = 180;
float currentAngle;
float startSpeed = 120;
float finalSpeed = 360;
float currentSpeed;
float radius = 3;

// Create the acceleration from 120 deg/s to 360 deg/s over a 180 degree angle within 3s
float t = 0;
accelFraction = 0;
Vector3 position;
while (accelFraction < 1f)
{
t += Time.deltaTime;
accelFraction = Mathf.Clamp(t / accelerationTime, 0, 1);
currentSpeed = Mathf.Lerp(startSpeed, finalSpeed, accelFraction);
float speedRatio = Mathf.Clamp(currentSpeed / finalSpeed, 0, 1);

currentAngle = Mathf.Lerp(startAngle, endAngle, speedRatio * accelFraction);

position = new Vector3(Mathf.Sin(currentAngle * Mathf.Deg2Rad), 0,
}


It allows me to accelerate from a start speed to an end speed, over a defined angular distance within a specific time. Great!

The problem is that I cannot figure out how to reverse this code to create the opposite effect, i.e. a deceleration. I have tried reversing the logic but it does not work, as counting downwards breaks the maths. Perhaps I am being obtuse but can anyone help here?

I would really like to keep my acceleration code the same; I suspect there is a simple tweak that I am missing. Any help is greatly appreciated!

• Have you considered using AnimationCurves for this, to author the exact shape of acceleration curve you want? Nov 2, 2021 at 17:58
• In my case the acceleration is uniform and occurs in a circular motion, over a defined angular coverage. In the above example from 0 to 180 degrees but I would like this to variable, which the above code provides. This solution works perfectly for acceleration but I just cannot get it to work the opposite way round for deceleration. I have never used animation curves before as I tend to just go with math.
– Cato
Nov 2, 2021 at 21:31
• I think the problem lies in "reversing this code," and you haven't indicated what you tried. Just by a quick look, perhaps to decelerate, you would use 1-accelfraction when lerping for current speed. Dec 3, 2021 at 22:03

I guess you could solve this problem mathematically. But I would solve this problem using an AnimationCurve instead. A very useful class which allows you to design things like ease-in and ease-out curves using a visual curve editor in the inspector.

My script:

public class Rotator : MonoBehaviour
{
public float rotationDuration;
public float startAngle;
public float stopAngle;
public AnimationCurve curve;

private float currentRotationTime;

void Update()
{
currentRotationTime += Time.deltaTime;
var progress = curve.Evaluate(currentRotationTime / rotationDuration);
var currentAngle = startAngle + (stopAngle - startAngle) * progress;

transform.rotation = Quaternion.Euler(0f, 0f, currentAngle);
}
}


(Instead of using that trigonometry logic of yours I am just rotating the object itself, but if you feed currentAngle into your code then it should work as expected)

How I drew the rotation curve in the inspector: How it looks when I press play: • I have experimented with this but I need the moving body to start and end at very specific speeds. I am not sure how that could be implemented using this method? Ideally I think using maths would be the most reliable solution.
– Cato
Nov 7, 2021 at 17:06