Assume a left-handed coordinate system where x is right, y is up, and z is into the screen. You have a unit vector pointing up along the y-axis. What's the rotation matrix for pointing the unit vector along the y-axis to an arbitrary point p?

I was asked this question during a phone screen. The interviewer implied there's an easy way to get this rotation matrix by "dropping in" a few values. I'm reading a 3D math book hoping to find this easy way but no luck yet. The ways to get this matrix in the book all seem too long to recite over the phone during an interview.

I think I can see part of the solution. The rows of the matrix are the post-transformation basis vectors. So the middle row of the matrix is just the point p possibly normalized (since that's where the y-axis will be post-rotation).

Any help with this easy "drop in" way of getting the rotation matrix is much appreciated!

Edit: If it seems like the problem statement is missing information please call it out. I feel like I remember the interview clearly but I could have left something out (or the interviewer could have).


1 Answer 1


First let's get the direction we want our y vector to point:

yDirection = Normalize(p - viewPoint);

(Here viewPoint can be the origin, since it doesn't look like you were given a specific location for the observer)

If this works out to be the zero vector then we need to fall back on some sensible default, which I'll elide here.

There's an infinite number of rotation matrices that will map the local y+ axis to point along yDirection (take any matrix that does this, and apply an extra rotation around the axis yDirection: now you have a new distinct matrix that still does what we asked), so we'll need to make some arbitrary choices here.

Let's decree that our rotation will take the local x+ axis and map it into the world xz plane. We always have at least one way to do this while staying perpendicular to yDirection. If we have a whole plane of choices, then we'll just map it to the world x+ axis by fiat.

xDirection = Cross((0, 1, 0), yDirection);

if (xDirection == (0, 0, 0)) {
     xDirection = (1, 0, 0);
} else {
     xDirection = Normalize(xDirection);

Now we have two perpendicular unit vectors to map x and y to. We can cross them to get the remaining z:

 zDirection = Cross(xDirection, yDirection);

And finally we can combine the three into a rotation matrix, whose first column is xDirection, second column is yDirection, and third column is zDirection. (Assuming you multiply Matrix * vector. If you go vector * Matrix, then use these direction vectors as the matrix's rows instead)

I work through this relationship in more detail in this answer.


You must log in to answer this question.