rotating objects: worry about rotating to infinity?

Started by
6 comments, last by Sly 15 years, 9 months ago
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?
Advertisement
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.
Best regards, Omid
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.
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.
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.
If you think that's nifty, ask google "2 light years in fathoms", or "17 zeptograms in ounces".
RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.
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.
STOP THE PLANET!! I WANT TO GET OFF!!
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.
Steve 'Sly' Williams  Monkey Wrangler  Krome Studios
turbo game development with Borland compilers

This topic is closed to new replies.

Advertisement