I have been searching for a solution to calculate the distance and bearing of a target gps location for a while now. This page always popped up but my brain hurt every time I tried to convert this to lua.
I am happy to say I have cracked it and here is my code.
function Geo_Angle( lat1, lon1, lat2, lon2) local dLon = math.rad(lon2-lon1); local y = math.sin(dLon) * math.cos(math.rad(lat2)); local x = math.cos(math.rad(lat1)) * math.sin(math.rad(lat2)) - math.sin(math.rad(lat1)) * math.cos(math.rad(lat2)) * math.cos(dLon); local brng = math.deg(math.atan2(y, x)); return ((brng + 360) % 360); end |
The distance code was created by roaminggamer else on the Corona forums (can’t find their name).
function Geo_Distance(lat1, lon1, lat2, lon2) if lat1 == nil or lon1 == nil or lat2 == nil or lon2 == nil then return nil end local dlat = math.rad(lat2-lat1) local dlon = math.rad(lon2-lon1) local sin_dlat = math.sin(dlat/2) local sin_dlon = math.sin(dlon/2) local a = sin_dlat * sin_dlat + math.cos(math.rad(lat1)) * math.cos(math.rad(lat2)) * sin_dlon * sin_dlon local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a)) -- 6378 km is the earth's radius at the equator. -- 6357 km would be the radius at the poles (earth isn't a perfect circle). -- Thus, high latitude distances will be slightly overestimated -- To get miles, use 3963 as the constant (equator again) local d = 6378 * c return d end |
Here is how I call the code
print("Bearing between Tamworth and Armidale: " .. tonumber(GeoAngle(-31.1063157, 150.9307341,-30.5143425, 151.66696439999998))) print("Distance between Tamworth and Armidale: " .. tonumber(GeoDistance(-31.1063157, 150.9307341,-30.5143425, 151.66696439999998)) .. "km") |
Results:
Corona Simulator[4155:693467] Bearing between Tamworth and Armidale: 47.07677793374 Corona Simulator[4155:693467] Distance between Tamworth and Armidale: 96.419986257454km |
When comparing my results with this site my bearing results are within 0.18677793374 degree and 0.078686257454 km for distance (good enough for my simple augmented reality app).
I tried to trick it by putting the source/dest either side of GMT and it did not measure the longest route around the globe.
Corona Simulator[4288:936166] Bearing between -179 lon and 179 lon: 270 Corona Simulator[4288:936166] Distance between -179 lon and 179 lon: 222.6341993844km |
Also putting a source/dest near each pole calculated the approximate right distance between the coordinates.
Corona Simulator[4288:936166] Bearing between -89 lat and 89 lat: 180° Corona Simulator[4288:936166] Distance between 89 lat and 89 lat: 19814.443745211km |