Reputation: 1060
I need find angle of vehicle turn measured in degrees.
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:
Vector1 (lat2 - lat1; lon2 - lon2)
. Not sure this approach could be applied to Location coordinates.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.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!
Upvotes: 3
Views: 1924
Reputation: 1675
vect1 = LatLon2 - LatLon1; // vector subtraction
vect2 = LatLon4 - LatLon3;
By definition of the dot product has the property:
vect1.vect2 = ||vect1||*||vect2||*Cos(theta)
The term vect1.vect2
is the dot product of vect1
and vect2
.
The general form of a dot product can be broken down component wise let v1 = <x1,y1>
and v2=<x2,y2>
for two arbitrary vectors v1
and v2
the dot product would be:
v1.v2 = x1*x2 + y1*y2
and the magnitude of some arbitrary vector v
is:
||v|| = sqrt(v.v); which is a scalar.
The above is equivalent to the Euclidean distance formula with components x and y:
||v|| = sqrt(x^2 + y^2)
Find a value for theta
given the two vectors vect1
and vect2
:
theta = Math.ArcCos(vect1.vect2/(||vect1||*||vect2||))
Upvotes: 2
Reputation: 28737
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
Upvotes: 1