2017-09-05 3 views
1

Immer wenn ich diese Koordinaten eingib, bekomme ich eine falsche Ausgabe.Die Funktion gibt den falschen Wert aus

static double ReadCoordinateFromConsole(double lat1, double lon1, double 
lat2, double lon2) 
{ 
    var R = 6371; // Radius of the earth in km 
    var dLat = deg2rad(lat2 - lat1); 
    var dLon = deg2rad(lon2 - lon1); 
    var a = 
     Math.Sin(dLat/2) * Math.Sin(dLat/2) + 
     Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * 
     Math.Sin(dLon/2) * Math.Sin(dLon/2); 
    var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); 
    var d = R * c; // Distance in km 
    return d; 
} 

static double deg2rad(double deg) 
{ 
    return deg * (Math.PI/180); 
} 

Dann in meiner Funktion, wo ich einige Koordinaten eingeben. 41,507483 -99,436554 38,504048 -98,315949. Diese Koordinaten sollten ungefähr gleich 347 sein, aber stattdessen bekomme ich die Ausgabe 7022,88, was falsch ist und ich habe keine Ahnung, warum.

static double ReadDoubleFromConsole(string msg) 
while (true) 
{ 
    Console.Write(msg); 
    string test = Console.ReadLine(); 
    string[] words = test.Split(' '); 
    bool inputContainsNumber = Regex.IsMatch(words[0], @"^-*[0-9,\.]+$"); 
    bool inputContainsNumber2 = Regex.IsMatch(words[1], @"^-*[0-9,\.]+$"); 
    bool inputContainsNumber3 = Regex.IsMatch(words[2], @"^-*[0-9,\.]+$"); 
    bool inputContainsNumber4 = Regex.IsMatch(words[3], @"^-*[0-9,\.]+$"); 
    if(inputContainsNumber && inputContainsNumber2 && inputContainsNumber3 
    && inputContainsNumber4) 
    { 
     double test1 = double.Parse(words[0]); 
     double test2 = double.Parse(words[1]); 
     double test3 = double.Parse(words[2]); 
     double test4 = double.Parse(words[3]); 
     double test5 = ReadCoordinateFromConsole(test1, test2, test3, 
     test4); 
     return test5; 
    } 
    Console.WriteLine("hmm, doesn't look correct - try again"); 
} 
} 
+6

Haben Sie versucht, [den Debugger mit dem Schritt Durch] (https://www.google.com/search? q = benutze + den + Debugger + in + visual + studio) und siehst deine Berechnungen bei jedem Schritt? – Reddog

+6

Was ist die mathematische Formel, die Sie implementieren möchten? Auch warum heißt Ihre Methode 'ReadCoordinateFromConsole', wenn sie das nicht tut? –

+0

Ich habe den genauen Code, den Sie verwenden, mit der gleichen Eingabe und bekam 347.328 .... und die Formel sieht richtig aus, so verstehe ich nicht, was Sie falsch machen. –

Antwort

3

Wie Sie durch die andere Antwort gezeigt haben, ist Ihr Algorithmus korrekt - Ihre Analyse der Benutzereingabe ist falsch!

Hier ist die Demonstration: http://rextester.com/IEEA93176

Und der Grund ist, dass in der Kultur, die Läufe in den , rextester als Dezimaltrennzeichen verwendet wird - und ich nehme an seine gleich in Ihrer Umgebung. Wenn Sie double.parse("41.1234") in einer Kultur verwenden, die , erwartet, erhalten Sie den Wert 411234 nicht 41.1234.

Ein Fix ist die Kultur

System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB"); 

Live-Demo zu zwingen (in Betrieb): http://rextester.com/KALRN89806

2

Es ist nichts falsch mit Ihrer Implementierung der Haversine formula - es erzeugt die korrekte Ausgabe.

Folgende Drucke 347.328348039426:

using System; 

namespace ConsoleApp1 
{ 
    class Program 
    { 
     static void Main() 
     { 
      Console.WriteLine(ReadCoordinateFromConsole(41.507483, -99.436554, 38.504048, -98.315949)); 
     } 

     static double ReadCoordinateFromConsole(double lat1, double lon1, double 
      lat2, double lon2) 
     { 
      var R = 6371; // Radius of the earth in km 
      var dLat = deg2rad(lat2 - lat1); 
      var dLon = deg2rad(lon2 - lon1); 
      var a = 
       Math.Sin(dLat/2) * Math.Sin(dLat/2) + 
       Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * 
       Math.Sin(dLon/2) * Math.Sin(dLon/2); 
      var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); 
      var d = R * c; // Distance in km 
      return d; 
     } 

     static double deg2rad(double deg) 
     { 
      return deg * (Math.PI/180); 
     } 
    } 
} 

Daher müssen Sie an anderer Stelle für Ihre Fehler suchen. Ich vermute, dass Sie der Methode nicht die richtigen Werte zuführen - ich empfehle Ihnen, Ihren Code im Debugger einzustufen, um festzustellen, was passiert.

Übrigens gibt es einen Grund, warum Sie nicht die .Net GeoCoordinate Klasse verwenden, um dies zu berechnen? Zum Beispiel:

using System; 
using System.Device.Location; 

namespace ConsoleApp1 
{ 
    class Program 
    { 
     static void Main() 
     { 
      var a = new GeoCoordinate(41.507483, -99.436554); 
      var b = new GeoCoordinate(38.504048, -98.315949); 

      Console.WriteLine(a.GetDistanceTo(b)/1000.0); 
     } 
    } 
} 

Diese Drucke 347.628192006498.

+1

Sogar ein Live-Beispiel, das es demonstriert, funktioniert: http://rexttester.de/IHTKZ95967 – Jamiec

Verwandte Themen