Module:Bearing

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
Lua
CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules

Documentation for this module may be created at Module:Bearing/doc

Code

--[[--------------------------< B E A R I N G >----------------------------------------------------------------

calculates the bearing from <from_lat>/<from_long> to <to_lat>/<to_long> using the equation from
https://www.igismap.com/formula-to-find-bearing-or-heading-angle-between-two-points-latitude-longitude/

written as a response to [ [User_talk:Trappist_the_monk#Hello,_bearings] ]

inputs in decimal degrees (degrees minutes seconds coordinates must be pre-converted)
	<from_lat> – latitude (north +, south -) of the starting point
	<from_long> – longitude (east +, west -) of the starting point
	<to_lat> – latitude (north +, south -) of the ending point
	<to_long> – longitude (east +, west -) of the ending point

returns bearing from 'from' to 'to' in decimal degrees

This code only works from the debug console:
	=p.bearing (39.099912, -94.581213, 38.627089, -90.200203)					-- original worked example St Louis, Missouri bears 96.5° from Kansas City, Kansas
	=p.bearing (38.627089, -90.200203, 39.099912, -94.581213)					-- reversed example: Kansas City, Kansas bears 279.3° from St Louis, Missouri

for negative lat/long (south/west) do not use U+2212 minus sign; use keyboard U+002D hyphen-minus 

]]

require('strict');

local function bearing (from_lat, from_long, to_lat, to_long)
	local from_lat_rad = math.rad (from_lat);									-- convert degree inputs to radians
	local from_long_rad = math.rad (from_long);
	local to_lat_rad = math.rad (to_lat);
	local to_long_rad = math.rad (to_long);
	
	local delta_long_rad = to_long_rad - from_long_rad;
	local x = math.cos (to_lat_rad) * math.sin (delta_long_rad);
	local y = (math.cos (from_lat_rad) * math.sin (to_lat_rad)) - (math.sin (from_lat_rad) * math.cos (to_lat_rad) * math.cos (delta_long_rad));
	local beta = math.atan2 (x, y);												-- result in radians
	beta = math.deg (beta);														-- convert to degrees
	return (0.0 > beta) and (beta + 360.0) or beta;								-- when beta is negative, add 360 degrees to make a positive bearing
end

--[[--------------------------< E X P O R T S >----------------------------------------------------------------
]]

return {
	bearing = bearing,
	}