2013-05-23 4 views
1

기기 제목에 따라 관심 장소 (POI)를 표시해야하는 iOS 앱을 개발 중입니다. 나는 CLLocationManager을 사용하여 사용자의 위치와 제목을 얻었습니다. 한 쌍의 목적지 좌표가 있습니다. 이것을 바탕으로 나는 어느 분기가 그 것인지를 계산하고 남 (0도)도에서의 편차의 부동 값을도 단위로 반환합니다. 나는 북쪽에는 +/- 180도, 남쪽에는 0도있다. 다음은 코드 스 니펫입니다.두 벡터 사이의 각도 계산?

-(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 ; 
} 

어쨌든 나는 목표가 4 분기에 있지만, 남쪽에서 -93 도인 상황이 있습니다. 나는 길을 잃었고 그 문제를 해결하는 방법을 모른다. ...

편집 : (분기는 + y가 북쪽이고 + x가 동쪽 등등)

p.s .: iPhone의 나침반이 정말 나쁘다는 것을 읽었습니다. 그렇다면 Google지도와 같은 앱이 제대로 작동하고 있습니까?

편집 2 : 각도로 실수했습니다. 과격하게 o에는 동쪽에 -90 도가 있고 서쪽에 90도있다.

+1

사이드 노트 : 부동 소수점을 평등하게 테스트하면 원하는 결과를 얻지 못할 수도 있습니다. – John

+0

네, 정확하게 N/S/E/W를보고있는 것은 장치 정확도가 거의 없기 때문에 "수학적"목적으로 사용했습니다. – raistlin

답변

2

,

angle = atan2(x, -y) * 180.0/M_PI; 

모든 if 문이 필요하고, 모든 사분면에서 작동합니다 공식.


atan2(y, x)는 벡터 (x, y)과 양의 x 축 사이의 각도를 반환, 반환 값은 -pipi 사이에 항상이다. 인수에 (x, -y) 의해 (y, x) 장착

는 벡터가 90도 회전되므로 상기 화학식 결과는 원하던 음극 y 축으로 측정 한 각도가되는 것을 의미한다.


업데이트 (질문에 "EDIT2"에 따라) :을 요구 사항은 다음 공식 "남쪽 = 0 °", "동쪽 = -90 ℃,", "서쪽 = 90 ℃,"인 경우

angle = atan2(-x, -y) * 180.0/M_PI; 
+0

남쪽을 향하고 있습니다. 동쪽은 0도, 서쪽은 +이므로 + 마침내 atan2 (-x, -y)가되어야합니다. 맞습니까? – raistlin

+0

@FilipChwastowski : x> 0, y == 0에 대한 공식은 각도 = 90도이고, 나는 그것이 당신이 원하는 것이라고 생각했습니다. –

+0

nah, 나는 북쪽에 +/- 180 도가 있음을 언급했다.) 결국 +/- 학위 방향이 맞으면 아무도 길을 잃지 않도록 답을 편집 해주세요.) – raistlin

1

atan2 함수는 이미 쿼드런트를 고려합니다. 즉, xy이 모두 음수이면 세 번째 사분면에 있다는 것을 "알고 있습니다". 아는 바로는 atan2(y, x)의 각도 출력이 무엇인지 알 수 있으며 표시 방법을 바꿀 수 있습니다.

Google지도가 상대적으로 부정확 한 나침반을 사용하는 경우에도 주된 이유는 도로의 구조가 힌트를 제공하기 때문에 도로가 어디 있는지 몰랐을 때보 다 더 큰 오류가 발생할 수 있다는 것입니다.

+0

"알고 있습니까?"x * y> 0이면 어떨까요? 상황에 따라 가능합니다 : < 0 or both > 0 ... – raistlin

+0

예. 그래서 atan2에 두 개의 인수를 제공합니다. 'x'와'y'가 모두 음수라면, 여러분은 제 3 사분면에 있습니다. 둘 다 긍정적이면, 사분면 I에 있습니다. atan2의 출력은 pi와 -pi 사이입니다 (제 생각에). 그것이 전체 원형입니다. – John

+0

arctg (alfa)는 항상 -pi/2와 pi/2 사이에 있습니다.) – raistlin

0

실제로 어떤 사분면을 결정했는지 항상 x와 y의 양수 값으로 atan2를 계산하도록 코드를 변경했습니다. 이제 작동합니다! 내가 제대로 볼 경우