Finding pitch/yaw values from lookat vector

I have a camera class that contains a position, a pitch, and a yaw (the pitch and the yaw correspond to y and x rotation values). I want to implement a lookAt function that takes a vector and the function changes the pitch and yaw so it's looking at that point in space. However, I cannot seem to find the math equation to do it (various ones online, none seem to work). How would I be able to implement it?

Here's an example of what I mean:

struct Camera
{
Vec3 position;
float pitch, yaw;

void lookAt(Vec3 center)
{
//????
}

mat4x4 toTransform() //How I convert the values to a matrix (if this is relevant)
{
return CreateLookAtMatrix
position,
position + Vec3(cos(pitch)*sin(yaw), sin(pitch), cos(pitch)*cos(yaw)),
Vec3(0.0f, 1.0f, 0.0f)
);
}
}

• Please stop using Euler angles. – Nicol Bolas Dec 7 '15 at 14:21

lookAt = position + Vec3(cos(pitch)*sin(yaw), sin(pitch), cos(pitch)*cos(yaw))

You just need to do a little algebra to get the yaw and pitch variables over to the left.

lookAt.y = position.y + sin(pitch), which we can rearrange to...
sin(pitch) = lookAt.y - position.y
pitch = asin(lookAt.y - position.y)


Where asin is arcsine, the inverse of sine.

Note that this assumes lookAt - position is a unit vector (length 1) which in your matrix expression is true by construction. If center can be anywhere then you'll want to start by constructing the unit vector you need:

void lookAt(Vec3 center)
{
Vec3 direction = (center - position).normalized;
pitch = asin(direction.y);
yaw = atan2(direction.x, direction.z);
}


I skipped ahead a bit on yaw there because we have both k*sin(yaw) and k*cos(yaw) for some real k, so we can just drop that into the atan2 convenience function and let it sort out all the cases for us. ;)

• Thank you so much for this! Saved me tonnes of time. Just one quick remark: for some reason I had to add PI to the last equation. – samvv Aug 5 '17 at 13:25
• It will vary based on how you measure your bearings. in OP's LookAtMatrix code, they used cos(yaw) for z, and sin(yaw) for x, which means a yaw of zero is facing along z+, and a yaw of π/2 is facing along x+. If your angle convention is different, then you might need to offset or even negate the angle generated by these formulas, since they're derived from OP's conventions. – DMGregory Aug 5 '17 at 13:41