0

I wrote this extension method for an 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);
}

It works fine when I am putting in an angle of 0, 90, 180 and 270, then it return a coordinate at the given distance away from the starting point. But when I am starting to go in an angle that do not point exactly North, East etc. Iam getting wrong distances.

Where do I go wrong ? Alternative is there some libraries to use?

Rune Jensen
  • 731
  • 1
  • 8
  • 14
  • Not really sure about this... but... beware of potential integer division – Ian Apr 13 '16 at 12:54
  • `int angle`??? `Double angle` - it's very possible to have, say, `30.51` degree – Dmitry Bychenko Apr 13 '16 at 12:55
  • Try *debugging*.First, what's going wrong - if angle is `90` is OK, try add small *disturbance*, say `91` degree: do you have extra *gain* or *loss* on `distanceX`? What about `distanceY`? Continue with `89` degree; then put `45` - *exactly* before `0` and `90` cases... – Dmitry Bychenko Apr 13 '16 at 13:00
  • `(distanceY / earthRadius) * 180 / Math.PI` you are probably missing a function such as `Sin` or `Cos` – Valentin Apr 13 '16 at 13:03
  • 1
    @RuneJensen Why do you need the `earthRadius`? – Valentin Apr 13 '16 at 13:13
  • @Valentin : Found this formula online, and to be honest i'm not quite sure what I have to do in order to calculate what I want. – Rune Jensen Apr 13 '16 at 13:21
  • @RuneJensen So, what do you want to calculate? Because `point.Y + ((distanceY / earthRadius) * 180 / Math.PI);` looks strange. Can you send a link where did you find the formula? – Valentin Apr 13 '16 at 13:44
  • @Valentin: I start out with a coordinate (55.5, 8.50), I want a method that gives me a new coordinate that is 1000 meters in a given angle away from the starting point. Ill try to find the page – Rune Jensen Apr 13 '16 at 13:54
  • @RuneJensen `55.5, 8.50` are the latitude and longitude, aren't them? – Valentin Apr 13 '16 at 13:55
  • @Valentin: [found the fomula here](http://stackoverflow.com/questions/5151652/how-can-i-get-the-latitude-and-longitude-of-x-meter-from-ref-latitude-and-long) at the Javascript example – Rune Jensen Apr 13 '16 at 14:09

1 Answers1

0

Try this formula. As I consider you should transfer latitude and longitude to radians and then back to degrees.

    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);
    }
Valentin
  • 5,380
  • 2
  • 24
  • 38
  • I tried your formula, as far as I can see, the results are the same as the old one. Do you know a formula to calculate the distance between two coordinates, so I can write a test to verify the result. Currently Iam plotting the points into google maps and use their measurement tool to verify... – Rune Jensen Apr 14 '16 at 09:06
  • @RuneJensen it's curious, can you explain how do you test this? Maybe trouble with setting up the bearing – Valentin Apr 14 '16 at 09:44