Проблемы с результатом вычисления широты / долготы по формуле haversine в C ++

0

Поэтому сейчас я занимаюсь домашним заданием для класса C++. В задании говорится, что мне нужно рассчитать расстояние между двумя местами, используя формулу haversine, основанную на вводе степеней, заданных пользователем для долготы и широты. Затем формула haversine вычисляет расстояние между двумя местами.

Проблема, с которой я сталкиваюсь, заключается в использовании тестовых значений, данных инструктором, я получаю больший ответ, чем то, что он получает.

Я рассчитываю расстояние между 33.9425/N 118.4081/W (аэропорт Лос-Анджелеса) и 20.8987/N 156.4305/W (аэропорт Кахулуи), где аэропорт Лос-Анджелеса является исходным местом.

Его ответ на расстояние составляет 2483,3 миль. Мой ответ - 2052,1 миль.

Вот мой код для формулы haversine:

double haversine(double lat1, double lat2, double lon1, double lon2) {
    // get differences first
    double dlon = difference(lon1, lon2); // difference for longitude
    double dlat = difference(lat1, lat2); // difference for latitude
    // part a of algorithm
    double a = pow(sin(dlat/2), 2) + cos(lat1) * cos(lat2) * pow(sin(dlon/2), 2);
    // part b of algorithm
    double b = 2 * atan2(sqrt(a), sqrt(1 - a));
    // our result, or the great-circle distance between two locations
    double result = EARTH_RADIUS * b;
    return result;
}

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

Обновление: Исправлена проблема, преобразовывая долготу и широту в радианах. В C++ я сделал это, определив PI = 3.14159265 и для каждой используемой функции триггера, умножив все, что было там * PI/180. (т.е. pow (sin ((dlat/2) * (PI/180)), 2)

Теги:
latitude-longitude
distance
haversine

2 ответа

2
Лучший ответ

Вам нужно преобразовать латы /longs в радианы, потому что триггерные функции в Java принимают радианские аргументы.

public static double haversine(double lat1, double lon1, double lat2, double lon2) {
    double dLat = Math.toRadians(lat2 - lat1);
    double dLon = Math.toRadians(lon2 - lon1);
    lat1 = Math.toRadians(lat1);
    lat2 = Math.toRadians(lat2);

И эта строка:

// part b of algorithm
double b = 2 * atan2(sqrt(a), sqrt(1 - a));

это то же самое, что и

// part b of algorithm
double b = 2 * Math.asin(Math.sqrt(a));

Теперь ваша функция должна работать. (:

Кроме того, для дальнейшего использования:

// our result, or the great-circle distance between two locations
double result = EARTH_RADIUS * b;
return result;

Следует сократить до:

// our result, or the great-circle distance between two locations
return EARTH_RADIUS * b;

Вы всегда должны быть краткими!

  • 0
    Будет ли C ++ иметь такую же проблему? То есть. просто нужно перевести мои широты и долготы в радианы?
0

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

#include <iostream>

using namespace std;

static const double DEG_TO_RAD = 0.017453292519943295769236907684886;
static const double EARTH_RADIUS_IN_METERS = 6372797.560856;
static const double EARTH_RADIUS_IN_MILES = 3959;

struct Position {
    Position(double lat, double lon) : _lat(lat), _lon(lon) {}
    void lat(double lat) { _lat = lat; }
    double lat() const { return _lat; }
    void lon(double lon) { _lon = lon; }
    double lon() const { return _lon; }
private:
    double _lat;
    double _lon;
};

double haversine(const Position& from, const Position& to) {
    double lat_arc = (from.lat() - to.lat()) * DEG_TO_RAD;
    double lon_arc = (from.lon() - to.lon()) * DEG_TO_RAD;
    double lat_h = sin(lat_arc * 0.5);
    lat_h *= lat_h;
    double lon_h = sin(lon_arc * 0.5);
    lon_h *= lon_h;
    double tmp = cos(from.lat()*DEG_TO_RAD) * cos(to.lat()*DEG_TO_RAD);
    return 2.0 * asin(sqrt(lat_h + tmp*lon_h));
}

double distance_in_meters(const Position& from, const Position& to) {
    return EARTH_RADIUS_IN_METERS*haversine(from, to);
}

double distance_in_miles(const Position& from, const Position& to)
{
    return EARTH_RADIUS_IN_MILES*haversine(from, to);
}

int main()
{
    double meters   = distance_in_meters(Position(33.9425, 118.4081), Position(20.8987, 156.4305));
    double miles    = distance_in_miles(Position(33.9425, 118.4081), Position(20.8987, 156.4305));
    cout << "\nDistance in meters is: " << meters;
    cout << "\nDistance in miles is: " << miles;


    cout << endl;
    system("PAUSE");
    return 0;
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню