2017-09-05 42 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.436554 38.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 =在+ visual + studio中使用+ debugger +)並在每個步驟查看你的計算結果? – 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