# Camera Pitch, Yaw from View Matrix

I have a camera that works with Pitch and Yaw (no roll) and compute the look at matrix as following :

glm::vec3 direction;
direction   = glm::normalize(direction);
this->view =
glm::lookAt(position, position + direction, glm::vec3(0, 1, 0));


Now I want to initialize these Pitch and Yaw from another View Matrix and used this method but without success:

  /* previousCamera->view as a glm::mat4 */
position = glm::vec3(previousCamera->view[3]);
const glm::vec3 direction = glm::vec3(previousCamera->view[2]);
yaw   = glm::degrees(glm::atan(direction.x, direction.z));
pitch = glm::degrees(glm::asin(direction.y));


Do you spot any mistake in my code?

Edit:

In addition to the answer from @DMGregory, my position and direction were not correctly extracted from the ViewMatrix:

  const glm::mat4 inverted = glm::inverse(previousCamera->view);
position = glm::vec3(inverted[3]);
const glm::vec3 direction = - glm::vec3(inverted[2]);
yaw   = glm::degrees(glm::atan(direction.z, direction.x));
pitch = glm::degrees(glm::asin(direction.y));


First, let's look at y because it's simplest.

• to encode pitch into your direction vector's y, you convert the pitch value to radians, then take its sine.

• to decode pitch from your direction vector's y, you take its arcsine and then convert it to degrees.

So you're correctly reversing each operation, and the value should round-trip correctly up to floating point accuracy.

yaw / x and z get a bit more complicated, so let's try running a few sample values through (with zero pitch, for simplicity):

• at yaw = 0, x = cos(0) = 1 and z = sin(0) = 0

• at (x, z) = (1, 0), yaw = degrees(atan(1, 0)) = 90 degrees
• at yaw = 90 degrees, x = cos(radians(90)) = 0 and z = sin(radians(90)) = 1

• at (x, z) = (0, 1), yaw = degrees(atan(0, 1)) = 0 degrees

So it looks like you've simply flipped your x and z arguments to atan.

If you think of the two-argument arctangent as finding an angle from positive x-axis on the unit circle in the xy plane, the arguments go in the order (y, x) rather than (x, y)

• Nice answer. My Position and Direction were also not correctly extracted. I edited my post. – FloFu Jul 8 '18 at 10:28