0

I create a Quaternion (w, x, y, z) using input from an IMU device. I then normalize the quaternion and find the euler angles based on this conversion code from quaternion to euler angles:

private PVector setEulerAngles(){

     // roll: x-axis rotation
     float sinr = 2.0f * (w*x + y*z);
     float cosr = 1.0f - 2.0f * (x*x + y*y);
     float roll = (float)Math.atan2(sinr, cosr);

     // pitch: y-axis rotation
     float sinp = 2.0f * (w*y - z*x);
     float pitch = 0.0f;
     if(Math.abs(sinp) >= 1){
       pitch = (float)Math.copySign(Math.PI/2, sinp);
     } else {
       pitch = (float)Math.asin(sinp);
     }

     // yaw: z-axis rotation
     float siny = 2.0f * (w*z + x*y);
     float cosy = 1.0f - 2.0f * (y*y + z*z);
     float yaw = (float)Math.atan2(siny, cosy);

     return new PVector(roll, pitch, yaw);
   }

I then apply the ZYX rotation within Processing. However, to orient my 3D object I have to flip the z and y values, and negate the y value for the z-rotation. I also had to create an offset of (PI/2) for rotateY, so my object faces the right direction. The object perfectly rotates around the x and y axis, but along the z-axis the object rotates in the right directions, but will flip suddenly. Is there a simple solution to get the object rotating properly around the z-axis?

 pushMatrx();
 translate(pos.x, pos.y, 0);
 rotateZ(-q.eulerAngles.y);
 rotateY(q.eulerAngles.z+(PI/2));
 rotateX(q.eulerAngles.x);
 shape(model);
 popMatrix();
karamazovbros
  • 950
  • 1
  • 11
  • 40
  • 2
    As I mentioned in [your other question](https://stackoverflow.com/questions/51433919/processing-rotating-a-3d-object-using-quaternions-works-for-x-axis-but-not-for/51436493#51436493): use a rotation matrix and you avoid all of this. – Nico Schertler Jul 20 '18 at 20:49
  • I was confused by the source code for creating a 4 by 4 matrix for the applyMatrix Processing function. It has a reference to 2 quaternions (q and q1), and I wasn't sure how that applies when you're only working with one quaternion. – karamazovbros Jul 20 '18 at 20:51
  • Can you give a link to the source code you are referring to? – Nico Schertler Jul 20 '18 at 20:52
  • It's from the link you sent (the last code example at the bottom): http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm – karamazovbros Jul 20 '18 at 20:53
  • `public final void quatToMatrix(Quat4d q)` takes a single quaternion. This is the function you need. The other one is probably just a typo (but didn't check exactly). – Nico Schertler Jul 20 '18 at 20:55
  • Yeah, but doesn't that give me a 3x3 matrix. How would I use that with applyMatrix that takes different parameters (4x4)? https://processing.org/reference/applyMatrix_.html – karamazovbros Jul 20 '18 at 20:58
  • 1
    Fill the last column and row with (0, 0, 0, 1). So you have a matrix `[ [ x x x 0 ]. [x x x 0], [x x x 0], [0 0 0 1] ]`. `x` stands for the entries of the 3x3 matrix. – Nico Schertler Jul 20 '18 at 21:00
  • Okay, so I did that and now x-rotation rotates object around y-axis, y-rotation rotates object around z-axis, and z-rotation rotates object around x-axis. – karamazovbros Jul 20 '18 at 21:35
  • any tips on how to fix this? – karamazovbros Jul 20 '18 at 22:04
  • 1
    Then, you just need to permute your 3x3 matrix. If the matrix you have is `[ [ m11, m12, m13, 0 ], [ m21, m22, m23, 0 ], [ m31, m32, m33, 0 ], [0, 0, 0, 1] ]`, then you need to move the first row/column to the back to get: `[ [ m22, m23, m21, 0], [m32, m33, m31, 0], [m12, m13, m11, 0], [0, 0, 0, 1] ]`. I hope I didn't mix something up. If this is not what you are looking for, try another permutation. – Nico Schertler Jul 21 '18 at 06:10
  • 1
    Throw Euler angles away.... read this [Understanding 4x4 homogenous transform matrices](https://stackoverflow.com/a/28084380/2521214) fully (I know its a bit long) and then on the bottom you got linked 3 QAs examples of camera and player control and full pseudo inverse matrix. See all of them after that you should know everything you need to implement your task. – Spektre Jul 21 '18 at 07:47
  • @NicoSchertler So the axes correspond to the right rotation, but the z and x axes are rotating in the opposite directions. The y-axis is rotating properly. – karamazovbros Jul 21 '18 at 19:15
  • 1
    Then you also need to flip the y-axis. I.e., negate the row and column of the corresponding axis (should be the second row and column, depending on what axis you mean). When you negate both row and column, the diagonal element will negate twice, i.e., it stays the same. There remain four elements that need to be negated (don't touch the fourth row and column). – Nico Schertler Jul 21 '18 at 20:58
  • I fixed it flipping the camera around and flipping the model. I really appreciate your help on this. I only took linear algebra and intro to computer graphics, so working with quaternions is new to me. **Before, when I was using Euler angles with ZYX rotation was the reason it suddenly flipped on the z rotation, because of gimbal lock?** Last thing, do you recommend any book on computer graphics and mathematics? – karamazovbros Jul 22 '18 at 05:25

0 Answers0