Angle between two Vectors 2D
Asked Answered
B

9

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

Braziel answered 19/11, 2012 at 17:27 Comment(5)
Math.Atan2(b.Y - a.Y,b.X - a.X);Plane
@Plane if that's an answer you should post it as an answer.Madelaine
This will probably give you the angle from 0 to the hypotenuse. So, I think you want: Math.PI - anglePlane
Answer to this question may also be of use: https://mcmap.net/q/747436/-angle-measurer-in-cWaldheim
The description of the problem is confusing. Do you want the angle between the vectors or the angle of a right triangle with two vectors?Bazil
B
31

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

Belisle answered 19/11, 2012 at 17:32 Comment(8)
Thx, it works in radians, so I will use MathHelper.ToDegrees((float)angle), of course :).Braziel
Yes, the return value is in radians :)Belisle
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?Osborne
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.Belisle
This is incorrect. This measures the angle of the vector between the end points of vector a and b.Bazil
Not quite incorrect. This answer is correct for the diagram, but incorrect for the "angle between vectors".Bazil
@Bazil I suggest you edit the question instead of downvoting answers that supply what was asked in the question (with a bad title I admit)Belisle
Thank you @Bazil : titles says it all - this answer is wrong and lisency answer should be marked correct.Astonishing
A
10

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);
}
Annihilation answered 24/1, 2015 at 7:57 Comment(0)
S
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

Sigismondo answered 2/7, 2014 at 21:41 Comment(0)
B
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)
Bazil answered 11/11, 2014 at 15:50 Comment(0)
M
3

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

Vector.AngleBetween(vector1, vector2)
Morphine answered 25/5, 2016 at 13:44 Comment(1)
Same answer is already here, although thanks for the interest https://mcmap.net/q/713250/-angle-between-two-vectors-2dBraziel
P
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.

Plane answered 19/11, 2012 at 17:32 Comment(0)
I
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));
Isaacs answered 19/11, 2012 at 17:34 Comment(0)
K
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).

Kinase answered 19/11, 2012 at 17:36 Comment(0)
N
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);
    }
}
Nephelometer answered 19/8, 2022 at 22:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.