# Calculate the angle between two 3d vectors: Function always returns 89.1-89.9

I have my own 2d game and I am attempting to calculate the angle between 2 GameObjects.

My Problem: My function that is meant to calculate the angle(direction) between 2 Vector3's doesn't appear to be correctly calculating the angle. It always returns a value thats between 89.1 and 89.9, its never any other value.

What am I doing wrong? Can you help me to get my function to correctly calculate the angle between 2 Vector3's?

float getAngle(Vector3 p1, Vector3 p2) {

// If p1 or p2 == Vector3.zero then this funciton wont work. What shd I do in this case?

float coefI  = p1.x * p2.x;
float coefJ  = p1.y * p2.y;
float coefK  = p1.z * p2.z;
float scalar = coefI + coefJ + coefK;
float magnitude1 = p1.sqrMagnitude;
float magnitude2 = p2.sqrMagnitude;

Debug.Log (System.String.Format ("{0}, {1}, {2}, {3}, {4}, {5}", coefI, coefJ, coefK, scalar, magnitude1, magnitude2));
return (Mathf.Acos ( scalar / (magnitude1 * magnitude2) ) * Mathf.Rad2Deg); // Always returns between 89.1 and 89.9 for some reason
}

void Update() {
Debug.Log( getAngle (Input.mousePosition, transform.position) );
}

• Log the value of the normalized dot product: scalar / (magnitude1 * magnitude2). If one of the vectors is zero, simply return 0. It does make some sense for a simulation: the zero vector is aligned with any other 3D vector so.. in a way, their angle is zero. – teodron Aug 17 '12 at 8:53
• @teodron so your saying to calculate the angle I shd log it and not use Acos? – Mack Aug 17 '12 at 8:55
• No, try and see if you get some sensibly different dot product values that you feed to the acos function. If that's the case, i.e. they're pretty close as well, the vectors are indeed almost perpendicular and you should look somewhere where the function is called.. – teodron Aug 17 '12 at 8:59
• If you insist on writing your own dot product calculation, at least order the operations so that they can more easily be optimised to use fused multiply-add: p1.x * p2.x + (p1.y * p2.y + (p1.z * p2.z)) – Martin Sojka Aug 17 '12 at 9:31
• @teodron: Unity has several scripting languages; the one here is C#, based on MonoDevelop. C#'s runtime will have support for FMA when the consumer-grade CPUs support it better (first ones will be here in this year from AMD and next year from Intel; consumer-grade GPUs support it for a while now, which is important if you use GPGPU), but as usual the optimisation will not kick in for all but the most obvious cases until some time after that, so it's better to help the VM along. It's not like the "optimised" version is any harder to read ... – Martin Sojka Aug 17 '12 at 9:52

sqrMagnitude is the vector length squared, but you need the vector lengths. Simple fix:
return (Mathf.Acos ( scalar / Mathf.Sqrt (magnitude1 * magnitude2) ) * Mathf.Rad2Deg);