Archived

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

Sean Doherty

Angle between two vectors

Recommended Posts

I have a ship with 4 Shields {front, left, right, back} being hit by a pulse beam. Using the direction of pulse beam and the direction of the ship being hit; I am trying to calculate which shield is being hit. The following is a subset of my code:
	// Retrieve the phaser source position.

	vecTargetPosition = pCCollisionUnit->RetrieveXYZ();

	// Retrieve the phaser target position.

	vecStarshipPosition = RetrieveXYZ();

	// Calculate a vector between the phaser source and the phaser target [Normalized].

	vecAngleToTarget = vecTargetPosition - vecStarshipPosition;
	D3DXVec3Normalize(&vecAngleToTarget, &vecAngleToTarget);

	// Retrieve the course and convert to Radians.

	if (m_fCourse > 360.0f)
	{
		m_fCourse = m_fCourse - 360.0f;
	}
	else if (m_fCourse < 0.0f)
	{
		m_fCourse = m_fCourse + 360.0f;
	}
	fRADCourse = m_fCourse * (3.14159f / 180.0f);

	// Calculate the Starship direction (Normalized).

	vexStarshipDirection.x =  ( ( (float) sin(fRADCourse) ) * (3.0f));
	vexStarshipDirection.z =  ( ( (float) cos(fRADCourse) ) * (3.0f));
	vexStarshipDirection.y = 0.0f;
	D3DXVec3Normalize(&vexStarshipDirection, &vexStarshipDirection);

	// Calcuate the Angle between the two vetors.

	fAngle = ((float) D3DXVec3Dot(&vexStarshipDirection, &vecAngleToTarget) ) * 180.0f / 3.14159f;
I would have expected "fAngle" to be a the Angle between the two the two vectors; but it only returns a range between approximatley -57 to + 57 degress? Maybe the input are wrong; but I am thinking that I am missing something? Thanks All _______________________________________ Understanding is a three edged sword... Independent Games compete Head to Head ... www.FreelanceGames.com [edited by - Sean Doherty on April 4, 2004 3:39:48 PM]

Share this post


Link to post
Share on other sites
Sean,

The dot product of two vectors returns the cosine of the angle, not the angle itself. To find the angle between two vectors, normalize them, then compute acos(dot(v1,v2)) and you''re done.

Jean-Francois

Share this post


Link to post
Share on other sites
deks is right but here''s more information:

a · b = |a| |b| cos([angle between a and b])

where |v| means the magnitude of the vector v. So if a and b are normalized then their magnitudes are 1 so the dot product just ends up being the cosine of the angle.

The magnitude of the cross-product between the two vectors (cross-product returns a vector) is |a| |b| sin(angle). Good to know.

Interestingly, the angle between something and itself is 0, so the cosine is 1, so the dot-product of a vector with itself is |v| |v|. So if you take the square root of that, you get its magnitude. That is how the magnitude of a vector is calculated:

|v| = sqrt( v.x*v.x + v.y*v.y + v.z*v.z )

See? It''s the square root of the dot product. Neat.

~CGameProgrammer( );

Screenshots of your games or desktop captures -- Upload up to four 1600x1200 screenshots of your projects, registration optional. View all existing ones in the archives..

Share this post


Link to post
Share on other sites
Deks,

I changed my code by adding the acos as follows:


fAngle = (acos((float) D3DXVec3Dot(&vexStarshipDirection, &vecAngleToTarget) )) * 180.0f / 3.14159f;


An it seems to be working for three cases; well the image will explain my question:



_______________________________________
Understanding is a three edged sword...

Independent Games compete Head to Head ...
www.FreelanceGames.com

[edited by - Sean Doherty on April 4, 2004 2:15:44 PM]

Share this post


Link to post
Share on other sites
Yeah, cosine is between -1 and 1, or -180° and 0°. So in other words it covers a span of 180 degrees, not 360. You cannot find the exact angle, unless perhaps you also took the magnitude of the cross-product to find the sine... basically, though, the cosine is good enough. How is it insufficient for you?

~CGameProgrammer( );

Screenshots of your games or desktop captures -- Upload up to four 1600x1200 screenshots of your projects, registration optional. View all existing ones in the archives..

[edited by - CGameProgrammer on April 4, 2004 3:47:18 PM]

Share this post


Link to post
Share on other sites
Ya, looks like method 1 will only return the inner angle. Here is the code to get the angle between 0-360 degress. Thanks All


float dot = vexStarshipDirection.x * vecAngleToTarget.x + vexStarshipDirection.z * vecAngleToTarget.z;
float cross = vexStarshipDirection.x * vecAngleToTarget.z - vexStarshipDirection.z * vecAngleToTarget.x;
fAngle = (atan2(cross,dot) * 180.0f / 3.14159f) + 180.0f;

/*
float dot = A.x * B.x + A.y * B.y;
float cross = A.x * B.y - A.y * B.x;
angle = (atan2(cross, dot) * 180.0f / Pi) + 180.0f;
*/



_______________________________________
Understanding is a three edged sword...

Independent Games compete Head to Head ...
www.FreelanceGames.com

[edited by - Sean Doherty on April 4, 2004 4:18:06 PM]

Share this post


Link to post
Share on other sites