Reputation: 4022
If I know for a fact that the x and z values of the vectors will be identical, therefore im only concerned in measuring the 'vertical' angle of from the differences in the y plane, is there a more efficient method to do this compared to computing the dot product?
My current code using the dot product method is as follows:
float a_mag = a.magnitude();
float b_mag = b.magnitude();
float ab_dot = a.dot(b);
float c = ab_dot / (a_mag * b_mag);
// clamp d to from going beyond +/- 1 as acos(+1/-1) results in infinity
if (c > 1.0f) {
c = 1.0;
} else if (c < -1.0) {
c = -1.0;
}
return acos(c);
I would love to be able to get rid of these square roots
Upvotes: 4
Views: 7026
Reputation: 477640
Suppose that your two vectors live at u = (x, y1, z)
and v = (x, y2, z)
, and you're interested in the planar angle between the two along the plane spanned by the two vectors. You'd have to compute the dot product and the magnitude, but you can save a few operations:
u.v = x.x + y1.y2 + z.z
u^2 = x.x + y1.y1 + z.z
v^2 = x.x + y2.y2 + z.z
So we should precompute:
float xz = x*x + z*z, y11 = y1*y1, y12 = y1*y2, y22 = y2*y2;
float cosangle = (xz + y12) / sqrt((xz + y11) * (xz + y22));
float angle = acos(cosangle);
Upvotes: 3
Reputation: 13356
If the values of x and z are unchanged, then the calculation is very easy: just use basic trigonometry.
Let the points be (x, y1, z)
and (x, y2, z)
. You can find out the angle a vector makes with the ZX-plane. Let the angles be t1
and t2
respectively. Then:
w = sqrt(x^2 + z^2)
tan(t1) = y1 / w
So t1 = atan(y1 / w)
Similarly t2 = atan(y2 / w)
The angle is (t2 - t1)
There's one pitfall: When both x and z are zero, the tan
s are undefined... but such a trivial case can easily be handled separately.
Unfortunately, there seems to be no way to avoid the square root.
Upvotes: 1