Sign in to follow this  
FippyDarkpaw

rotating objects: worry about rotating to infinity?

Recommended Posts

If a game has constantly rotating objects defined in a typical manner, for example: float currentRotation = 0f; float rotationRate = 0.5f; Every Update() the rotating objects will spin like this: currentRotation += rotationRate * timeElapsed; Do we need to worry about rotating out of range of floating point? I suppose the same issue applies to counters such as effect cooldowns or timers? Basically anything that constantly counts should be guarded against counting to infinity?

Share this post


Link to post
Share on other sites
You probably don't need to worry about it, just consider such a thing as system time in milliseconds. If you're still worried you can always have a periodic counter for rotation, obviously there's no need to go outside of the [0, 2π) interval.

Share this post


Link to post
Share on other sites
What I would do is just wrap the value as it spins around. So assuming you were using degrees for your angles your code could be like this:

currentRotation += rotationRate * timeElapsed;
while (currentRotation < 0)
currentRotation += 360;
while (currentRotation > 360)
currentRotation -= 360;

Then it makes sure your values are always in between 0 and 360 so you don't have to worry about reaching infinity at all. And if you want to work with radians, just substitute 2 * Pi in there instead of the 360.

Share this post


Link to post
Share on other sites
Quote:
Original post by NickGravelyn
What I would do is just wrap the value as it spins around. So assuming you were using degrees for your angles your code could be like this:

currentRotation += rotationRate * timeElapsed;
while (currentRotation < 0)
currentRotation += 360;
while (currentRotation > 360)
currentRotation -= 360;

Then it makes sure your values are always in between 0 and 360 so you don't have to worry about reaching infinity at all. And if you want to work with radians, just substitute 2 * Pi in there instead of the 360.


This could lead to a performance bottleneck if "rotationRate * timeElapsed" happens to be a (negative or not) very big number.

I would recomment using the modulus operator, or modf() for floating-point numbers.


Quote:
Original post by FippyDarkpaw
...
Every Update() the rotating objects will spin like this:

currentRotation += rotationRate * timeElapsed;
...

Note that that will make the object rotate faster and faster since you're adding instead of just "currentRotation = rotationRate * timeElapsed".
I'm not sure what will happen if you get to the limits of the floating-point, but you need not to get to it if you use a modulus operation after setting the value.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kamikaze15Note that that will make the object rotate faster and faster since you're adding instead of just "currentRotation = rotationRate * timeElapsed".


That depends on your timer. In mine (XNA) "timeElapsed" is time elapsed since the previous frame. So rotation will be constant.

I have seen some frameworks where "timeElapsed" is from the start of the game (XNA in WinForms, for example). I just had that exact problem there on a different project. I used code straight from a normal XNA project and my objects were spinning faster over time. =)

Anyway, so I suppose I'll solve it like this. The rotating objects have an X,Y,and Z rotation and as long as the game is running. Rotation is in radians and timeElapsed is since last frame:


// 360 degrees in radians
float Deg360InRads = 6.28318531f;

// spin object
rotationX += rotationRateX * timeElapsed;
rotationY += rotationRateY * timeElapsed;
rotationZ += rotationRateZ * timeElapsed;

// mod rotation by 360 degrees
// to prevent counting to infinity
rotationX = rotationX % Deg360InRads;
rotationY = rotationY % Deg360InRads;
rotationZ = rotationZ % Deg360InRads;


Thanks for the help guys. =)

BTW, this problem made me discover Google Calculator. Do a search for "360 degrees in radians" and the answer is the first hit. That's pretty helpful and never knew it existed.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kamikaze15
I'm not sure what will happen if you get to the limits of the floating-point, but you need not to get to it if you use a modulus operation after setting the value.


Precision will decrease as time progresses, that's for sure.

It may not go to #INFINITY eventually, I don't know exactly what the behaviour is with large numbers, but it may be worse: your CPU starts throwing floating point overflow interrupts every time you update the rotation. Plus you'll see that your objects stops rotating.
We had a problem once in an audio processing algorithm with floating point underflows. Every time the algorithm was called the CPU would generate interrupts for the underflow (for every sample in the audio buffer), and this would totally kill performance.
Our algorithm would cause thousands of underflows every second so the sudden increase in CPU load was obvious, but in the case of only updating rotations once every frame you may not see a raise in CPU load.
But regardless of actually seeing it, these sort of things are a pain to to debug. They seem to happen incosistently after some time, like glitches, and it does not generate a breakpoint in your code (at least not in Windows VC++).

My advice: avoid this, and save yourself some headaches.

Share this post


Link to post
Share on other sites
If you keep adding small fractional amounts to an increasing value, it will eventually get to the point where the floating point accuracy is less than the amount you are adding. We had this bug in a game when after two days of continuous play, the player's character would stop animating. This ended up being due to the animation of the character being based on the elapsed game time. After two days, the floating point accuracy became less than 1/30sec, thus the elapsed game time stopped.

Another floating point issue is if you keep multiplying a transformation matrix by another rotation matrix. Since the scale exists in the same 3x3 elements of the matrix, floating point error accumulates, affecting the scale until the model disappears up its own butt.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this