PDA

View Full Version : glRotate(), precision points



PhotonicDude
10-30-2003, 12:31 PM
Hi all, I have a question/observation and I'd like feedback if you have seen this or know a way to around this problem...

When using glTranslated(x,y,z) or glScaled(x,y,z) with identity matrices, my 4*4 resulting matricies are clean (where x,y,z have all decimal values after the point equal to 0 ( ex:4.0) , the resulting matrix multiplication gives a matrix that has also clean values).

Yet when I use the (ex) glRotated(90.0f,0.0f, 1.0f, 0.0f) on the identity matrix,
(the resulting multiplication:
[c 0 s 0]
[0 1 0 0]
[-s 0 c 0]
[0 0 0 1]
c is for cos(angle) and s for sin(angle)

I seem to observe that "s" values are clean values but the "c" values have garbage after the 7th decimal point... I observe this when angle is factor of pi/2 (90deg) for c and s but not with angle = 0;
In this example Cos(90)(or c) should be 0.0,
but I have -0.000000437....

Is this normal with OpenGL ?

Thanks again, PhotonD

Won
10-30-2003, 12:41 PM
To paraphrase from Jim Blinn paraphrasing someone else:

Doing floating point math is like moving piles of sand. Each time you lose a little sand and pick up a little dirt.

Unfortunately, there's not much you can do about it. You are very rarely going to see exact values in floating point computation. Fortuntately it usually doesn't matter. The imprecision probably comes from the degrees/radians conversion internally.

-Won

PhotonicDude
10-30-2003, 12:51 PM
Thanks Won , I though so also (internal conversion hic-up).

PhotonicD

mogumbo
10-30-2003, 03:45 PM
Depending on the app you can fix some of these problems with a bit of effort. For example, I was working on a modeler a while ago and noticed the same problem when I rotated objects by 90 degrees. So I wrote functions called mySinf() and myCosf() which had special cases for 30, 60, and 90 degree rotations to ensure that I would get "clean" values and not build up error after several rotations by these common angles. In your case, this would only work if you were willing to also write your own myGlRotate()

[This message has been edited by mogumbo (edited 10-30-2003).]

PhotonicDude
10-30-2003, 05:11 PM
I will have no choice but to write my own "correction" methods since the application I am working on will eventually need this precision.

It's good to know someone that has gone along this path before,
thanks mogumbo!

PhotonicD

Won
10-31-2003, 09:17 AM
Probably the best way is to avoid performing incremental floating point operations. Basically: instead of doing this:

glRotatef(increment, axis);

Do something like this:

glLoadIdentity();
angle += increment;
glRotatef(angle, axis);

You probably have a better chance at controlling the precision of angle than the results of the rotate.

-Won

*Aaron*
10-31-2003, 09:40 AM
There's another option that's often overlooked: don't use glRotate*() at all. If you look at the spec, you will find the exact formula that this function is supposed to use. Just calculate the matrices on the CPU, and upload them to GL. This will not only allow you to eliminate unnecessary roundoff errors that may occur in the driver, it will standardize the behavior of rotation matrices across different GL implementations.