11
\$\begingroup\$

I've got 2 direction vectors, for the X axis and the Y axis of the object. How do I calculate the rotation matrix of the object using these?

\$\endgroup\$

1 Answer 1

18
\$\begingroup\$

The basic idea is to use a cross product to generate the extra orthogonal axes of your rotation matrix, based upon the axes that you already have.

Matrix3x3 MakeMatrix( Vector3 X, Vector3 Y )  
{  
    // make sure that we actually have two unique vectors.
    assert( X != Y );

    Matrix3x3 M;  
    M.X = normalise( X );  
    M.Z = normalise( cross_product(X,Y) );
    M.Y = normalise( cross_product(M.Z,X) );  
    return M;
}

Note that the above does not make assumptions about X and Y vectors (apart from them not being identical), and does a lot of extra math that it might not have to do in your situation.

For example, in this code I'm doing a second cross-product to be sure our matrix gets an orthogonal Y axis, instead of blindly trusting that the input X and Y axes are precisely 90 degrees apart. If in your situation you are sure that your input axes really are orthogonal to each other, then you can skip the second cross product, and just assign the input Y vector directly, instead of recalculating it.

Note that I'm assuming that your matrix representation has accessible 'X, Y, Z' vector members. Some implementations just expose an array of nine floats instead, in which case the 'X' vector will be either elements 0, 1, and 2, or 0, 3, and 6, depending upon whether the matrix is row-major or column-major. In this (annoying) situation, I usually find that it's easier to just try both ways and see which one works, rather than to search through documentation to try to figure out which ordering your particular matrix implementation is using. :)

Finally, note that depending on your 3D coordinate system's handedness, you may need to multiply M.Z by negative one, in order to generate a legal rotation matrix for your 3D engine.

\$\endgroup\$
4
  • \$\begingroup\$ Thank you very much! I'll do this and let you know my results. \$\endgroup\$ Commented Nov 23, 2011 at 4:02
  • \$\begingroup\$ Thank you for the very helpful answer! I'm curious, though: isn't the X vector always elements 0, 1, and 2 regardless of the matrix being row- or column-major? 0, 3, and 6 would imply accessing the first column of a row-major matrix, or vice-versa. \$\endgroup\$
    – fbrereto
    Commented Jun 13, 2012 at 23:02
  • 1
    \$\begingroup\$ +1 for at least assert()ing that the two vectors are not equal, but I think you should also require that they are not zero vectors. \$\endgroup\$
    – hans_meine
    Commented Jul 10, 2014 at 19:06
  • 1
    \$\begingroup\$ Note that this does not take into account a case where X is -Y. \$\endgroup\$ Commented Sep 15, 2016 at 17:29

You must log in to answer this question.

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