Рассчитайте опору между двумя точками (lat, long)

Я пытаюсь разработать свой собственный усовершенствованный механизм реальности.

Поиск в Интернете, я нашел этот полезный учебник . Читая его, я вижу, что важная вещь зависит от местоположения пользователя, местоположения точки и севера.

Следующий рисунок из этого учебника.

Введите описание изображения здесь

После этого я написал метод Objective-C для получения бета-версии:

+ (float) calculateBetaFrom:(CLLocationCoordinate2D)user to:(CLLocationCoordinate2D)destination { double beta = 0; double a, b = 0; a = destination.latitude - user.latitude; b = destination.longitude - user.longitude; beta = atan2(a, b) * 180.0 / M_PI; if (beta < 0.0) beta += 360.0; else if (beta > 360.0) beta -= 360; return beta; } 

Но, когда я пытаюсь, это работает не очень хорошо.

Итак, я проверил iPhone AR Toolkit, чтобы посмотреть, как это работает (я работал с этим набором инструментальных средств, но для меня это так много).

И в ARGeoCoordinate.m есть еще одна реализация того, как получить бета-версию:

 - (float)angleFromCoordinate:(CLLocationCoordinate2D)first toCoordinate:(CLLocationCoordinate2D)second { float longitudinalDifference = second.longitude - first.longitude; float latitudinalDifference = second.latitude - first.latitude; float possibleAzimuth = (M_PI * .5f) - atan(latitudinalDifference / longitudinalDifference); if (longitudinalDifference > 0) return possibleAzimuth; else if (longitudinalDifference < 0) return possibleAzimuth + M_PI; else if (latitudinalDifference < 0) return M_PI; return 0.0f; } 

Он использует эту формулу:

 float possibleAzimuth = (M_PI * .5f) - atan(latitudinalDifference / longitudinalDifference); 

Почему (M_PI * .5f) в этой формуле? Я этого не понимаю.

И продолжайте поиск, я нашел другую страницу, рассказывающую о том, как рассчитать расстояние и опору из двух мест. На этой странице есть еще одна реализация:

 /** * Returns the (initial) bearing from this point to the supplied point, in degrees * see http://williams.best.vwh.net/avform.htm#Crs * * @param {LatLon} point: Latitude/longitude of destination point * @returns {Number} Initial bearing in degrees from North */ LatLon.prototype.bearingTo = function(point) { var lat1 = this._lat.toRad(), lat2 = point._lat.toRad(); var dLon = (point._lon-this._lon).toRad(); var y = Math.sin(dLon) * Math.cos(lat2); var x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon); var brng = Math.atan2(y, x); return (brng.toDeg()+360) % 360; } 

Какой из них правильный?

Solutions Collecting From Web of "Рассчитайте опору между двумя точками (lat, long)"

Рассчитать подшипник

 //Source JSONObject source = step.getJSONObject("start_location"); double lat1 = Double.parseDouble(source.getString("lat")); double lng1 = Double.parseDouble(source.getString("lng")); // destination JSONObject destination = step.getJSONObject("end_location"); double lat2 = Double.parseDouble(destination.getString("lat")); double lng2 = Double.parseDouble(destination.getString("lng")); double dLon = (lng2-lng1); double y = Math.sin(dLon) * Math.cos(lat2); double x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon); double brng = Math.toDegrees((Math.atan2(y, x))); brng = (360 - ((brng + 360) % 360)); 

Преобразовать градусы в радианы

 Radians = Degrees * PI / 180 

Преобразование радианов в градусы

 Degrees = Radians * 180 / PI 

Я знаю, что этот вопрос старый, но вот более легкое решение:

Float bearing = loc1.bearingTo (loc2);

В формуле

float possibleAzimuth = (M_PI * .5f) - atan(latitudinalDifference / longitudinalDifference);

(M_PI * .5f) означает π / 2, который равен 90 °. Это означает, что это та самая формула, которую вы указали вначале, потому что в отношении вышеприведенного рисунка

Β = arctan (a / b) = 90 ° – arctan (b / a).

Таким образом, обе формулы аналогичны, если a относится к разности долготы и b в разнице широт. Последняя формула вычисляет снова то же самое, используя первую часть моего уравнения.

a на диаграмме – разность долгот, b – разность широт, поэтому в написанном вами методе вы получили их неправильно.

 a = destination.latitude - user.latitude; // should be b b = destination.longitude - user.longitude; // should be a 

Попробуйте переключить их и посмотреть, что произойдет.

См. Ответ Палунда для ответов на остальные ваши вопросы.

Попробуйте это для точного результата:

 private static double degreeToRadians(double latLong) { return (Math.PI * latLong / 180.0); } private static double radiansToDegree(double latLong) { return (latLong * 180.0 / Math.PI); } public static double getBearing() { //Source JSONObject source = step.getJSONObject("start_location"); double lat1 = Double.parseDouble(source.getString("lat")); double lng1 = Double.parseDouble(source.getString("lng")); // destination JSONObject destination = step.getJSONObject("end_location"); double lat2 = Double.parseDouble(destination.getString("lat")); double lng2 = Double.parseDouble(destination.getString("lng")); double fLat = degreeToRadians(lat1); double fLong = degreeToRadians(lng1); double tLat = degreeToRadians(lat2); double tLong = degreeToRadians(lng2); double dLon = (tLong - fLong); double degree = radiansToDegree(Math.atan2(sin(dLon) * cos(tLat), cos(fLat) * sin(tLat) - sin(fLat) * cos(tLat) * cos(dLon))); if (degree >= 0) { return degree; } else { return 360 + degree; } } 

Вы можете проверить результат подшипника на http://www.sunearthtools.com/tools/distance.php .

Если вы хотите, вы можете взглянуть на код, используемый в движке дополненной реальности mixare, он находится на github, и есть версия для iPhone: github.com/mixare