Lerping a rotation

Started by
10 comments, last by rgibson11 13 years, 5 months ago
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?
Advertisement
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
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
Thanks for reply.
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
Quote:Original post by snake5
You can either use SLERP or normalize the angles


Isn't slerp only for 3d rotation, not 1d angle?
Quote:Original post by bubu LV
Quote:Original post by snake5
You 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.
Quote:Original post by skytiger
I 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()
------------------------------Great Little War Game
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
Quote:Original post by rgibson11
the 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?

This topic is closed to new replies.

Advertisement