0

Let's say I have 2 coordinates that are ~222.33 meters away from each other :

A: 49.25818, -123.20626
B: 49.25813, -123.2032

Those 2 points makes a segment.

How can I calculate the coordinate of point Z that is X meters away from either A or B but towards the other point?

I already know the distance between my 2 points using System.Device.Location library.

GeoCoordinate A = new GeoCoordinate(49.25818, -123.20626);
GeoCoordinate B = new GeoCoordinate(49.25813, -123.2032);
var distanceInMeters = A.GetDistanceTo(B);
// distanceInMeters = 222.33039783713738

I'm looking for something like this:

GeoCoordinate GetPointTowards(GeoCoordinate fromPoint, GeoCoordinate towardPoint, double distanceInMeter) {
    [???]
}

I think I may need the bearing or something to be able to get the new point location.

Most examples I've found are for iOS, Android or GMaps with specific libraries..

Remi
  • 693
  • 8
  • 17
  • maybe this nuget library can help? https://numerics.mathdotnet.com – jazb Nov 21 '18 at 01:28
  • Could you provide another two coordinates with the correct meters please.. Need to test my logic before posting a Method that you can pass into. – Levon Ravel Nov 21 '18 at 01:48
  • @LevonRavel : {49.25835, -123.21894}, {49.25837, -123.21989}. They are 69.038124262531255 meters away. – Remi Nov 21 '18 at 01:52
  • okay I can post the equation – Levon Ravel Nov 21 '18 at 01:53
  • 1
    https://stackoverflow.com/questions/3225803/calculate-endpoint-given-distance-bearing-starting-point Found this answer hope it helps. It is in kilometers but I think the conversion to meters should be easy enough. – Levon Ravel Nov 21 '18 at 02:26

2 Answers2

2

Here's an outline of how I would do it. With this approach, there is no need to explicitly deal with the difference in units between coordinates and distances because taking the ratio of target to total distance eliminates the unit.

totalDistance = distance in meters between point A and point B.
targetDistance = distance in meters to travel from point A to point B

ratio = targetDistance / totalDistance

diffX = B.X - A.X
diffY = B.Y - A.Y

targetX = A.X + (ratio * diffX)
targetY = A.Y + (ratio * diffY)

But this wouldn't handle the edge cases like being at 179 degrees longitude and adding 3 degrees which would put you at -178 longitude.

Lynn
  • 29
  • 3
0

This is my code converted to C# from http://www.movable-type.co.uk/scripts/latlong.html. The fraction is from 0 to 1 and is the fraction along the distance from the first point to the second point the output position will be. You could always modify it to take a straight distance value.

public static (double Lat, double Lon) IntermediatePoint((double Lat, double Lon) StartPoint, (double Lat, double Lon) EndPoint, double fraction)
    {
        if (fraction < 0 || fraction > 1)
            throw new ArgumentOutOfRangeException();
        double angDist = Distance(StartPoint, EndPoint) / radius;
        double lat1 = StartPoint.Lat * (Math.PI / 180);
        double lon1 = StartPoint.Lon * (Math.PI / 180);
        double lat2 = EndPoint.Lat * (Math.PI / 180);
        double lon2 = EndPoint.Lon * (Math.PI / 180);
        double a = Math.Sin((1 - fraction) * angDist) / Math.Sin(angDist);
        double b = Math.Sin(fraction * angDist) / Math.Sin(angDist);
        double x = a * Math.Cos(lat1) * Math.Cos(lon1) + b * Math.Cos(lat2) * Math.Cos(lon2);
        double y = a * Math.Cos(lat1) * Math.Sin(lon1) + b * Math.Cos(lat2) * Math.Sin(lon2);
        double z = a * Math.Sin(lat1) + b * Math.Sin(lat2);
        double lat3 = Math.Atan2(z, Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2)));
        double lon3 = Math.Atan2(y, x);
        return (lat3 * (180 / Math.PI), lon3 * (180 / Math.PI));
    }
public static double Distance((double Lat, double Lon) point1, (double Lat, double Lon) point2)
    {
        double φ1 = point1.Lat * (Math.PI / 180.0);
        double φ2 = point2.Lat * (Math.PI / 180.0);
        double Δφ = (point2.Lat - point1.Lat) * (Math.PI / 180.0);
        double Δλ = (point2.Lon - point1.Lon) * (Math.PI / 180.0);
        double a = Math.Sin(Δφ / 2) * Math.Sin(Δφ / 2) + Math.Cos(φ1) * Math.Cos(φ2) * Math.Sin(Δλ / 2) * Math.Sin(Δλ / 2);
        double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));

        return radius * c;
    }

radius is a constant representing the Earth's radius in meters.

TrueCP5
  • 358
  • 3
  • 14