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();