Entfernungsberechnung
-
Hallo, ich hänge grade bei einer eigentlich recht simplen Herausforderung:
Ich habe zwei Orte am Globus, durch User definiert mit Breiten- und Längengraden jeweils im Format Grad Min Sekunden. Nun möchte zwischen diesen beiden Punkten gemäß meinen mathematischen Kenntnissen die sphärische Entfernung berechnen. Wie stell ich das am gescheitesten an? Mit der Methode, die ich im Nachhinein poste geht es ja wohl nicht. Er liefert mir konstant falsche Ergebnisse wenngleich ich es bereits geschafft habe, dass er annähernd richtige Ergebnisse liefert zb Berlin Lissabon: 2132 km. / Tatsächlich: 2317 km. Das kann aber an den Koordinaten selbst gelegen haben, diese weichen geringfügig vom Beispiel, welches ich mir angesehen habe ab.
Meine Beobachtungen: Mit steigendem positiven Längengrad erhöht sich die Entfernung, allerdings auch mit sinkendem Längengrad zb. -9 zu -74 (New York). Gestestet auch: Wien London: lt. Programm: 14676 / Wien Berlin: lt. Programm: 18608 km. Ich habe aber auch nichts gescheites für C++ via Google gefunden, wohl einige Ansätze, aber die helfen mir persönlich nicht weiter. Möglich ist, dass ich einfach einen mathematischen Denkfehler habe... Kommentar zu DEG-0.24.. das habe ich deswegen versucht, weil ich bei Lissabon Longitude -9 7' 59'' ja nicht auf -9.1142 Grad Dezimal komme, sondern auf -8.86, weil er doch 9 abzieht am Ende. Wie auch immer, es dürfte da im Ganzen was nicht so ganz hinkommen. Bitte um Hilfe! Danke vorab und LG Martin// Program Name: Distance Calculator #include <iostream> #include <stdlib.h> // Systemlibrary #include <unistd.h> #include <stdio.h> #include <fstream> #include <string.h> #include <cmath> using namespace std; int main() { string startp; double startpLatDEG; double startpLatMin; double startpLatSec; double startpLonDEG; double startpLonMin; double startpLonSec; string destp; double destpLatDEG; double destpLatMin; double destpLatSec; double destpLonDEG; double destpLonMin; double destpLonSec; double startpLat; double startpLon; double destpLat; double destpLon; double distkm; double dist; cout << "Welcome to the Distance Calculator! This program enables a quick calculation of any distance around the globe! Note that the result is given as the air distance!" << endl << endl; cout << "Please choose the airport you want to start at: "; getline(cin, startp); cout << "Please choose your destination: "; getline(cin, destp); cout << "Please define the location of the starting airport. This is necessary to plan the best route to your destination! Needed parameters: Latitude in degrees, minutes and seconds. The same for Longitude: "; cout << "Degrees: "; cin >> startpLatDEG; cout << "Minutes: "; cin >> startpLatMin; cout << "Seconds: "; cin >> startpLatSec; cout << "Longitude Degrees: "; cin >> startpLonDEG; cout << "Minutes: "; cin >> startpLonMin; cout << "Seconds: "; cin >> startpLonSec; cout << "Now please do the same for your selected destination: "; cout << "Degrees: "; cin >> destpLatDEG; cout << "Minutes: "; cin >> destpLatMin; cout << "Seconds: "; cin >> destpLatSec; cout << "Longitude Degrees: "; cin >> destpLonDEG; cout << "Minutes: "; cin >> destpLonMin; cout << "Seconds: "; cin >> destpLonSec; cout << "Thank you very much! The distance will now be calculated!" << endl << endl; sleep(7); /* Hier: Konvertierung Daten in Dezimaldaten und Entfernungsberechnung (Luftlinie)! */ // Problem: Minuswerte bei Grad! // Startpunkt (grad positiv): if(startpLatDEG >= 0) { startpLat = (((startpLatSec/60)+startpLatMin)/60)+startpLatDEG; } if(startpLonDEG >= 0) { startpLon = (((startpLonSec/60)+startpLonMin)/60)+startpLonDEG; } // Endpunkt (Grad positiv): Herausforderung. if(destpLatDEG >= 0) { destpLat = (((destpLatSec/60)+destpLatMin)/60)+destpLatDEG; } if (destpLonDEG >= 0) { destpLon = (((destpLonSec/60)+destpLonMin)/60)+destpLonDEG; } // Startpunkt (Grad negativ) if(startpLatDEG < 0) { startpLat = (((startpLatSec/60)+startpLatMin)/60)+startpLatDEG-0.24726; // Korrekter Wert z.b Lissabon -9 Grad } if(startpLonDEG < 0) { startpLon = (((startpLonSec/60)+startpLonMin)/60)+startpLonDEG-0.24726; } // Endpunkt (Grad negativ) if(destpLatDEG < 0) { destpLat = (((destpLatSec/60)+destpLatMin)/60)+destpLatDEG-0.24726; } if(destpLonDEG < 0) { destpLon = (((destpLonSec/60)+destpLonMin)/60)+destpLonDEG-0.24726; } cout << "Starting Point: " << startpLat << " " << startpLon << endl << "Destination Point: " << destpLat << " " << destpLon << endl << endl; cin.get(); // Entfernung (6378.388 * acos(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(lon2 - lon1))): distkm = 6378.388 * acos(sin(startpLat) * sin(destpLat) + cos(startpLat) * cos(destpLat) * cos(destpLon - startpLon)); // Konvertiere Entfernung in Kilometer in Meilen: double distparameter = 0.621371192237334; dist = distkm*distparameter; cout << "The distance between " << startp << " and " << destp << " is " << dist << "miles. Or " << distkm << "Kilometers" << endl << endl << "Press 'Enter' to close the program!" << endl; cin.get(); return 0; }
-
ohne mir code und berechnung genauer anzusehen, das wichtigste bei den winkelfunktionen ist, den winkel in
rad
anzugeben, und nicht in grad.
-
Mach dir als allererstes eine Funktion degMinSec2float: ganzzahl-grad, minute, sekunde -> floatingpoint-grad. Also die sowas abbildet: f(60,30,0) = 60.5. Damit konvertierst du die "komischen" Winkelangaben in "normale" Fließkommazahlen. Diese danach mit Pi/180 multiplzieren, um Bogenmaß zu berechnen. Und danach bei Wikipedia unter http://en.wikipedia.org/wiki/Great-circle_distance nachgucken, welche Formel wenig Rundungsfehler hat
-
vielleicht hilft Dir das:
https://en.wikipedia.org/wiki/Haversine_formula
-
Exakter wohl so:
http://www.movable-type.co.uk/scripts/latlong-vincenty.html