Skip to content

Instantly share code, notes, and snippets.

@missinglink
Last active August 3, 2021 08:22
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save missinglink/ab7c8b9b8699622539986373e6237fd4 to your computer and use it in GitHub Desktop.
Save missinglink/ab7c8b9b8699622539986373e6237fd4 to your computer and use it in GitHub Desktop.
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