# Quaternion Decomposition

I'm having trouble decomposing a unit quaternion into euler angles (or roll, pitch and yaw). The overall goal is to tell how a phone is rotated with respect to the world. I'm given a unit quaternion this world axis:

The axis has the following characteristics:

• X is defined as the vector product Y.Z (It is tangential to the ground at the device's current location and roughly points East).
• Y is tangential to the ground at the device's current location and points towards magnetic north.
• Z points towards the sky and is perpendicular to the ground.

DISCLAIMER: Trying to find the rotation around the z-axis by using atan2(y-component of quaternion, x-component of quaternion) without involving the phone at all, the angle is always between 180 and 360 degrees. Since I'm very new to working with quaternions, I'm trying to figure out whether my error is in the math, or in my code.

I have the following phone axis:

The phone will be held in landscape mode rotated 90 degrees counterclockwise around the z-axis. I need the angle of rotation around the world's z-axis (to see which direction the user is facing), the angle of rotation about the world's y-axis (to determine the angle off of the horizon), and the angle of rotation about the x-axis (to see whether the device is horizontal to the ground).

• Trying to break a quaternion back down into Euler angles can be cumbersome; what do you ultimately want to do with these angles? Feb 17 '14 at 0:04
• I'm creating a structure from motion app and for the UI, I need to let the user know how far off they are from being horizontal to the ground so they can take straight pictures. Internally I need to know the angle off the horizon and the direction they are facing so I know what pictures they have taken, and what pictures they still need to take. Feb 17 '14 at 0:33

Okay, so you have an East-North-Down coordinate system as the fixed frame, and you have the phone's Up-Left-Out (of the screen) set of axes, and the quaternion is given in terms of the fixed coordinate system's basis vectors. I'll call the fixed axes $\hat x, \hat y, \hat z$ and the phone's axes $\hat x', \hat y', \hat z'$.
If you're using the phone as a camera, then I imagine it's the phone's Out-of-screen direction that is most like the direction the camera is facing (or rather, the negative of this). So the vector $-\hat z'$ should be the direction that the camera is facing. You should then project this vector onto the $xy$-plane by zeroing out its $\hat z$ component: $P_{xy}(\hat z') = \hat z' - \hat z (\hat z \cdot \hat z')$. You can then renormalize the result and find the angle in the $xy$-plane by basic trig. This should give you the compass direction that the camera is pointing (as an angle relative to east).
Angle off the horizon is easier. Take $-\hat z' \cdot \hat z = \cos \theta$. $\theta$ is then the angle off the vertical. $\theta - \pi/2$ should then give the angle you want: if $\theta = \pi/2$, then the camera is level. If it's larger, then the camera is tilted upwards. That checks out.
• Will my $-\hat z'$ vector always be $(0, 0, -1)$? I'm also assuming that I'm projecting onto the $xy$-plane of the fixed axes. I'm confused about how to do the projection. I know how to do a projection but for this particular one, I don't know what the $\hat z$ or $\hat z'$ vectors are and how to calculate them from the unit quaternion on the world axis that I have. Feb 17 '14 at 2:15
• Oh, well the natural thing to do with a quaternion is to use it to compute the body axes. It should be true that $\hat x' = q \hat x q^{-1}$, where $\hat x = i$, and so on. Feb 17 '14 at 3:43