Расчет подшипника между двумя CLLocationCoordinate2Ds

Очень «простая» проблема: учитывая два CLLocationCoordinate2Ds, как я могу получить подшипник (как радианы) от первого до второго? Я провел много исследований и исследований по этому вопросу, как с общей проблемой, так и с Objective-C / Cocoa Touch / iOS.

Вот моя реализация:

- (float) getHeadingForDirectionFromCoordinate:(CLLocationCoordinate2D)fromLoc toCoordinate:(CLLocationCoordinate2D)toLoc { float fLat = fromLoc.latitude; float fLng = fromLoc.longitude; float tLat = toLoc.latitude; float tLng = toLoc.longitude; return atan2(sin(fLng-tLng)*cos(tLat), cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(fLng-tLng)); } 

Однако этот метод не возвращает результаты для меня. Если подшипник близок к северу или к югу, кажется, все в порядке, однако любое другое направление, похоже, возвращает несогласованные данные, например:

С 50.405018, 8.437500

К 51.339802, 12.403340

Мой метод возвращает: 5.918441 радианы

Должно быть 1.18660576 радианов

(см. http://www.movable-type.co.uk/scripts/latlong.html и http://www.movable-type.co.uk/scripts/latlong-map.html?lat1=50.405018&long1=8.437500 & lat2 = 51.339802 & long2 = 12.403340 )

Я дважды и тройной проверял правильность формулы. Я также заметил, что проверил множество значений, подобных приведенному выше примеру, некоторые правильные, некоторые неправильные. Я играл с различными модулями или ограничивал возвращаемое значение, также не повезло.

Есть идеи? Есть ли проблема с моим кодом? Может быть, я неправильно понял, как работают математические функции?

Ваша математика правильная, за исключением:

  1. Обязательно преобразуйте fLat , fLon , tLat и tLon в радианы, прежде чем применять к ним любые sin () или cos () . Разделите на 180.0 и умножьте на PI.

  2. Введите дельту между tLng и fLng как tLng-fLng , а не наоборот. Обратите внимание, что эта разница появляется в выражении дважды.

С этими изменениями я получаю радианы 1.18660677830947 с математикой с двойной точностью и значениями в вопросе.

Здесь код, измененный с изменениями, предложенными Ореном Трутнером и от меня:

 #define degreesToRadians(x) (M_PI * x / 180.0) #define radiansToDegrees(x) (x * 180.0 / M_PI) - (float)getHeadingForDirectionFromCoordinate:(CLLocationCoordinate2D)fromLoc toCoordinate:(CLLocationCoordinate2D)toLoc { float fLat = degreesToRadians(fromLoc.latitude); float fLng = degreesToRadians(fromLoc.longitude); float tLat = degreesToRadians(toLoc.latitude); float tLng = degreesToRadians(toLoc.longitude); float degree = radiansToDegrees(atan2(sin(tLng-fLng)*cos(tLat), cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(tLng-fLng))); if (degree >= 0) { return degree; } else { return 360+degree; } } 

Swift 3:

 func getBearing(toPoint point: CLLocationCoordinate2D) -> Double { func degreesToRadians(degrees: Double) -> Double { return degrees * M_PI / 180.0 } func radiansToDegrees(radians: Double) -> Double { return radians * 180.0 / M_PI } let lat1 = degreesToRadians(latitude) let lon1 = degreesToRadians(longitude) let lat2 = degreesToRadians(point.latitude); let lon2 = degreesToRadians(point.longitude); let dLon = lon2 - lon1; let y = sin(dLon) * cos(lat2); let x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon); let radiansBearing = atan2(y, x); return radiansToDegrees(radiansBearing) } 

вы можете использовать мой код .. это работа над моим проектом с микроконтроллером, который использует GPS для данных.

 #define d2r ((22/7.0)/180.0) #define r2d (180.0/(22/7.0)) double get_heading1(double lat1, double long1, double lat2, double long2) { double diff_lat, diff_long; double degree; diff_long =(double) (((long2*1000000)-(long1*1000000))/1000000) * d2r; diff_lat = (double) (((lat2*1000000)-(lat1*1000000))/1000000) * d2r; degree = r2d (atan2(sin(diff_long)*cos(d2r*lat2),cos(d2r*lat1)*sin(d2r*lat2)-sin(d2r*lat1)*cos(d2r*lat2) *cos(diff_long))); if (degree >= 0) { return degree; } else { return 360+degree; } } 
  • Получить имя свойства объекта как строку в Objective-C
  • Попытка рефакторирования сетевого метода с использованием шаблона Singleton в iOS
  • Сколько из «Objective-C», которое я изучаю, является универсальной Objective-C, а не каркасами Apple?
  • Может ли кто-нибудь объяснить функцию списка поиска в NSUserDefaults?
  • Как объединить несколько элементов управления iOS в одном объекте (управление)?
  • Как удалить предупреждение о возврате памяти при вставке большого количества данных в основные данные?
  • Блок освобождается во время NSDictionary (ARC)
  • Разница между @property (nonatomic, readonly) и расширением @property внутри класса?
  • Отмена определенной UILocalNotification
  • Ошибка основных данных с постоянным хранилищем
  • Использование Private Framework: импорт RadioPreferences.h
  • Interesting Posts

    Должны ли подклассы называть назначенный инициализатор в ближайшем суперклассе?

    Применение тени к UITextView.layer?

    Проблема с представлением приложения iOS (не подписана с использованием сертификата подачи Apple)

    Переход UIPageViewController позволяет

    Удалите несколько таблиц из одного запроса, разделив их с точки с запятой

    В какой версии LLVM и XCode мне нужно использовать массивный синтаксис Array в Objective-C?

    Время ожидания запроса ASIHTTPRequest

    React-native: scrollview внутри panResponder

    Как загрузить файл IPA в новый testflight?

    Лучшее место для сохранения изображения, загруженного из Интернета на устройствах iOS?

    Вычисление кумулятивного прироста дает мне более серьезные результаты

    Получение ошибки ACErrorPermissionDenied (код ошибки 7) для Facebook при использовании Social Framework

    Как получить адрес электронной почты для facebook с помощью SLRequest в iOS Social Framework

    Удаление данных iCloud не очищает NSUbiquitousKeyValueStore?

    Несколько приложений из одной базы кода – несколько проектов или целей в Xcode?

    Давайте будем гением компьютера.