39 posts / 1 project
3D rotations with 3D Gibbs vectors in place of 4D quaternions
Edited by Procedural on
Recently I discovered that Gibbs vectors multiply and rotate exactly like quaternions (because they are quaternions), but using only 3 values instead of 4.

Here's C code to try them yourself, it can be compiled with no compile parameters in both Clang and Visual Studio:

Basically, Gibbs vectors encode quaternion's scalar part to the vector part with divisions on all vector elements. That's it.

You can also try them in GpuLib's Instancing and MRT example, build_vs2015.bat and build_vs2017.bat are available.
Mārtiņš Možeiko
2376 posts / 2 projects
3D rotations with 3D Gibbs vectors in place of 4D quaternions
Edited by Mārtiņš Možeiko on
Hmm... This looks very interesting!

If I understand correctly this cannot represent 180° rotations because of division by 0, right? Probably this is not issue for some cases, but with this limitation it cannot completely replace matrix.

In your example this works because tan value is approximated to 13245402.0 which is "very large" number (but not infinity). I'm wondering if for some cases tan will return ±∞ and all calculations further will be incorrect... Maybe it will never happen because no floating point value will get close enough to ±π/2.
39 posts / 1 project
3D rotations with 3D Gibbs vectors in place of 4D quaternions
mmozeiko
but with this limitation it cannot completely replace matrix.

In the real world, in the actual reality of real time graphics, when we multiply at least 2 orientations, quaternions will always be cheaper than matrices, so even if Gibbs vectors fail somehow you can always fallback to them.

mmozeiko
I'm wondering if for some cases tan will return ±∞ and all calculations further will be incorrect...

Right, in that case I would write a custom tan that won't return infinity.

mmozeiko
Maybe it will never happen because no floating point value will get close enough to ±π/2.

This is correct too, in GpuLib example I never saw any issues like that.
What are the chances of a camera rotation or animation hitting one of the axes exactly at floating point 0b0000_0000_0000_0000_0000_0000_0000_0000 or 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000? Close to 0. :)
504 posts
3D rotations with 3D Gibbs vectors in place of 4D quaternions
there is also the chance that a.w * b.w - (a.x * b.x + a.y * b.y + a.z * b.z) = 1-dot(A, B) will end up 0.

This is a very likely spot for catastrophic cancellation which will ruin your accuracy.
Mārtiņš Možeiko
2376 posts / 2 projects
3D rotations with 3D Gibbs vectors in place of 4D quaternions
Edited by Mārtiņš Možeiko on
Procedural
What are the chances of a camera rotation or animation hitting one of the axes exactly at floating point 0b0000_0000_0000_0000_0000_0000_0000_0000 or 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000? Close to 0. :)

The problem is not about hitting value exactly 0 or 180 or any other. The problem with floats is that if you get close enough to some discontinuity which can happen with much higher probability, the calculations will become very unstable. The results produced will become very large or ∞ or NaN. And later calculations will propagate this error further. As a result you'll get weird glitches in rendering or sudden jumps in rotation which could be super annoying to debug or eliminate.
39 posts / 1 project
3D rotations with 3D Gibbs vectors in place of 4D quaternions
mmozeiko
if you get close enough

Isn't any divide in any math code ever suffers from the same problem?

I will not guard my code against divide by 0 anywhere other than in vector length procedure... Will you?
Ginger Bill
222 posts / 2 projects
I am ginger thus have no soul.
3D rotations with 3D Gibbs vectors in place of 4D quaternions
With unit quaternions, there is no worry with dividing by zero. However, with Rodrigues/Gibbs Parameters (RPs) as Mārtiņš has pointed out, 180° rotations cannot be represented, even in floating pointer.

Modified Rodrigues parameters (MRPs) can be used to solve this issue but it only pushes the problem to 360°.

These objects are an exponential mapping of the 3D rotations (exponential map of so(3), the Lie algebra of SO(3)). To represent a 3D rotation, you need at a minimum 4 degrees of freedom (pieces of information): the axis of rotation (x, y, z) and the angle of rotation (θ). Quaternions encode this with no information loss as they have 4 values.

RPs rely on the fact that the axis of rotation is unit length thus you can "lose" a degree of freedom. Even with this fact, you lose other niceties as you have found.

Quaternions seem to be the best solution to the problem for representing 3D rotations on a computer.
39 posts / 1 project
3D rotations with 3D Gibbs vectors in place of 4D quaternions
gingerBill
To represent a 3D rotation, you need at a minimum 4 degrees of freedom (pieces of information): the axis of rotation (x, y, z) and the angle of rotation (θ). Quaternions encode this with no information loss as they have 4 values.

The code is updated for extracting an axis and angle from a Gibbs vector.
Mārtiņš Možeiko
2376 posts / 2 projects
3D rotations with 3D Gibbs vectors in place of 4D quaternions
Edited by Mārtiņš Možeiko on
Procedural
mmozeiko
if you get close enough

Isn't any divide in any math code ever suffers from the same problem?

I will not guard my code against divide by 0 anywhere other than in vector length procedure... Will you?

That's exactly my point - you don't guard against those because there is no solution. Nor in vector normalization, nor for this rotation.

For vectors normalization this is not a problem, because you cannot normalize vector without length. You design your algorithms / functionality in a way that doesn't produce these invalid vectors. And if they occur, that's a bug or impossible situation.

For example, let's say you need normalized direction from some object to light source to use in lighting equation. In real life this will always be non-0 vector when you subtract object position from light position. Sure in case the positions are the same (or almost the same) the vector will be non-normalizeable (the result will be huge or NaN). But that's ok, in such case it is ok to have a glitch. Because in real-world this never happens - light cannot be at same position as object. And if it is, then nobody knows what to expect result to be. So the software can do whatever it wants, no need to "guard" against divide by 0.

But in Gibbs rotations the algorithm is designed to not work for 180° or in case ratchetfreak mentions. But these cases are perfectly normal, the expected result is strictly defined, but they will misbehave.

Nevertheless, I like the idea. I'm sure this representation can work just fine for some use cases. Just not the 100% replacement for rotation matrix/quaternion.
39 posts / 1 project
3D rotations with 3D Gibbs vectors in place of 4D quaternions
mmozeiko
But in Gibbs rotations the algorithm is designed to not work for 180° or in case ratchetfreak mentions.

ratchetfreak's problem is not a problem for unit quaternions (and Gibbs vectors are of unit length) as Ginger Bill mentioned, you can check it yourself by printing dot product in gmul procedure.

As of 180°, the only solution to this problem is:

Deal With It™ :)

I mean, the context is everything. Mouse / gamepad camera rotations? 180° rotations are not possible here. Character animation? If you can think of a character that can rotate its limbs for more than 180° in one operation? I personally can't. I don't know where else you can use >180° rotations, leave a comment below which real world example actually require this. In the context of gamedev I can't think of any!
Ginger Bill
222 posts / 2 projects
I am ginger thus have no soul.
3D rotations with 3D Gibbs vectors in place of 4D quaternions
It actually is a problem. RPs can be zero unlike quaternions.

Other than curiosity, I see no benefit to using RPs over quaternions for practical use. RPs cause more problems than they solve. Other than memory footprint, they have no advantage over quaternions.
39 posts / 1 project
3D rotations with 3D Gibbs vectors in place of 4D quaternions
gingerBill
It actually is a problem. RPs can be zero unlike quaternions.

It is not, until proven otherwise. I can't make dot product return 1, if you know how let us know.

gingerBill
Other than curiosity, I see no benefit to using RPs over quaternions for practical use. RPs cause more problems than they solve.

By more problems you mean one? Saving space is not practical enough for you?

gingerBill
Other than memory footprint, they have no advantage over quaternions.

This is one MASSIVE advantage if we talk space for hundreds of thousands of vectors, and one 180° in one op problem no one even proved to be real so far, because in the real world, in animation, people always lerp.
Ginger Bill
222 posts / 2 projects
I am ginger thus have no soul.
3D rotations with 3D Gibbs vectors in place of 4D quaternions
Edited by Ginger Bill on
First off, how do you encode an zero rotation, half a turn or a full turn around a particular axis? At these particular rotations (depending on the particular encoding), it removes all the information about its axis. With quaternions, all angles of rotation are unique and still keep all the information unlike RPs where the same rotation can be represented in multiple ways.

You lose information when you reduce the degrees of freedom.

If saving space is that much of a concern, multiplying the axis by its angle will achieve the same thing whilst also removing most of the angle rotation problems but then the calculations become a little more costly. Another way to save space is to use a smaller type like 32-bit float or a 16-bit float. But personally, I don't think that saving one extra component outweighs the costs you get from the extra instructions needed to calculate the products.

Show me the evidence that the memory saving cost is worth it over the performance one in the real world and not the theoretical one.

504 posts
3D rotations with 3D Gibbs vectors in place of 4D quaternions
Edited by ratchetfreak on
Procedural

ratchetfreak's problem is not a problem for unit quaternions (and Gibbs vectors are of unit length) as Ginger Bill mentioned, you can check it yourself by printing dot product in gmul procedure.

eh no. The entire point of Gibbs is that the length encodes the rotation angle, so they are not of unit length.

Procedural

As of 180°, the only solution to this problem is:

Deal With It™ :)

I mean, the context is everything. Mouse / gamepad camera rotations? 180° rotations are not possible here. Character animation? If you can think of a character that can rotate its limbs for more than 180° in one operation? I personally can't. I don't know where else you can use >180° rotations, leave a comment below which real world example actually require this. In the context of gamedev I can't think of any!

Rotations are composed from a base orientation. So any time the object is 180° in the other direction the Gibbs will break down.

For example take a car on a flat surface turning in a circle.

At some point it needs to be rotated 180° compared to the starting position. At that point your car will glitch out and depending on how you created the turning transform (iteratively or closed function) will add inaccuracies for the future. So it may recover or it will remain with a glitched transform until it gets reset.

You can't lerp or slerp Gibbs and get the same result as the quaternions unless you normalize them to quaternions. So if you want space savings then just drop the w component and use sqrt(1-dot(q3, q3)) to get it back when needed.
Ginger Bill
222 posts / 2 projects
I am ginger thus have no soul.
3D rotations with 3D Gibbs vectors in place of 4D quaternions
Edited by Ginger Bill on
Quaternions are used for storing an orientation, not just rotations. RPs cannot do this. I'll repeat this again:

You lose information when you reduce the degrees of freedom.

Exponential maps in general have this problem.

Matrix: Easily composed; cannot interpolate
Euler Angle: Not easily composed; you can sometimes interpolate them; can joint limit; has Gimbal lock
Angle Axis: Not easily composed; can interpolate; can joint limit; avoids gimbal lock
Quaternion: Easily composed; can interpolate; can joint limit (but difficult); avoids gimbal lock
Exponential Map: Easily composed; cannot interpolate; cannot joint limit easily; can have gimbal lock