What is wrong with my calculation? (Math vector problem)

I'm following along with a book I'm reading, though I've decided to implement my own Vector2D struct since that way I can learn better. I've done everything correctly but for some reason the acos() function is getting a number that is outside of its domain which I believe is between -1 and 1 (inclusive). I am currently trying to calculate the angle between two vectors using this formula: cos (theta) = u.v / |u|.|v|

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
float Vector2D::Magnitude(Vector2D& vec1)
{
	return sqrt(pow(vec1.m_x, 2) + pow(vec1.m_y, 2));
}

void Vector2D::Normalize(Vector2D& vec1)
{
	vec1.m_x = vec1.m_x / vec1.Magnitude(vec1);
	vec1.m_y = vec1.m_y / vec1.Magnitude(vec1);
}

float Vector2D::DotProduct(Vector2D& vec1, Vector2D& vec2)
{
	return vec1.m_x * vec2.m_x + vec1.m_y * vec2.m_y;
}

float Vector2D::CalculateAngleTheta(Vector2D& vec1, Vector2D& vec2)
{
	float Theta = 0.0f, DotProd = 0.0f, Mag1 = 0.0f, Mag2 = 0.0f;

	DotProd = vec1.DotProduct(vec1, vec2);

	Mag1 = vec1.Magnitude(vec1);
	Mag2 = vec2.Magnitude(vec2);
	
	Theta = acos(DotProd / Mag1 * Mag2); // Right here I get -nan(ind)
	return Theta;
}


I worked out everything on a piece of paper and it's right. I went through the code with a debugger and the numbers are correct, I just don't know why the acos() is not working. Does it have to do with the fact that computers use radians?

EDIT: Here's main.cpp just in case (it's a bit messy but I'm just trying to get few things up and running for now)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main()
{
	Vector2D DesiredPosition;
	Vector2D vec1, vec2;

	vec1.SetValue(3, 4);
	vec2.SetValue(4, 3);

	float Angle = 0.0f;

	Angle = vec1.CalculateAngleTheta(vec1, vec2);
	std::cout << Angle << "\n";

	int iTemp = 0;
	cin >> iTemp;
	return 0;
}


EDIT#2: Oh and I tried to normalize my vectors to unit vectors so instead of doing this: u.v / |u|.|v| I tried doing this u.v / 1 * 1 but no luck, the acos() insisted.
Last edited on
Theta = acos(DotProd / Mag1         * Mag2);

should be
Theta = acos(DotProd  /     (Mag1 * Mag2)    );


(I've put some spaces in to try to emphasise the problem - Mag2 is actually being multiplied by, not divided by, in your code.)


Other things
- rather than pow( x, 2 ) use the much simpler and considerably more efficient x * x;
- on lines 8 and 9 you calculate the same thing twice - maybe just calculate the magnitude first and put it in a local variable;
- consider using doubles rather than floats;
- you may have to watch for division by zero if you send it the vector (0,0).
Last edited on
> on lines 8 and 9 you calculate the same thing twice - maybe just calculate
> the magnitude first and put it in a local variable;
actually, you change vecl in line 8, so the computation in line 9 would be incorrect.
so you must use an auxiliar.

Also, vec1.Magnitude(vec1)
¿love to repeat things? You don't use the caller object, ¿why is it a member function then?
(alternatively, ¿why pass a parameter?)

Same for DotProduct()
Topic archived. No new replies allowed.