Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

quat_from_mat4 not working #37

Open
Mikepicker opened this issue Mar 31, 2020 · 6 comments
Open

quat_from_mat4 not working #37

Mikepicker opened this issue Mar 31, 2020 · 6 comments

Comments

@Mikepicker
Copy link

Unfortunately, the function doesn't give correct results.

Here's a proposal to change it (taken from https://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm):

float tr = M[0][0] + M[1][1] + M[2][2];

  if (tr > 0) { 
    float S = sqrt(tr+1.0) * 2; // S=4*qw 
    q[3] = 0.25 * S;
    q[0] = (M[1][2] - M[2][1]) / S;
    q[1] = (M[2][0] - M[0][2]) / S; 
    q[2] = (M[0][1] - M[1][0]) / S; 
  } else if ((M[0][0] > M[1][1])&(M[0][0] > M[2][2])) { 
    float S = sqrt(1.0 + M[0][0] - M[1][1] - M[2][2]) * 2; // S=4*qx 
    q[3] = (M[1][2] - M[2][1]) / S;
    q[0] = 0.25 * S;
    q[1] = (M[1][0] + M[0][1]) / S; 
    q[2] = (M[2][0] + M[0][2]) / S; 
  } else if (M[1][1] > M[2][2]) { 
    float S = sqrt(1.0 + M[1][1] - M[0][0] - M[2][2]) * 2; // S=4*qy
    q[3] = (M[2][0] - M[0][2]) / S;
    q[0] = (M[1][0] + M[0][1]) / S; 
    q[1] = 0.25 * S;
    q[2] = (M[2][1] + M[1][2]) / S; 
  } else { 
    float S = sqrt(1.0 + M[2][2] - M[0][0] - M[1][1]) * 2; // S=4*qz
    q[3] = (M[0][1] - M[1][0]) / S;
    q[0] = (M[2][0] + M[0][2]) / S;
    q[1] = (M[2][1] + M[1][2]) / S;
    q[2] = 0.25 * S;
  }
@datenwolf
Copy link
Owner

Did you check that the order of the quaternion elements is correct? linmath.h uses a slightly different convention and uses the last element for the real part, i.e. the ordering of the quaternions is i,j,k,r.

@Mikepicker
Copy link
Author

I've also tried shifting the elements, but it didn't work either. Does it work fine in your case?

I did a simple test:

  1. Initialize an identity matrix
  2. Extract quaternion with quat_from_mat
  3. Create a new matrix with mat_from_quat
  4. Realized that it's not the identity matrix

Can you do this test? If it works for you maybe it's something I messed up :)

@datenwolf
Copy link
Owner

I've also tried shifting the elements, but it didn't work either. Does it work fine in your case?

I did a simple test:

1. Initialize an identity matrix

2. Extract quaternion with quat_from_mat

There's your problem right there. An identity matrix has no distinct eigenvector, i.e. axis of rotation: Every vector is an eigenvector of an identity matrix.

Which in turn means, that there's no unique quaternion associated with it.

You must test with a rotation matrix.

@Mikepicker
Copy link
Author

Oh, thanks for pointing me that out!

By the way, I've tested it with some transforms coming from an animated data (which contains rotation matrices) and I couldn't get good results, while using the approach I posted it worked smoothly.

Have you had any issue with the function?

@monolifed
Copy link

monolifed commented May 3, 2020

@datenwolf
Copy link
Owner

Yeah, I'll have to look at this. A couple of weeks ago I got a bunch of pull requests, and I was so swamped with work, that I didn't check them properly. Mea culpa.

TTBT when I published linmath.h I never expected to take off like that. There are a few warts and pimples I'd like to clean up, but wonder how much that would break for existing codebases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants