Calculating the Angle of a Vector2 from zero

Here is an example if what I want.


I’ve tried this code:

			float vectorAngle = 0; 
			if(InputC.TorqueVector != Vector2.zero)
				vectorAngle = Vector2.Angle(InputC.TorqueVector - vectorZero, vectorZero)-90;
			vectorAngle = 360-vectorAngle;

where vectorZero is (0,1) and TorqueVector is the vector i’m trying to measure the angle of.
with this i’m able to get most vectors to work except vectors with -y components.
what am i doing wrong?

Edit:
My New code is:

			float vectorAngle = Mathf.Acos(Mathf.Deg2Rad*InputC.TorqueVector.x);
			vectorAngle *= Mathf.Rad2Deg;
			if(InputC.TorqueVector.y < 0)
				vectorAngle*= -1;

This works correctly for vectors (-20,0) & (20,0)
but for vectors (0,0),(0,20),(0,-20) i get angles near 90.
what am i missing?

Just in case if someone will search for a solution and will find this topic via google, here is the working solution: public float GetAngleFromVector(Vector2 vector) { vector = vector.normalized; float angle = Mathf.Atan2(vector.y, vector.x) * Mathf.Rad2Deg; return (angle < 0) ? angle + 360 : angle; }

2 Answers

2

Here is my solution:

public static float Angle(Vector2 vector2)
{
    if (vector2.x < 0)
    {
        return 360 - (Mathf.Atan2(vector2.x, vector2.y) * Mathf.Rad2Deg * -1);
    }
    else
    {
        return Mathf.Atan2(vector2.x, vector2.y) * Mathf.Rad2Deg;
    }
}

Edit: Adding a Mathf.Sign to return 1 or -1 and keep the math in just one line. Thanks @jardineiro

public static float Angle(Vector2 vector2)
{
    return 360 - (Mathf.Atan2(vector2.x, vector2.y) * Mathf.Rad2Deg * Mathf.Sign(vector2.x));
}

Thanks. This was very helpful. One note: You can simplify a bit with Mathf.Sign to return 1 or -1 based on the sign of the x value. public static float Angle(Vector2 p_vector2) { return 360 - (Mathf.Atan2(p_vector2.x, p_vector2.y) * Mathf.Rad2Deg * Mathf.Sign(p_vector2.x)); } }

The first solution works very well, but the simplified one (the second one) only returns 180+ values for me.

The angle of a 2D vector can be calculated a number of ways. Mathf.ACos(InputC.TorqueVector.x) or Mathf.ASin(InputC.TorqueVector.y) will get you the angle, relative to 0, but it will not retain the sign. In other words, if the actual angle is pi/4 or -pi/4, the answer you’ll get back will be pi/4. To rectify this, simply check the sign of the y-coordinate. If it is positive, the angle will remain positive, if it is negative, multiply the angle by -1.

The same issue comes up with Vector2.Angle(). So the answer you’re getting is correct, given what you’ve told it to do. You just need to account for the y-coordinate’s sign.

NOTE: If you’re going to use the trig functions in Mathf, if you’re inputting an angle, CONVERT TO RADIANS, FIRST. Despite the Vector classes giving angles in degrees, and some rotation-functions operating in degrees, check the specific documentation for each class before assuming the input or returned values will be in either degrees or radians.

[EDIT] I noticed there were a few mistakes in my logic, here. First, the value you’re looking for is an angle. The value you’re plugging in is a coordinate. Only convert to radians if you’re inputting an angle. Secondly, it is typically more accurate to use ATan than ACos or ASin, as it takes both coordinates into account. If you have a zero-vector, either do nothing (because technically there -is- no angle) or return 0.

This makes a lot more sense i noticed that it was only giving me a 4th of what i need when i tried some stuff with Asin, i'm going to try this. Thanks

This worked partially, i've updated the question with the new issue.

Updated the answer. I dun made some mistakes in my calculations, and there was at least one I hadn't touched on, with the programming of this (zero vector and zero coordinates).

use Atan(y/x) works a lot better, thanks and to fix my issue i just added 180 to the angle when y is negative and multiply by -1 when x is negative