Given a vector, A, which represents a point, and a unit vector, B, which represents the looking direction, how would I rotate A so that B is the axis that's looked down on? Let's say the looking-axis is originally (0,0,1) and I want it to become B by rotating A accordingly. So it needs to rotate by (0,0,1) - B.


2 Answers 2


You can directly construct a look-at matrix without using trigometry (but using vector math). First, you need an up-vector to specify which direction should be up from the camera's point of view. This would typically be (0, 1, 0) or (0, 0, 1), depending on your choice of coordinates.

Then, you can calculate the orthonormal basis for your camera:

float3 right = normalize(cross(dir, up));
float3 upTrue = normalize(cross(right, dir));

Beware! If dir is parallel or antiparallel to up, this will break.

Then, you can construct the (left-handed) camera-to-world matrix by shoving right, upTrue, and dir into the first three rows (if using row vectors) or columns (if using column vectors) of a 4x4 matrix. Put the camera position into the fourth row/column.

Then calculate the inverse of this 4x4 matrix to get the world-to-camera matrix. If you just need the rotation part, use a 3x3 matrix, and you can take the transpose instead of doing a full inverse.

This matrix can then be used as a view matrix in a 3D graphics engine, or you can transform a point yourself by multiplying with this matrix.

  • \$\begingroup\$ Thanks. Can you clarify a bit on how I would construct a 3x3 matrix using column vectors? \$\endgroup\$ Commented Jun 7, 2012 at 5:30
  • \$\begingroup\$ @myrkos What do you need to know? Are you familiar with matrices in general? \$\endgroup\$ Commented Jun 7, 2012 at 6:08
  • \$\begingroup\$ I am, but I'm still a bit new to them. I'm a but confused where I would put the right,upTrue, and dir. On the top of each column? \$\endgroup\$ Commented Jun 7, 2012 at 6:11
  • \$\begingroup\$ Each vector has three components; you copy those entries into the first, second, and third row components of each column of the matrix. The first column would contain the xyz values of right, from top to bottom, and so on. \$\endgroup\$ Commented Jun 7, 2012 at 16:38
  • \$\begingroup\$ Oh, oh, sorry. I read float3 as some sort of float number rather than a 3D vector. Thanks! \$\endgroup\$ Commented Jun 7, 2012 at 17:19

Given direction as d and point as p

d = normalize(d);
double yaw = Math.Atan2(d.X, d.Y);
double pitch = Math.Atan2(d.Z, Math.Sqrt((d.X * d.X) + (d.Y * d.Y)));
p.rotateXYZ(pitch, yaw, 0); //Roll == 0

Well, this should do :)

  • \$\begingroup\$ You could also use Math.Asin(d.z) for the pitch, since you already normalized d; that's slightly simpler/faster. (Although, the Atan2 calls will work even when d is unnormalized.) \$\endgroup\$ Commented Jun 7, 2012 at 4:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .