Last active
August 3, 2021 08:22
-
-
Save missinglink/ab7c8b9b8699622539986373e6237fd4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function toRad(degree) { return degree * Math.PI / 180; } | |
function toDeg(radian) { return radian * 180 / Math.PI; } | |
// round floating point errors | |
function rnd( float ){ | |
return (Math.floor(100000 * float) / 100000).toFixed(5); | |
} | |
function assert( a, b ){ | |
switch( typeof a ){ | |
case 'number': | |
if( a % 1 !== 0 ) console.log( rnd(a) == rnd(b) ? '✓': '✖', rnd(a), rnd(b), a, b ); // float | |
else console.log( a == b ? '✓': '✖', a, b ); // int | |
break; | |
default: | |
console.log( a == b ? '✓': '✖', a, b ); | |
} | |
} | |
function dist( a, b ){ | |
return Math.acos( Math.sin( a.lat ) * Math.sin( b.lat ) + | |
Math.cos( a.lat ) * Math.cos( b.lat ) * Math.cos( a.lon - b.lon )); | |
} | |
function course( a, b, d ){ | |
return Math.acos( | |
( Math.sin( b.lat ) - Math.sin( a.lat ) * Math.cos( d )) / | |
( Math.sin( d ) * Math.cos( a.lat ) ) | |
); | |
} | |
function xTrack( d, crs1, crs2 ){ | |
return Math.asin( Math.sin( d ) * Math.sin( crs1 - crs2 ) ); | |
} | |
function aTrack( d, xtd ){ | |
return Math.acos( Math.cos( d ) / Math.cos( xtd ) ); | |
} | |
function aTrackSimple( d, xtd ){ | |
return Math.asin( Math.sqrt( Math.pow( Math.sin( d ), 2 ) - Math.pow( Math.sin( xtd ), 2 ) ) / Math.cos( xtd ) ); | |
} | |
function interpolate( d, f, a, b ){ | |
var A = Math.sin( (1-f) * d ) / Math.sin( d ); | |
// assert( A, 0.62588 ); | |
var B = Math.sin( f * d ) / Math.sin( d ); | |
// assert( B, 0.422735 ); | |
var X = A * Math.cos( a.lat ) * Math.cos( a.lon ) + B * Math.cos( b.lat ) * Math.cos( b.lon ); | |
// assert( X, -0.157344 ); | |
var Y = A * Math.cos( a.lat ) * Math.sin( a.lon ) + B * Math.cos( b.lat ) * Math.sin( b.lon ); | |
// assert( Y, 0.764745 ); | |
var Z = A * Math.sin( a.lat ) + B * Math.sin( b.lat ); | |
// assert( Z, 0.624826 ); | |
return { | |
lat: Math.atan2( Z, Math.sqrt( Math.pow( X, 2 ) + Math.pow( Y, 2 ) ) ), | |
lon: Math.atan2( Y, X ) | |
} | |
} | |
// we travel from JFK to LAX and end up at D | |
var LAX = { lon: 118.4, lat: 33.95, rad: { lat: 0, lon: 0 } }; | |
var JFK = { lon: 73.7833, lat: 40.6333, rad: { lat: 0, lon: 0 } }; | |
var LOST = { lon: 116.5, lat: 34.5, rad: { lat: 0, lon: 0 } }; | |
LAX.rad.lat = toRad( LAX.lat ); | |
LAX.rad.lon = toRad( LAX.lon ); | |
JFK.rad.lat = toRad( JFK.lat ); | |
JFK.rad.lon = toRad( JFK.lon ); | |
assert( LAX.rad.lat, 0.592539 ); | |
assert( LAX.rad.lon, 2.066470 ); | |
assert( JFK.rad.lat, 0.709186 ); | |
assert( JFK.rad.lon, 1.287762 ); | |
LOST.rad.lat = toRad( LOST.lat ); | |
LOST.rad.lon = toRad( LOST.lon ); | |
assert( LOST.rad.lat, 0.6021386 ); | |
assert( LOST.rad.lon, 2.033309 ); | |
var dist_AD = dist( LAX.rad, LOST.rad ); | |
assert( dist_AD, 0.02905 ); | |
var crs_AD = course( LAX.rad, LOST.rad, dist_AD ); | |
assert( crs_AD, 1.22473 ); | |
//--- | |
var dist_AB = dist( LAX.rad, JFK.rad ); | |
assert( dist_AB, 0.62358 ); | |
var crs_AB = course( LAX.rad, JFK.rad, dist_AB ); | |
assert( crs_AB, 1.15003 ); | |
//--- | |
var xtd = xTrack( dist_AD, crs_AD, crs_AB ); | |
assert( xtd, 0.00216747 ); | |
var atd = aTrack( dist_AD, xtd ); | |
assert( atd, 0.0289691 ); | |
var atd2 = aTrackSimple( dist_AD, xtd ); | |
assert( atd2, 0.0289691 ); | |
var forty = interpolate( dist_AB, 0.4, LAX.rad, JFK.rad ); | |
assert( forty.lat, 0.674909 ); | |
assert( forty.lon, 1.77371 ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment