2017-09-05 11 views
1

これらの座標を入力すると間違った出力が得られます。関数が間違った値を出力します

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); 
} 

次に、座標を入力する関数です。 41.507483 -99.43655438.504048 -98.315949。これらの座標は約347と等しいはずですが、代わりに出力が7022,88になっていますが、これは間違っており、理由は何も分かりません。

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

あなたは(https://www.google.com [ステップスルーするためにデバッガを使用]みました/ search?q = +デバッガ+ in + visual + studio)を使用して、各ステップで計算を確認します。 – Reddog

+6

実装しようとしている数式は何ですか?また、あなたのメソッドが 'ReadCoordinateFromConsole'と呼ばれる理由は何ですか? –

+0

同じ入力を使って、正確なコードを使用しましたが、347.328を得ました...そして、数式が正しいように見えるので、間違っていることを理解できません。 –

答えて

3

あなたのアルゴリズムは正しいですが、あなたの解析結果は間違っています。

はここでデモです:http://rextester.com/IEEA93176

その理由は,で実行をrextester文化に小数点区切り文字として使用されていること、である - そして私はあなたの環境でその同じことを前提としています。あなたが,を予期している文化の中でdouble.parse("41.1234")を使用すると、411234ではなく、41.1234という値が得られます。

一つの修正は

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

ライブデモ(作業)の文化を強制することです:http://rextester.com/KALRN89806

2

Haversine formulaの実装には何も問題はありません。正しい出力が生成されます。

次のプリント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); 
     } 
    } 
} 

したがって、あなたのエラーのために別の場所を調べなければなりません。私はメソッドに正しい値を与えていないと思います。何が起きているのかを判断するために、デバッガでコードをシングルステップすることをお勧めします。

ちなみに.Net GeoCoordinateクラスを使って計算していない理由はありますか?例:

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); 
     } 
    } 
} 

これは347.628192006498を表示します。

+1

実例を実演しています:http://rextester.com/IHTKZ95967 – Jamiec

関連する問題