# Given a direction(vector) and a wanted direction(vector), how do you get a rotation?

This topic is 4581 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Given a direction(vector) and a wanted direction(vector), how do you get a rotation, like, quaternion?? E.g. I am facing 1,0,1. And I want to face 2,5,4. How do I get the thing(either in quaternion or angle-rotating axis form) that, when applied to 1,0,1 would become 2,5,4? All I can find is telling you how to get the resulting direction with a starting direction and a rotation, but not what I mentioned. Please help.

##### Share on other sites
>>Given a direction(vector) and a wanted direction(vector), how do you get a rotation, like, quaternion??

Cross product!!!

Vector3 rotation_vec = Direction cross Wanted_Direction

You'd want to normalize the direction and wanted direction vectors. Then, the inverse sine (asin) will give you the angle to rotate through, and the direction that rotation_vec points in is the axis.

double angle = asinf(rotation_vec.Length());
rotation_vec.Normalize();

Quaternion quat_rotation;
quat_rotation.w = angle;
quat_rotation.xyz = rotation; //normalized at this point

That should give you a basic idea.

##### Share on other sites
Quote:
 Vector3 rotation_vec = Direction cross Wanted_Directiondouble angle = asinf(rotation_vec.Length());rotation_vec.Normalize();Quaternion quat_rotation;quat_rotation.w = angle;quat_rotation.xyz = rotation; //normalized at this point

tthibault, I dont think that actually works.

Taking the cross product of two normalized angles will yield another normalized vector(length always equal to one). Although this is indeed your "axis of rotation", you cannot obtain how far to rotate between the two directions by taking the length of an already normalized vector (it will always be one). I think you need ot use the cross product to find the axis to rotate on and the dot product to find out how far to rotate along this axis.

This is the code I would use:

// Note: Directions should be normalizedDirStart.Normalize();DirEnd.Normalize();// Find axis to rotate alongVECTOR3 rotAxis = DirStart.Cross(DirEnd);    // Use dot product and arccos to detrmin how far to rotate along previous axisfloat   angle = acos( DirStart.Dot(DirEnd));// and borrowing from tthibault to fill in a quaternion...quat_rotation.w = angle;quat_rotation.xyz = rotAxis; // or you can use something like this in direct3d to build a rotational matrixD3DMatrixRotationAxis(rotMat, &axis, angle);

Hope this helps

##### Share on other sites
The dot-product shows the correspondence
a . b = |a| * |b| * cos( < a,b > )

The cross-product shows the correspondence
|a x b| = |a| * |b| * |sin( < a,b > )|

So, even if both input vectors show unit length, the length of the resulting vector (in the case of the cross-product) _is_ depending on the included angle. Else a cross-product of self
a x a
were not able to disappear for any non zero length vector. But, looking at the computation formula for the cross-product, one can see that e.g.
(a x a)x := ay*az - az*ay
(and similarly for y and z) always disappears.

##### Share on other sites
In addition to the axis-angle method, there are some other methods for directly computing the quaternion that rotates one vector onto another. It's covered in one of the first two GPG books, but there's an even nicer algorithm that I've seen online (among other things, it doesn't require the input to be unit length).

One nice thing about the 'direct' methods is that unlike the axis-angle methods you don't have to handle near-aligned vectors (parallel and pointing in the same direction) as a special case.

I just googled for the algorithm I had in mind, but couldn't find it; I'm pretty sure though that it's discussed somewhere on this site.

Oh, and here's one more method; it does require unit-length input, but handles near-aligned vectors uniformly:
vector3 mid = normalize(v1+v2);q.set(cross(v1,mid),dot(v1,mid));
(I may or may not have gotten that right...)

[Edit: Fixed error in code.]

[Edited by - jyk on May 30, 2006 11:03:47 AM]

##### Share on other sites
>>Taking the cross product of two normalized angles will yield another normalized vector(length always equal to one)

Wait, no, it still works...

|A x B| = |A| * |B| * sin(theta)

if A and B are have a length of 1, you just take the asin of the length, getting theta.

1. 1
2. 2
Rutin
17
3. 3
4. 4
5. 5

• 26
• 10
• 11
• 9
• 9
• ### Forum Statistics

• Total Topics
633717
• Total Posts
3013510
×