# Straighter SLERP/LERP

I am debugging my Lerping to see how it works. It is rotating a card and it looks good. However the lerping contains way beyind the card is visually done rotating. I understand it has to do with the mathematics. Is thera a way i can fix it? Is it unavoidable with Lerp/Slerp? Basically what i want is the function to be done when the card has rotated enough so that steps are no longer visible.

public IEnumerator LerpRotationY (float durationSeconds, FlipsSide flipSide)
{
int targetAngle = FlipSideEnumToDegrees (flipSide);

//float flipSpeed = 3F;
var flipRotation = Quaternion.Euler (0, targetAngle, 0);
float t = Time.deltaTime;
var cardRotation = cardSides.rotation;
var timePassed = Time.time;
print ("SLERPING! ");
while (t < durationSeconds) {

cardSides.rotation = Quaternion.Slerp (cardSides.rotation, flipRotation, t);

yield return null;
t += Time.deltaTime;
}
print ("SLERPING FINISHED: " + (Time.time - timePassed).ToString ());}


I'm having trouble visualizing the problem you are describing, however I can see two issues with the implementation posted.

The first issue is that you are using the updated rotation as the first parameter of the lerp function. Doing this will produce a movement that will start off quickly but then slow down towards the end. This effect is great for camera movement but would look a little off for rotating a card.

Another issue is that you are using t (elapsed time) as the third parameter for lerp, this will produce varying (and possibly unexpected) results for those occasions where durationSeconds is not equal to 1. The solution is to use t / durationSeconds as this will smoothly travel from 0 to nearly 1. At the end of the loop you can then force the final rotation to ensure a predictable final state.

A smooth and complete lerp requires stable start and end parameters and a t parameter that ranges between 0 and 1.

Please try this version with these changes applied:

public IEnumerator LerpRotationY (float durationSeconds, FlipsSide flipSide) {
int targetAngle = FlipSideEnumToDegrees(flipSide);
var flipRotation = Quaternion.Euler(0, targetAngle, 0);
// store starting rotation:
var startingRotation = cardSides.rotation;
float t = Time.deltaTime;

while (t < durationSeconds) {
// First parameter changed to startingRotation
// Third parameter changed to t / durationSeconds
cardSides.rotation = Quaternion.Slerp(startingRotation, flipRotation, t / durationSeconds);
yield return null;
t += Time.deltaTime;
}
// force final rotation:
cardSides.rotation = flipRotation;
}

• Thanks! Am i correct in observing that the only change you made is to divide t with durationSeconds? – Daarwin Jan 1 '14 at 16:09
• @Lautaro I've added some comments to highlight the changes. – Kelly Thomas Jan 1 '14 at 16:13