2016-04-13 2 views
0

Я написал этот метод расширения для IPoint.Вычисление координаты по углу и расстоянию от координаты

public static IPoint Offset(this IPoint point, double angle, double distanceInMeters) 
{ 
    var radians = Math.PI * angle/180; 
    var distanceX = distanceInMeters * Math.Cos(radians); 
    var distanceY = distanceInMeters * Math.Sin(radians); 
    var earthRadius = 6371000; 

    var y = point.Y + ((distanceY/earthRadius) * 180/Math.PI); 
    var x = point.X + ((distanceX/(earthRadius * Math.Cos(y * 180/Math.PI))) * 180/Math.PI); 


    return new Point(x, y); 
} 

Он отлично работает, когда я ставлю в угол 0, 90, 180 и 270, то возвращают координаты в заданном расстоянии от начальной точки. Но когда я начинаю идти под углом, который не указывает точно Север, Восток и т. Д. Я получаю неправильные расстояния.

Где я могу пойти не так? Альтернатива Есть некоторые библиотеки для использования?

+0

Не совсем уверен в этом ... но ... остерегайтесь потенциального целочисленного деления – Ian

+0

'int angle' ??? 'Double angle' - очень возможно иметь, скажем,' 30.51' степень –

+0

Попробовать * отладка *. Во-первых, что происходит не так - если угол '90' в порядке, попробуйте добавить небольшое * нарушение *, скажем,' 91' степени : у вас есть дополнительный * выигрыш * или * потеря * на 'distanceX'? Что относительно 'distanceY'? Продолжайте с '89' степени; затем положите '45' - * точно * перед случаями' 0' и '90' ... –

ответ

0

Попробуйте эту формулу. Поскольку я считаю, что вы должны перевести широту и долготу в радианы, а затем вернуться к градусам.

public static Point Offset(this Point point, double angle, double distanceInMeters) 
    { 
     double rad = Math.PI * angle/180; 

     double xRad = Math.PI * point.X/180; // convert to radians 
     double yRad = Math.PI * point.Y/180; 

     double R = 6378100; //Radius of the Earth in meters 
     double x = Math.Asin(Math.Sin(xRad) * Math.Cos(distanceInMeters/ R) 
           + Math.Cos(xRad) * Math.Sin(distanceInMeters/ R) * Math.Cos(rad)); 

     double y = yRad + Math.Atan2(Math.Sin(rad) * Math.Sin(distanceInMeters/ R) * Math.Cos(xRad), Math.Cos(distanceInMeters/ R) - Math.Sin(xRad) * Math.Sin(x)); 

     x = x * 180/Math.PI; // convert back to degrees 
     y = y * 180/Math.PI; 

     return new Point(x, y); 
    } 
+0

Я пробовал вашу формулу, насколько я вижу, результаты такие же, как и старые. Вы знаете формулу для вычисления расстояния между двумя координатами, поэтому я могу написать тест для проверки результата. В настоящее время я планирую точки в карты Google и использую их инструмент измерения, чтобы проверить ... –

+0

@ RuneJensen Любопытно, можете ли вы объяснить, как вы это проверяете? Может быть, проблема с настройкой подшипника. – Valentin

+0

Мне нравится [это] (http://s22.postimg.org/mccohv0r5/map.png) –

Смежные вопросы