Jump to content
  • Advertisement
Sign in to follow this  
rgibson11

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.

If you intended to correct an error in the post then please contact us.

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 ago
float h2 = (*ito).headings.back(); //Current server heading
float currh = 0.0f; //Lerped heading
currh = 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 this post


Link to post
Share on other sites
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

Share this post


Link to post
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 this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
Quote:
Original post by snake5
You can either use SLERP or normalize the angles


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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
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 time
float h2 = (*ito).headings.back(); //Current server time
float 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.0
ff.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 this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!