# Lerping a rotation

This topic is 2805 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have a small problem.
My multiplayer game currently has a packet being delivered every 100ms.
The packet contains position and a heading angle which is -pi to pi.

I am actually rendering 100ms behind real server time in order to be able to lerp the positions (which work fine). I tried to lerp the heading angle this way and it works but theres a sudden snapback at the end of every rotation. I just cant figure out what it could be

//lerp:
//return a + (b - a) * t;

float h1 = (*ito).headings.front(); //Heading 100ms agofloat h2 = (*ito).headings.back(); //Current server headingfloat currh = 0.0f; //Lerped headingcurrh = Math::lerp(h1, h2, zlerp);//zlerp = elapsed time since last update / 100.0 (ms) This works perfect for pos

Anyone could know what im doing wrong?

##### Share on other sites
You can't lerp between angles without problems. You can either use SLERP or normalize the angles, find the fastest route from one angle to another (remember - angle is equal to the remainder of a division between that angle and the "full circle angle" in the same units, 2 pi radians or 360 degrees), modify the 2nd angle to make it fit the fastest route and only then do a lerp between those angles.

http://en.wikipedia.org/wiki/Modulo_operation

##### Share on other sites
I calculate the shortest difference between two angles like this:

d = b - a;a = abs(d);s = sign(d);if (a > pi) { d = s * (2 * pi - a) * -1;}//if

now you can:

lerp = a + d * i;

you can map back into (-pi,pi) range using the same code again:

a = abs(d);s = sign(d);if (a > pi) { d = s * (2 * pi - a) * -1;}//if

this uses less cycles than modulo

##### Share on other sites
That seems to help but my maths isnt that great?
Do you have a quick example of what you said? or should I go ahead learning slerp.
Also why is your user rating so low? :S

-edit thanks skytiger. I got an example now. cheers :D

##### Share on other sites
Quote:
 Original post by snake5You can either use SLERP or normalize the angles

Isn't slerp only for 3d rotation, not 1d angle?

##### Share on other sites
Quote:
Original post by bubu LV
Quote:
 Original post by snake5You can either use SLERP or normalize the angles

Isn't slerp only for 3d rotation, not 1d angle?

SLERP gets you between points on a sphere.

What do points on a sphere have to do with rotations?

In 3d, you can represent a rotation as a unit quaternion; the unit quaternions lie on a sphere in four dimensions, so you can use SLERP to get between them.

In 2d, you can represent a rotation as a unit vector. The unit vectors lie on a sphere in 2 dimensions (i.e., a circle), so you can use SLERP to get between them.

In both cases, this does what you want because the notion of distance on the sphere agrees with what you'd want to call the distance between two rotations.

##### Share on other sites
Quote:
 Original post by skytigerI calculate the shortest difference between two angles like this:*** Source Snippet Removed ***now you can:*** Source Snippet Removed ***you can map back into (-pi,pi) range using the same code again:*** Source Snippet Removed ***this uses less cycles than modulo

What is sign() ? Is that a function you made yourself? cant find it anywhere in standard libraries

try sgn()

##### Share on other sites
Ok I tried using slerp and it seems to be working very well.
Except for one slight error.
The rotations are smooth as hell except sometimes it stops rotation and quickly rotates the other way.

Please can someone who is familiar with slerps check this code. I would be very greatful. Im sure its some simple error im making

float h1 = (*ito).headings.front(); //100ms behind server timefloat h2 = (*ito).headings.back(); //Current server timefloat hcurr = 0.0f;Quaternion hh1, hh2, ff;float uu, uu2, uu3;hh1.fromHeadPitchRoll(h1, 0.0f, 0.0f);hh2.fromHeadPitchRoll(h2, 0.0f, 0.0f);ff = Quaternion::slerp(hh1, hh2, zlerp); //zlerp = time since last update / 100.0ff.toHeadPitchRoll(uu, uu2, uu3); //uu should be the slerped heading angle

the actual slerp function is from a well known maths library so im pretty sure its correct

##### Share on other sites
Quote:
 Original post by rgibson11the actual slerp function is from a well known maths library so im pretty sure its correct
What math library is it? Does the SLERP function in question correct for quaternion aliasing?

1. 1
2. 2
Rutin
23
3. 3
JoeJ
20
4. 4
5. 5

• 22
• 40
• 23
• 13
• 13
• ### Forum Statistics

• Total Topics
631733
• Total Posts
3001927
×