16

I'm trying to compute the angle between two vectors. I tried this, but it always returns zero:

public double GetAngle(Vector2 a, Vector2 b)
{
    double angle = Math.Atan2(b.Y, b.X) - Math.Atan2(a.Y, a.X);
    return angle;
}

GetAngle(new Vector2(1,1), new Vector2(50,50));

VectorsThe angle I need

Neuron
  • 5,141
  • 5
  • 38
  • 59
Sorashi
  • 931
  • 2
  • 9
  • 32

9 Answers9

30

You should take a look at the documentation of atan2 (here).

What you're looking of is finding the difference between B (your upper left vector) and A (your bottom right vector), then pass this as a parameter to atan2

return Math.Atan2(b.Y - a.Y, b.X - a.X);

What your code currently does is find the angle of the vector b in reference to 0,0 and subtract the angle of the vector a in reference to 0,0.

The reason you always get 0 is because 1,1 and 50,50 are on the same line that crosses 0,0 (both calls return something approx. 0.785398), so subtracting them will result in 0

Neuron
  • 5,141
  • 5
  • 38
  • 59
emartel
  • 7,712
  • 1
  • 30
  • 58
  • 2
    Thx, it works in radians, so I will use MathHelper.ToDegrees((float)angle), of course :). – Sorashi Nov 19 '12 at 17:36
  • 1
    Yes, the return value is in radians :) – emartel Nov 19 '12 at 17:37
  • Would this be the same as subtracting the vectors first to get a directional vector? Then running the Atan2 on the X and Y of the new vector? – Serguei Fedorov Aug 25 '13 at 17:53
  • Yes it's the exact same thing! Visualize a vector (0.5, 0.5) and (-0.5, 0.5) so, respectively 45 and 135 degrees from the X axis. If you subtract both vectors, you will have (1, 0), which is 90 degree from the X axis. – emartel Aug 26 '13 at 03:34
  • 2
    This is incorrect. This measures the angle of the vector between the end points of vector a and b. – RunHolt Nov 11 '14 at 15:48
  • Not quite incorrect. This answer is correct for the diagram, but incorrect for the "angle between vectors". – RunHolt Nov 11 '14 at 15:57
  • @RunHolt I suggest you edit the question instead of downvoting answers that supply what was asked in the question (with a bad title I admit) – emartel Nov 12 '14 at 08:01
  • Thank you @RunHolt : titles says it all - this answer is wrong and lisency answer should be marked correct. – Andrew Feb 04 '22 at 11:20
9

I think code show as below copy from .NET source code could help you.

reference: http://referencesource.microsoft.com/#WindowsBase/Base/System/Windows/Vector.cs,102

/// <summary>
/// AngleBetween - the angle between 2 vectors
/// </summary>
/// <returns>
/// Returns the the angle in degrees between vector1 and vector2
/// </returns>
/// <param name="vector1"> The first Vector </param>
/// <param name="vector2"> The second Vector </param>
public static double AngleBetween(Vector vector1, Vector vector2)
{
    double sin = vector1._x * vector2._y - vector2._x * vector1._y;  
    double cos = vector1._x * vector2._x + vector1._y * vector2._y;

    return Math.Atan2(sin, cos) * (180 / Math.PI);
}
lisency
  • 433
  • 1
  • 5
  • 9
5

A simple solution should be this:

Vector2 a_normalized = normalize(a);
Vector2 b_normalized = normalize(b);
double angle = arccos(dot(a_normalized,b_normalized));

http://simple.wikipedia.org/wiki/Dot_product

This is Pseudo-code, because C# is not my world. Sorry

Alexei
  • 347
  • 2
  • 10
4

if you are looking for the "angle between vectors a and b", you want the delta of the angle for vector a and the angle for vector b:

Math.Atan2(b.Y, b.X) - Math.Atan2(a.Y, a.X)

But the diagram doesn't match "angle between vectors". The answer for the diagram is indeed the previous answer given:

Math.Atan2(b.Y - a.Y, b.X - a.X)
RunHolt
  • 1,892
  • 2
  • 19
  • 26
2

You have to use the difference in x and y inside of the Atan2 method:

Math.Atan2(b.Y - a.Y,b.X - a.X);

Also, I believe this will give you the angle from 0 to the hypotenuse of the triangle you've provided (not entirely sure).

I'd suggest trying Math.PI - angle.

Shmiddty
  • 13,847
  • 1
  • 35
  • 52
2

I'm a bit late to the party, but how about the static method on the Vector class:

Vector.AngleBetween(vector1, vector2)
Darren
  • 4,408
  • 4
  • 39
  • 57
  • Same answer is already here, although thanks for the interest http://stackoverflow.com/a/28123501/1697953 – Sorashi May 25 '16 at 14:06
0

tan(angle) = opposite/adjascent

arctan(opposite/adjascent) = angle

opposite = a.y - b.y

adjascent = b.x - a.x

Math.Atan((a.Y - b.Y) / (b.X - a.X));
doctor killer
  • 392
  • 1
  • 14
0

since you use vector2 class, I guess you can use

a-b

to get the vector from a to b.

so the angle you need is: Pi - angle(a-b).

urlreader
  • 6,319
  • 7
  • 57
  • 91
0
public static class FunAngleCalc
{
    public static double angle(MathPoint p1, MathPoint center, MathPoint p2)
    {
        MathPoint transformedP1 = new MathPoint(p1.x - center.x, p1.y - center.y);

        MathPoint transformedP2 = new MathPoint(p2.x - center.x, p2.y - center.y);
        double angleToP1 = Math.Atan2(transformedP1.y, transformedP1.x);

        double angleToP2 = Math.Atan2(transformedP2.y, transformedP2.x);

        return toDegrees(normaliseToInteriorAngle(angleToP2 - angleToP1));
    }

    private static double normaliseToInteriorAngle(double angle)
    {
        if (angle < 0)
        {
            angle += (2 * Math.PI);
        }
        if (angle > Math.PI)
        {
            angle = 2 * Math.PI - angle;
        }
        return angle;
    }

    private static double toDegrees(double radians)
    {
        return 360 * radians / (2 * Math.PI);
    }
}
Ahmet Firat Keler
  • 2,603
  • 2
  • 11
  • 22
Hesham Yemen
  • 437
  • 5
  • 6