Tom Tetlaw
Tom Tetlaw

Reputation: 113

Different methods for finding angle between two vectors

Last year I learnt at a school, in a C++ game dev class, that to find the angle between two vectors you could use this method:

vec2_t is defined as: typedef float vec2_t[2]; vec[0] = x and vec[1] = y

float VectorAngle(vec2_t a, vec2_t b)
{
    vec2_t vUp;
    vec2_t vRight;
    vec2_t vDir;
    float dot, side, angle;

    VectorCopy(vUp, a);
    VectorNormalize(vUp);

    VectorInit(vRight, -vUp[1], vUp[0]);

    VectorCopy(vDir, b);
    VectorNormalize(vDir);

    dot = VectorDot(vUp, vDir);
    side = VectorDot(vRight, vDir);
    angle = acosf(dot);

    if(side < 0.0f)
        angle *= -1.0f;

    return angle;
}

Then just yesterday while looking for a solution to something else I found you could use this method instead:

float VectorAngle(vec2_t a, vec2_t b)
{
    return atan2f(b[1]-a[1], b[0]-a[0]);
}

This seems much more simple to implement... my question is, why would one favour one method over the second one when the second one is much more simple?

EDIT: Just to make sure: If vector a is [100, 100] and vector b is [300, 300] then method 2 returns 0.78539819 radians, is this correct?

Upvotes: 0

Views: 5780

Answers (4)

Open AI - Opting Out
Open AI - Opting Out

Reputation: 24133

You can use complex numbers for 2d vector calculations. Multiplication of complex numbers can be seen as a positive rotation, and division as a negative rotation. We want to use division as it acts to subtract one angle from the other:

#include <complex>

int main() {
    using std::complex;
    using std::arg;

    complex<double> a, b;

    double angle = arg(a/b);

    return 0;
}

Upvotes: 0

Pavel Zhuravlev
Pavel Zhuravlev

Reputation: 2791

The second method calculates the geometric difference vector for b and a (b-a) and returns the angle between this difference and X axis, Obviously such angle is not generelly equal to angle between a and b.

Upvotes: 2

alexm
alexm

Reputation: 6882

A method I find usable:

        // cross product
        double y = (v1[0] * v2[1]) - (v2[0] * v1[1]);

        // dot product
        double x = (v1[0] * v2[0]) + (v1[1] * v2[1]);

        return atan2(y, x);

Upvotes: 3

perreal
perreal

Reputation: 97918

Compare the acosf source to atanf2f source to see difference in implementations. The latter uses a table which might be infeasible for some systems.

Upvotes: 1

Related Questions