Frage

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.

War es hilfreich?

Lösung

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;

Andere Tipps

The atan2 function already takes quadrant into account. In other words, it "knows" that you're in the third quadrant if both x and y are negative. Knowing that, you can see what the angle output for atan2(y, x) is, and then change it to how you want it displayed.

The main reason why Google maps works even with a relatively inaccurate compass is that the structures of the roads give you hints, so you can get by with a bigger error than if you didn't know where the roads were.

Actually, after deciding what quadrant it is I changed code to always calculate atan2 with positive values of x and y - now it works!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top