Search code examples
androidmathgpsgeolocationgeometry

Find movement turn angle using Location


I need find angle of vehicle turn measured in degrees.

Problem description

Location points update with equal intervals (1 sec). Therefore device makes like 4-5 points during turn. I schematically displayed that on picture.

Is it possible to calculate the angle of turn using Location? If it is possible, how?


What I tried:

  1. Create two geometric vectors from points 3, 4 and 1, 2 respectively and find angle between those vectors. Coordinates of vectors I calculated like Vector1 (lat2 - lat1; lon2 - lon2). Not sure this approach could be applied to Location coordinates.
  2. Use location1.bearingTo(location2). But this doesn't give expected results. Seems like it gives "compass" results. Perhabs I could use it somehow but not sure.
  3. Also tried few trigonometric formulas like here or here or here. They didn't give expected angle.

EDIT: Solution The accepted answer works great. But to complete the answer I have to show that method of angleDifference. This one works for me:

public int getAngleDifference(int currentAngle){
    int r = 0;
    angleList.add(currentAngle);
    if (angleList.size() == 4) {
        int d = Math.abs(angleList.get(0) - angleList.get(3)) % 360;
        r = d > 180 ? 360 - d : d;

        angleList.clear();
    }
    return r;
}

I add points to list untill there're 4 of them and then calculate angle difference between 1st and 4th points for better results.

Hope it will help for someone!


Solution

  • Approach 1 does not work as you described: Lat, Lon are not cartesian coordinates (One degree of longitude expressed in meters is not one degree of latitide, this is only valid at the equator). You would have first to transform to a (local) cartesian system.

    An error is in the drawing: The angle marked with "?" is placed at the wrong side. You most probably want angle: 180 - ? In your example the car ist turning less than 90°, altough your angle shows more than 90°. To understand better make another drawing where the car turns left for only 10 degrees. In your drawing this would be 170°, which is wrong.

    Approach 2) works better, but you need to sum up the angle differences. You have to write yourself a method

    double angleDifference(double angle1, double angle2);
    

    This look easier than it is, although the code is only a few lines long. Make sure that you have some test cases that tests the behaviour when crossing the 360° limit. Example

    (turn from bearing 10 to bearing 350), should either give 20 or -20, depending if you want that the method give sthe absolut evalue or the relative angle