1
votes

Given two 3D vectors A and B, I need to derive a rotation matrix which rotates from A to B.

This is what I came up with:

  1. Derive cosine from acos(A . B)
  2. Derive sine from asin(|A x B| / (|A| * |B|))
  3. Use A x B as axis of rotation
  4. Use matrix given near the bottom of this page (axis angle)

This works fine except for rotations of 0° (which I ignore) and 180° (which I treat as a special case). Is there a more graceful way to do this using the Direct3D library? I am looking for a Direct3D specific answer.

Edit: Removed acos and asin (see Hugh Allen's post)

4

4 Answers

2
votes

No, you're pretty much doing it the best way possible. I don't think there is a built-in DirectX function that does what you want. For step 4, you can use D3DXMatrixRotationAxis(). Just be careful about the edge cases, such as when |A| or |B| is zero, or when the angle is 0° or 180°.

1
votes

It's probably more of a typo than a thinko, but acos(A.B) is the angle, not its cosine. Similarly for point 2.

You can calculate the sin from the cos using sin^2 + cos^2 = 1. That is, sin = sqrt(1-cos*cos). This would be cheaper than the vector expression you are using, and also eliminate the special cases for 0/180 degrees.

1
votes

You might look at the following article from siggraph link text

0
votes

Maybe you can use D3DXMatrixLookAtLH ?