Advertisement

[Quaternion_Validity]

Started by July 11, 2022 08:38 AM
8 comments, last by JoeJ 2 years, 4 months ago

Hello guys,

I hope you're all doing very well.

So I've developed this app that rotates an object using quaternion.

Quaternion values are extracted from a csv file.

I'm thinking about adding some conditions to make sure that the quaternion values are valid.

For example if the conditions are true, then we can rotate the object. Otherwise, an error message will be printed saying that the object can't be rotated since the values aren't valid. (Let's say in case, someone modified the csv file without knowing it and that affected some quaternion values).

So I'm wondering wether these conditions are sufficient or not:

-All quaternion components ( w, x, y and z) should be between -1 and 1

-the quaternion norm should be less then or equal to 1

But I think the second condition isn't necessary if the components are all between -1 and 1. Right ?

I can't find any other conditions, I searched on the internet and this is what I found.

Is there any other conditions that needs to be added ?

I'm not sure if this is the right forum to ask this question but since you guys develop games, you certainly use quaternions a lot.

Please help me.

Thank you a lot.

ogldev1 said:
But I think the second condition isn't necessary if the components are all between -1 and 1. Right ?

No that's wrong. E.g. if all 4 values would be 1, the norm would 4, not 1.

So the important fact is:

ogldev1 said:
-the quaternion norm should be less then or equal to 1

while this:

ogldev1 said:
-All quaternion components ( w, x, y and z) should be between -1 and 1

… is just a consequence of the above.

Thus, you can just check the norm to be very close to 1, which guarantees to quaternion represents a rotation.

If not, you could just normalize it to continue, but print a warning message to inform the user.

Advertisement

Oh, sorry!

ogldev1 said:
-the quaternion norm should be less then or equal to 1

That's wrong too.

The norm should be exactly one, not less! (ofc. accepting some epsilon of floating point error)

@JoeJ First of all, thank you for your help.

Thing is the quaternion values I have, their norms is not equal to 1, it's around 0.9998. But the rotations is still working.

ogldev1 said:
Thing is the quaternion values I have, their norms is not equal to 1, it's around 0.9998. But the rotations is still working.

Yeah that's a small error. Maybe an epsilon of 0.001 could be used to print the warning (if at all), but i would normalize all quaternions after loading from file in any case.

Just recently i have spent 2 days debugging IK solver, only to figure out in the end my transform gizmo did add a small error to the target quaternion each frame, which was the origin of my issues.

When working with quaternions, it's common practice to renormalize them after some calculations have been applied, even if we know it's all operations which should preserve the norm (like rotations).
The same applies to rotations matrices, where we can do an orthogonalization to keep axis at 90 degrees from each other, plus an normalization of their lengths.

But this depends.

E.g. we have a character skeleton, containing quaternions representing bones. And we have animation data, also made from quaternions representing joint angles. In this case, all quaternions are static data and normalized. After applying the animation, there will be a small error, but it will not grow from frame to frame, because we always start from valid data. So no need to renormalize.

But if we do physics simulation on a ragdoll for the same character, we will integrate changes to the state from the last frame. Thus error would accumulate with time, so we need to renormalize all quaternions at least once per frame to avoid issues.

That's a clear explanation, thank you :D.

So I need to renormalize the quaternion again after extracting its values from the file and then apply the rotation right ?

Advertisement

ogldev1 said:
So I need to renormalize the quaternion again after extracting its values from the file and then apply the rotation right ?

Yes, exactly.
The reason could be the decimal numbers in your text file may fail to reproduce the exact same number which was saved before, e.g. because there are not enough digits.
Renormalization does not undo such errors, but it ensures we get a quaternion to represent a rotation, so our related math routines still work as expected.

If you do something like a spinning cube demo, where the orientation of the object is rotated every frame, you also need to renormalize each frame to prevent accumulation of small errors.

Some quaternion libraries may even do renormalization under the hood, e.g. after a multiplication to perform a rotation.
But that's bad practice, because it would waste some performance. Thus renormalization is usually left to the user, and we have to be aware about this.

Okay, I have a another question.

The norm of every quaternion in my case is around 0.99.

What if before specifying the condition of the quaternion validity ( norm =1 ), I round every norm to the nearest tenth so that the norm would be equal to 1.

Can I do that ?

ogldev1 said:
What if before specifying the condition of the quaternion validity ( norm =1 ), I round every norm to the nearest tenth so that the norm would be equal to 1.

That's a rather unusual way, not backed by good instruction support.

The conventional way using some epsilon looks like this:

constexpr float eps = 0.001f;
bool valid = fabs(1.f - quaternion.norm()) < eps;

if (!valid) MessageBox ("Saboteur in the company!!! Saboteur in the company!!! /:O\ ");

quaternion = normalize(quaternion);

Btw, an error of 0.01 is quite big. The CSV file should have 6 digits per number, ideally.

This topic is closed to new replies.

Advertisement