Archived

This topic is now archived and is closed to further replies.

helix

Finding the rotation from one vector to another

Recommended Posts

Repost. I got no replies in my original post. Here is the relevant code:
    
//

// Find the rotation from v1 to v2

//

D3DXMATRIX Util::RotationFromV1toV2( const D3DXVECTOR3* v1, const D3DXVECTOR3* v2 )
{
	// Find the rotation axis

	D3DXVECTOR3 vRotAxis;
	D3DXVec3Cross( &vRotAxis, v1, v2 );

	// Angle of rotation

	const float fAngle = (float)acos( D3DXVec3Dot( v1, v2 ) ) * DEG;

		// Rotation quaternion

	D3DXQUATERNION quat = D3DXQUATERNION( vRotAxis.x, vRotAxis.y, vRotAxis.z, fAngle );

	// Rotation matrix

	D3DXMATRIX rotMat;
	D3DXMatrixRotationQuaternion( &rotMat, &quat );

	return rotMat;
}
  
This does not give me the desired results. Depending on the direction of the vector I want to rotate it to, it will point backwards and/or the result will just be off. If I am rotating to a vector (v2) in the general vicinity of the original vector (that I am rotating from -- v1), it looks pretty damn close but the more v2 is pointing away from v1, the worse my results are. Any thoughts? This problem has plagued me for a month at least now and none of my friends can figure it out either. This is keeping me from completing my game! [edited by - beoch on October 16, 2002 11:59:54 PM]

Share this post


Link to post
Share on other sites
AFAIK a rotation stored as a D3DQUATERNION should be constructed as D3DQUATERNION(sin(fAngle/2)*vRotAxis.x, sin(fAngle/2)*vRotAxis.y,sin(fAngle)*vRotAxis.z,cos(fAngle/2)).

Be careful with degrees and radians too.

Share this post


Link to post
Share on other sites
Well, one problem is that acos only has a range of 0 to pi, not 2pi, so your rotation is either a positive or negative angle, i.e. v1.v2=v2.v1. You need to check the sign of component of v2 orthogonal to v1 to determine the sign of the angle, i.e. if v1 was the x axis then the sign of the y component of v2 would determine the sign of the angle. Second both v1 and v2 have to be unit vectors for your dot product to be the cosine of the angle, i.e. v1.v2=|v1||v2|cos(theta). It isn''t clear from the code snippet if they are normalized vectors. I also don''t know quaterions nor DirectX so there may be other problems.

Share this post


Link to post
Share on other sites
quote:
Original post by LilBudyWizer
Well, one problem is that acos only has a range of 0 to pi, not 2pi, so your rotation is either a positive or negative angle, i.e. v1.v2=v2.v1.


No, it''s not a problem : the direction of the axis will change, making an effectively ''negative'' rotation with still a ''positive'' angle.

Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]

Share this post


Link to post
Share on other sites
quote:
Original post by Fruny
normalised vectors -

Axis = cross product of the two vectors
Angle = arc-cosine of their dot product

Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]



Bravo; two thumbs up bud.
Oh and this is not your average "hello thread resurrection Batman :D"


[edited by - JavaCoolDude on June 29, 2003 3:25:53 AM]

Share this post


Link to post
Share on other sites
Since you''ve already taken the cross product to find the axis of rotation, can''t you use the arcsine of its magnitude to find the angle?

On second thoughts, it might take longer to find the magnitude of the cross product than to simply take the dot product. Is this the case? If not, why do people use the dot product for the angle?

Share this post


Link to post
Share on other sites