-2

I am trying to implement a function that will give me the GEO location (Lat,Long) given 3 GEO reference points and radius away from each point.

The signature for the function I'm looking for is:

public static GeoLocation Triangle(GeoLocation pos1, double r1, GeoLocation pos2,
                                   double r2, GeoLocation pos3, double r3)

As example, 3 friends meet up somewhere secret. Each one can only tell me where he/she lives (GeoLocation = lat,long) and how far they are meeting from their house (r = radius). Given 3 such reference points (from all 3 friends), I should have sufficient information to calculate this secret meeting point as a GeoLocation.

This problem is very similar to the mobile / towers problem where you triangulate a mobile by measuring individual signal strengths from a few towers.

I have tried to find formulas online for quite some time now, which is why I'm posting my question here on Stack Overflow.

I will appreciate it if you could help me fill in the formula (Triangle method) - Thanks.

Code I have so far:

public class GeoLocation
{
    private double _latitude;
    private double _longitude;

    public GeoLocation(double latitude, double longitude)
    {
        this._latitude = latitude;
        this._longitude = longitude;
    }

    //Tested and working!
    public double DistanceToKm(GeoLocation loc)
    {
        double lat1, lon1, lat2, lon2;
        lat1 = this._latitude;
        lon1 = this._longitude;
        lat2 = loc._latitude;
        lon2 = loc._longitude;
        var R = 6371; // Radius of the earth in km
        var dLat = deg2rad(lat2 - lat1); // deg2rad below
        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;
    }
}

Code which I think is not needed, but for what it's worth:

public static Coords ToCoord(GeoLocation pos)
{
    var x = Math.Cos(pos._longitude) * Math.Cos(pos._latitude);
    var y = Math.Sin( pos._longitude) * Math.Cos(pos._latitude);
    var z = Math.Sin(pos._latitude);
    return new Coords(x,y,z);
}

class Coords
{
    public double x;
    public double y;
    public double z;

    public Coords(double x, double y, double z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }
}
z0mbi3
  • 336
  • 4
  • 14
  • Hi @roryap. This is not a matter of not working. I have tried to find the formula online but couldn't. I have also tried to derive it myself, with no success. I can tell you the formula is not simple (I have a degree in B.Science/Physics and another in B.Engineering). This is not 2D space, it's a 3D problem, involving Latitude & Longitude. I don't find your comment constructive at all. Please read my full question. – z0mbi3 Apr 03 '15 at 12:31
  • Holy crap. How far away from the meeting place are these people living!? – Sam Axe Apr 03 '15 at 12:36
  • At about 50miles, you get quite inaccurate values if you presume a 2D map. Also, the formulas don't work out then, you have to add a delta error, otherwise you won't get a solution. This makes the problem so much more complicated. – z0mbi3 Apr 03 '15 at 12:39
  • I reject your premise then. If they each live about 50 miles away from the meeting place then they are going to be more than 50 miles away from each other. In that case they aren't friends. They are acquaintances at best. Maintaining a friendship at that long distance over any amount of time would be improbable. – Sam Axe Apr 03 '15 at 12:42
  • Additionally - if this meeting is so secret, why the hell are they telling you!? – Sam Axe Apr 03 '15 at 12:44
  • Kidding aside - this question might receive better treatment from people that know math well.. like on math.stackexchange.com – Sam Axe Apr 03 '15 at 12:55
  • This looks promising: http://gis.stackexchange.com/questions/48937/how-to-calculate-the-intersection-of-2-circles – Sam Axe Apr 03 '15 at 12:57
  • @Sam, Thanks Sam, It's a good start for me. – z0mbi3 Apr 03 '15 at 13:09
  • Thanks @Sam, You're right - I should have started my search on a Maths forum – z0mbi3 Apr 03 '15 at 13:12

1 Answers1

0

Seems this is the solution after all.

https://gis.stackexchange.com/questions/66/trilateration-using-3-latitude-and-longitude-points-and-3-distances

... far more complicated than school geometry @DrKoch

Here is the Python solution:

yC = earthR *(math.cos(math.radians(LatC)) * math.sin(math.radians(LonC)))
zC = earthR *(math.sin(math.radians(LatC)))

P1 = array([xA, yA, zA])
P2 = array([xB, yB, zB])
P3 = array([xC, yC, zC])

#from wikipedia
#transform to get circle 1 at origin
#transform to get circle 2 on x axis
ex = (P2 - P1)/(numpy.linalg.norm(P2 - P1))
i = dot(ex, P3 - P1)
ey = (P3 - P1 - i*ex)/(numpy.linalg.norm(P3 - P1 - i*ex))
ez = numpy.cross(ex,ey)
d = numpy.linalg.norm(P2 - P1)
j = dot(ey, P3 - P1)

#from wikipedia
#plug and chug using above values
x = (pow(DistA,2) - pow(DistB,2) + pow(d,2))/(2*d)
y = ((pow(DistA,2) - pow(DistC,2) + pow(i,2) + pow(j,2))/(2*j)) - ((i/j)*x)

# only one case shown here
z = sqrt(pow(DistA,2) - pow(x,2) - pow(y,2))

#triPt is an array with ECEF x,y,z of trilateration point
triPt = P1 + x*ex + y*ey + z*ez

#convert back to lat/long from ECEF
#convert to degrees
lat = math.degrees(math.asin(triPt[2] / earthR))
lon = math.degrees(math.atan2(triPt[1],triPt[0]))

print lat, lon`
Community
  • 1
  • 1
z0mbi3
  • 336
  • 4
  • 14