pixel perfect local rotations and quats vs mats

Started by
12 comments, last by Paradigm Shifter 11 years, 1 month ago

ok, who out there uses quaternions?

can you get pixel perfect rotations about local axes at arbitrary orientations? or does floating point error creep in and spoil the fun the way it does with matrices?

lets say incremental turns around local y by 1/10th degree per turn (3600 turns to do a 360), and 1600 x 900 screen resolution. can a floating point quat, starting from any orientation, come back to exactly the same pixel every time after doing a 360?

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Advertisement
If it contains floating point it's prone to precision error; doesn't matter what data structure you use, you must do your calculations in a manner that deals with or compensates for this error instead. Re: quaternions, and even if you do use them for rotation, at some time you're going to need to put that rotation in a matrix anyway as you'll be wanting to do translation/projection/etc too, and quaternions can't do those.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

You would not do incremental turns of 1/10 degree with any representation you use, that is inefficient, it is not how graphics APIs work, and it's unwise because of accumulating error.

You do not throw an "object" at OpenGL or Direct3D which it "remembers", and later you can tell it to rotate by 1/10 degree a few times. It doesn't work that way.

Instead, you would do a single rotation from a neutral position to whatever orientation you want every frame when you draw your object. This is a single transform (note, however, that a unit quaternion can rotate at most +/-180°, so you need a little bit more thought). Since you do not accumulate a thousand tiny rotations, the rounding issue does not arise.

That being said, unit quaternions are none "worse" than orthonormal matrices. On the contrary, a quaternion (unit or not) has fewer degrees of freedom (i.e. fewer "numbers") and is thus not as much "over-defined" as a matrix for performing a rotation. Therefore, you reasonably expect fewer rounding issues.

The obvious advantage of a matrix is that you can do translation, scaling, and shear as well whereas a (unit) quaternion does no such thing. But since you're only interested in a rotation, that doesn't matter.

Instead, you would do a single rotation from a neutral position to whatever orientation you want every frame when you draw your object. This is a single transform (note, however, that a unit quaternion can rotate at most +/-180°, so you need a little bit more thought).

They can rotate objects +/- 360 degrees (although simplistic SLERP implementations usually use a dot + negate to artifically restrict the quats to +/-180)

Effectively, yes, but actually no. At least I wouldn't know how you'd do that.

A quaternion stores cos(½?) as one of its components, and the cosine function has a period of 2?.

Which means you can unambiguously represent a rotation of +/- ½·2? = +/- ? or +/- 180°.

But of course rotating by -1° is the same orientation as rotating by +359° so effectively you can get any orientation.

If it contains floating point it's prone to precision error; doesn't matter what data structure you use

that's what i suspected.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

nstead, you would do a single rotation from a neutral position to whatever orientation you want every frame when you draw your object.

i guess it wasn't clear in my original post, i'm not talking about drawing objects, i'm talking about storing their orientation and rotating them about local axes by incremental amounts. once that's done, you have an orientation in a matrix or quat, and use that to draw.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

ok, given float inaccuracies, how does one achieve pixel perfect rotations at high resolutions? I've been able to do it in the past, but at 640 x 480, not 1600 x 900. there i used D3DXMATRIX, and gram-shmitt re-ortho-normalize.

i guess one would have to implement the data structure at high accuracy, such as long long fixed point. and then copy the accurate info to a less accurate matrix for drawing.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

you can compute double on CPU but shaders need float . I do not see why float matricies in shaders would not result in pixel precise rotations. What do you mean by pixel precise rotation and why you think you are not having it?

Effectively, yes, but actually no. At least I wouldn't know how you'd do that.

A quaternion stores cos(½?) as one of its components, and the cosine function has a period of 2?.

Which means you can unambiguously represent a rotation of +/- ½·2? = +/- ? or +/- 180°.

But of course rotating by -1° is the same orientation as rotating by +359° so effectively you can get any orientation.

Ok. So given an XY coordinate that lies on a circle, is it possible to determine the angle? Applying your logic, the answer would be no, because:

angle = acos( X )

And that would only give you +/-90 degrees.... whereas the correct answer is yes, so long as you use both components, i.e. atan2(Y, X).

So sure, if you're going to completely ignore the existence of the sin(angle / 2) in addition to cos(angle / 2), then you will indeed be able to ignore the fact that a quat can represent +/-360 degrees. But you know, as I said before, if you use a crap SLERP implementation that performs a quat-negate when the dot product is less than zero, then you will not be aware of the other half of the hemisphere. If you were to change your slerp from:

if( dot(Q1, Q2) < 0 )

to

if( dot(Q1, Q2) > 0 )

your quats will always take the longest path, i.e. the one greater than 180 degrees. FYI, if you have a quat Q, that represents a rotation of 1 degree, it's negate represents the rotation of -359.

This topic is closed to new replies.

Advertisement