Поэтому сейчас я занимаюсь домашним заданием для класса 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)
Вам нужно преобразовать латы /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;
Вы всегда должны быть краткими!
Это было то, что я написал с помощью радианов, если вам разрешено не использовать то, что вам дал ваш учитель. У меня был такой проект, как сейчас, и вытащил формулу с разных сайтов.
#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;
}