direction vector to world matrix

Started by
7 comments, last by XiotexStudios 17 years, 8 months ago
I used to remember how to do this! Perhaps its the UK heat... but... Can anyone remember the steps needed to turn a normalised direction vector into a world matrix that can be used to orient a mesh to the direction. Assuming y is up all the time. My immediate guess is that since I have a normalised direction and Y = 0,1,0 I can do a cross product to get the side vector and then fill in the world matrix by hand... any thoughts (or easier way)?
Byron Atkinson-JonesXiotex Studioswww.xiotex.com
Advertisement
And before anyone bumps me to maths.... I am using DX to do this and I may be missing some really usefull D3DX function here...
Byron Atkinson-JonesXiotex Studioswww.xiotex.com
Off the top of my head:

Desired Direction x Current Direction = Rotation around all 3 axis.

So you'd do:
Vector3 vec = Vector3.Cross(Desired, Current);
Matrix mat = Matrix.RotationYawPitchRoll(vec.Y, vec.X, vec.Z);

Hope this is correct :).
Sirob Yes.» - status: Work-O-Rama.
I just realised - since I am essentially working in 2D here... I could use atan2f on the normalised vector...
Byron Atkinson-JonesXiotex Studioswww.xiotex.com
Quote:Original post by sirob
Off the top of my head:

Desired Direction x Current Direction = Rotation around all 3 axis.

So you'd do:
Vector3 vec = Vector3.Cross(Desired, Current);
Matrix mat = Matrix.RotationYawPitchRoll(vec.Y, vec.X, vec.Z);

Hope this is correct :).


Sirob,

That can't be right. If you cross the x and z axes you will get the y (a vector perpendicular to both). To actually rotate from the x to the z is 90 degrees around the y. But if you plug the y-axis into the function:

Matrix.RotationYawPitchRoll(1, 0, 0);

You will get a matrix that rotates 1 radian around the y-axis.

1 radian = 57.296 degrees. Not 90.


However, if you get home and have a chance to figure out what it was you were trying to remember, I would like to know! If there is a way to get the 3 angles of rotation from something as simple as that, I would be very interested to know! I have tried to figure out how to do such a thing myself, and found it really difficult.

Thanks.
--------------------------Most of what I know came from Frank D. Luna's DirectX books
0) call the 0,1,0 vector 'initial_up'.


1) right = initial_up CROSS forward
  • .


    2) right = normalise(right). [length(AxB) == sin(angle)*length(A)*length(B), initial_up and forward might not be perpendicular, so the result might not be unit].


    3) real_up = forward CROSS right
  • . Get real up vector (the "first best guess" initial_up might not be perpendicular to forward). 'forward' and 'right' are perpendicular due to the above cross product, real_up is unit.


    4) plug right, real_up, and forward into a matrix as basis vectors of an orthonormal basis: http://www.gamedev.net/community/forums/topic.asp?topic_id=400849&whichpage=1?


    5) in 2D, you can simply use the "perp product" property to get a 2D vector that's perpendicular to another 2D vector:

    x' = -y
    y' = x


    6) an alternative to 1-3 to look at is Gram Schmidt orthonormalization which uses the projection properties of a dot product.


  • me=too sleepy for maths, you may need to reverse the terms to get the correct basis (Google "right hand rule" for correct ordering).
  • Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

    Quote:Original post by DXnut
    However, if you get home and have a chance to figure out what it was you were trying to remember, I would like to know! If there is a way to get the 3 angles of rotation from something as simple as that, I would be very interested to know! I have tried to figure out how to do such a thing myself, and found it really difficult.


    The straight forward was is to cross the two vectors. You'll get a vector who's direction is the axis of rotation, and length is cos(angle). You can really just plug those two values right into D3DXMatrixRotationAxis and get an instant result.

    [EDIT] figured I'd add some psuedo code in case I wasn't clear enough ;)
    Vector3 vec = Current x Desired;float len = length(vec);Vector3 norVec = normalize(vec); // or vec / len...Matrix mat = D3DXMatrixRotationAxis(norVec, acos(len));

    Comments: Normalizing the vector might not be needed. The docs don't say it has to be normalized, but they don't say it doesn't, so I'm playing it safe.

    As for YawPitchRoll, I'm guessing it just needs an acos() in there. Not sure if you need the same function for all 3 axis, but that shouldn't be too difficult to sort through.

    Lastly, if you don't want to have all these trigo functions, you could just plug the cos(angle) straight into a rotation matrix (through you might need the sin too).

    Hope this helps.
    Sirob Yes.» - status: Work-O-Rama.
    Thanks! That makes sense too. rating+ for you.
    --------------------------Most of what I know came from Frank D. Luna's DirectX books
    Nice solution!

    However, for what I originall needed this does as well

    m_fTargetAngle = RadToDegree(atan2f(Dest.x - m_vPos.x,Dest.y - m_vPos.y));

    Byron Atkinson-JonesXiotex Studioswww.xiotex.com

    This topic is closed to new replies.

    Advertisement