-1

I'm trying to get the heading angle from two points as shown below, within -180/180 range. Clockwise measures should be positive while counterclockwise should be negative.

;Assume a view from above:
;
;              C
;              |
;              |
;              |
;            , A------->  (A's heading [A is facing this direction])
;        , '    `
;    , '          `
;  D                `
;                     `
;                       `
;                         B

float fAngle = A.GetHeadingAngle(B) ;fAngle will equal 45.0
float gAngle = A.GetHeadingAngle(C) ;gAngle will equal -90.0
float hAngle = A.GetHeadingAngle(D) ;hAngle will equal 150.0 (approx)

I've tried using atan2 and the difference in coordinates of the two points to get the angle:

headingangle = atan2(dy, dx) * (180.0 / MATH_PI);

but it doesn't give the expected results. for example:

expected HeadingAngle = -10.443440
actual HeadingAngle = 107.463173

Can any math gurus help?

cruelflames
  • 33
  • 2
  • 5
  • not sure if this is the problem, but in math (hence also for `atan2`) angles are counterclockwise – 463035818_is_not_an_ai Jan 12 '18 at 14:09
  • And your `GetHeadingAngle` implementation is where? Do you normalize the vector to length 1 before trying to calculate the angle? – grek40 Jan 12 '18 at 14:10
  • Possible duplicate of [Using atan2 to find angle between two vectors](https://stackoverflow.com/questions/21483999/using-atan2-to-find-angle-between-two-vectors) – grek40 Jan 12 '18 at 14:14
  • I'm trying to recreate what the GetHeadingAngle function does (used in the game Skyrim) by writing it in C++. The above is how it should work essentially. I'm not sure whether the vector is normalized in that function – cruelflames Jan 12 '18 at 14:15
  • I'm not a math guru, but you might be able to get some help also on math.stackexchange.com – Leonardo Alves Machado Jan 12 '18 at 14:15
  • @LeonardoAlvesMachado thanks, I just did that – cruelflames Jan 12 '18 at 14:38

2 Answers2

1

You can try something like this:

#include <cmath>
#include <iostream>

struct Obj
{
    double x, y, dir;
    Obj(double x, double y, double dir) :x{ x }, y{ y }, dir{ dir } {}
    double GetHeadingAngle(Obj const &other)
    {
        double heading = std::atan2(other.x - this->x, other.y - this->y) * 180 / 3.1415926535897 - this->dir;
        if (heading < -180) heading += 360;
        if (heading > 180) heading -= 360;
        return heading;
    }
};


int main() 
{
    Obj A(10, 10, 90);

    Obj B(15, 5, 0);
    std::cout << A.GetHeadingAngle(B) << std::endl; // 45

    Obj C(10, 15, 0);
    std::cout << A.GetHeadingAngle(C) << std::endl; // -90

    Obj D(5, 5, 0);
    std::cout << A.GetHeadingAngle(D) << std::endl; // 135

    return 0;
}

https://ideone.com/MyKdOy

Killzone Kid
  • 6,171
  • 3
  • 17
  • 37
0

atan2 will give you an angle relative to the x axis (one of the two polar coordinates). So, to calculate the angle between B and A, calculate B's azimuth, calculate that of A, and subtract one of another (possibly adding or subtracting 2*pi, to reduce result's absolute value).

Note that your definition of angles is the opposite of standard one (the positive direction is usually counter-clockwise), so you'll have to negate the result of atan2 (or, simply, subtract the second azimuth from the first one).

bipll
  • 11,747
  • 1
  • 18
  • 32