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:
- Derive cosine from
acos(A . B) - Derive sine from
asin(|A x B| / (|A| * |B|)) - Use A x B as axis of rotation
- 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)
-
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°. -
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.
Vulcan Eager : I am not sure that calculating the sine from sqrt(1-cosine*cosine) will work. This is because cosine*cosine will cause us to lose the sign of the cosineHugh Allen : You don't "lose the sign of cosine" because you use the cosine as-is in the rotation matrix. What you should really ask is do you get the right sign for sin? In this case (0-180 degrees) you only want the positive square root, so it's all good.Vulcan Eager : I agree completely!Vulcan Eager : Hugh, What about the 0 to -180 range?Hugh Allen : Negative angles aren't necessary for this particular application. When rotating from B to A the axis vector will be negated rather than the rotation angle.Vulcan Eager : That's how things ended. Thanks again for a very prompt reply. -
You might look at the following article from siggraph link text
-
Maybe you can use D3DXMatrixLookAtLH ?
0 comments:
Post a Comment