Math Question, I suck at math

Ok, I have a vector of length 1, and what I want to do is calculate the rotation matrix that would move the point (0, 1, 0) to the end of the vector. How do I do this?

Here’s what I’ve been trying, it may be wrong:

double xAngle = 0, yAngle = 0, zAngle = 0;
if(vector.y == 0) xAngle = 0;
else xAngle = Math.atan(vector.z / vector.y);
if(vector.z == 0) yAngle = 0;
else yAngle = Math.atan(vector.x / vector.z);
if(vector.y == 0) zAngle = 0;
else zAngle = Math.atan(-1 * vector.x / vector.y);

pointX = 0;
pointY = 1;
pointZ = 0;

//hardcoded calculation that would be done in a rotational matrix
pointY = Math.cos(xAngle)*pointY + Math.sin(xAngle)pointZ;
pointZ = -1
Math.sin(xAngle)*pointY + Math.cos(xAngle)*pointZ;
pointX = Math.cos(yAngle)pointX + -1Math.sin(yAngle)*pointZ;
pointZ = Math.sin(yAngle)*pointX + Math.cos(yAngle)*pointZ;
pointX = Math.cos(zAngle)*pointX + Math.sin(zAngle)pointY;
pointY = -1
Math.sin(zAngle)*pointX + Math.cos(zAngle)*pointY;

If there exists some method which can do this for me, or some short vector or matrix manipulation (I have a vecmath.jar with simple vector and matrix classes and methods), or you have some short code that does just what i want, please tell me. Thanks a lot!

This is easier than that. Matrices are just arrays of axis vectors. What you are after is a matrix that has the y-axis pointing along the vector you describe. This pseudo-code should show how to do it, it will need tweaking to whichever vactor & matrix classes you use:

  1. Start with our desired y-axis:

myVector y = vector;

Then set the z-axis to point up Z:

myVector z(0, 0, 1);

You then build the true x-axis by:

myVector x = y.crossProduct( z );
x.normalize();

Finally, build the true z-axis:

z = x.crossProduct( y );

Then build the matrix:

myMatrixClass m;
m.setXAxis( x );
m.setYAxis( y );
m.setZAxis( z );

And that is your rotation matrix.
Note that this one should leave +z in roughly the same direction as the original z-axis, so the point (0,0,1) should come out with a positive z always. If you set x instead of z and change the cross-products to:
z = x.cross( y ); x.normalize(); x = y.cross( z );
That will keep the x-axis in the same direction instead.
Hope this helps,

Dom

Do you need that step of building the ‘true’ Z-axis? Since you used the 0,0,1 Z to create X from Y&Z in the first place, shouldn’t it come out the same (0,0,1) when you derive Z from X&Y?

Yep, because:

(y-axis fixed)
z-axis setto up <- this is probably not 90 degrees to Y

make x-axis - due to cross product, this IS perpendicular to the y and z axis, but z is still not perpendicular to Y

build true Z - this one will now be truly perpendicular.

The standard use for this is aligning a game camera in the world (except z is fixed, and y is up). You make a normal from the camera position to the point of interest (character usually), and set the camera z-axis to this (or away from in OpenGL I think). You then set Y axis to straight up. The first cross product gets you the right axis for the camera. The last cross product gets you the ‘tilted’ up-axis of the camera (for example if you were looking 45 degrees down along the z axis, the y-axis should come out as (0, 0.707, 0.707) not the (0,1,0) we fed in at the start.
Hope that makes sense (I have a tendancy to ramble…)

  • Dom

makes perfect sense. I don’t know where my brain was. It’s been far to long since I’ve done some real math… I keep meaning to find the time to do some 3D stuff to refresh my memory but it just hasn’t happned yet… Got any spare time you can lend me? :slight_smile:

One note:
I think this will fail if the desired y is such that it also just happens to be pointing straight ‘up’, since ZY won’t define a plane. Be careful of those edge conditions that cause errors when you least expect them.