Page 1 of 1

[SOLVED] Angle of rotation allow angles > 359?

Posted: Mon Feb 21, 2005 1:52 am
by pheadbaq
I've been working on a Knights of the Old Republic style 3rd person camera (rotation around the character on Y axis only) and I'm curious if a particular condition is allowed by Irrlicht. Here's the code snippet I'm concerned with:

while(device->run()) {
...
core::vector3df cam_rotation = camera->getRotation();
cam_rotation.Y += .009;
...
}//End while.

This is how I set the speed of rotation, and this will happen any time the left or right arrow keys are held down in my game. However, if I were to hold the left (or right) arrow key down for an extended period of time, would the angle of rotation on the Y axis be allowed to exceed 359 (and hence possible run-time error) or would Irrlicht bring it back to 0 and continue on? Or is there some other type of catch-all that would save me in this scenario? I can code in the limit of 360, I was just curious if it's already done somehow.

Posted: Mon Feb 21, 2005 3:03 am
by Guest
um, im not sure if irrlight defaults to modulus the angle by 360, (acually i think it uses radians and not degrees). But you could code in something to start it at 0 if it reaches 360.
something like


while(device->run()) {
...
core::vector3df cam_rotation = camera->getRotation();
cam_rotation.Y += .009;
if(cam_rotation >= 360){
cam_rotation.Y = 0;
}
...
}//

Posted: Tue Feb 22, 2005 1:20 pm
by Guest
Considering the validity of angles:

mathematically all angles are valid, and the maths won't fail if you go over 360 degrees (or 2 PI radians) or below 0. You won't get a runtime error.

You WILL lose precision if the angle gets very big, though (since the vector3df uses floats, and floats have a relative precision), but that's not the most important reason to restrict your angles.

The trouble is with angle comparisons. E.g. if you want something to turn in a certain direction, you may want to turn over the smallest angle. E.g. if the current rotation is forward, and the desired rotation is left, you want to turn left, not right because that is not efficient.
Such a comparison is relatively easy when you keep all angles within one cycle of each other.

So you're best off by rolling over the angles (exception: you don't want to roll over angular velocities).

What you'd want to do for rotations is something like this:

float normalizeangle(float angle)
{
while(angle>180.0) // very suboptimal but readable
angle-=360.0;
while(angle<-180.0)
angle+=360.0;
return angle;
}

This way you don't introduce an error just because of a rollover.

Shortest turn:

turnangle = normalizeangle(desiredangle-currentangle);

Posted: Tue Feb 22, 2005 4:09 pm
by Acki
or you can do it like this:

angle += (angle % 360.0) + 0.009;

Posted: Tue Feb 22, 2005 7:35 pm
by pheadbaq
Thanks everybody for helping me on this one. I think Acki nailed exactly what I need to do. I knew there wouldn't be a problem with values over 360, because it was already working, but my main concern was the Y variable hitting a value that would be out of range for its data type, and whether or not Irrlicht took the angle modulus 360 when used in the context of rotation. I'm good now, thanks :D