I'm developing an iOS app, which has to show POIs (points of interest) depending on device heading. I used CLLocationManager
to get user's location and heading. I have one pair of destination's coordinates. Based on this I'm calculating which quarter is that and returning float value of deviation from south (0 degrees) in degrees. I have -/+180 degrees in the north and 0 in the south. Here is code snippet:
-(float)updateTargetLongitude:(float)lon Latitude:(float)lat{
// //longitude = x
// //latitude = y
NSLog(@"current location = (%.5f, %.5f)", [[NSUserDefaults standardUserDefaults] doubleForKey:@"currentLongitude"], [[NSUserDefaults standardUserDefaults] doubleForKey:@"currentLatitude"]);
float x = lon - [[NSUserDefaults standardUserDefaults] doubleForKey:@"currentLongitude"];
float y = lat - [[NSUserDefaults standardUserDefaults] doubleForKey:@"currentLatitude"];
float angle;
NSLog(@"Searching angle from source (%.5f, %.5f) to destination (%.5f, %.5f)", locationManager.location.coordinate.longitude, locationManager.location.coordinate.latitude, lon, lat);
if (x == 0 && y == 0) {
NSLog(@"you're there already!");
return -0.1;
}
if(x == 0 && y > 0){
NSLog(@"look north");
angle = 180.0;
}
if (x == 0 && y < 0) {
NSLog(@"look south");
angle = 0;
}
if (x > 0 && y == 0) {
NSLog(@"look east");
angle = 90.0;
}
if (x < 0 && y == 0) {
NSLog(@"look west");
angle = -90;
}
if (x > 0 && y > 0) {
NSLog(@"first quarter");
angle = -atan2f(y, x) - M_PI_2;
}
if (x < 0 && y > 0) {
NSLog(@"second quarter");
angle = atan2f(y, x) + M_PI_2;
}
if (x < 0 && y < 0) {
NSLog(@"third quarter");
angle = atan2f(x, y);
}
if (x > 0 && y < 0) {
NSLog(@"fourth quarter");
angle = -atan2f(x, y);
}
NSLog(@"returning radians angle = %.4f for (%.5f, %.5f) :: degrees = %.3f", angle, y, x, angle * 180 / M_PI);
return angle * 180 / M_PI ;
}
Somehow I have situation, when target is in fourth quarter, but is -93 degrees from south. I'm lost and I don't have any idea how to fix that...
edit: by quarter I mean Cartesian coordinate system, where +y is north, +x is east and so on!
p.s.: I've read that iPhone compass is really bad, but if so how app like Google maps is working properly?
edit2: I made a mistake with angles. Oficially o have -90 degrees in east and 90 in west.
If I see it correctly, the formula
angle = atan2(x, -y) * 180.0/M_PI;
should work in all quadrants, making all the if
statements unnecessary.
atan2(y, x)
returns the angle between the vector (x, y)
and the positive x-axis, the return value is always between -pi
and pi
.
Replacing (y, x)
by (x, -y)
in the arguments
means that the vector is rotated by 90 degrees, therefore the result of the above formula
is the angle measured to the negative y-axis, which is what you wanted.
Update (according to "edit2" in the question): If the requirement is "south = 0 deg", "east = -90 deg", "west = +90 deg" then the formula would be
angle = atan2(-x, -y) * 180.0/M_PI;