generated from ztimson/template
init
This commit is contained in:
+167
@@ -0,0 +1,167 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.degreesLat = degreesLat;
|
||||
exports.degreesLong = degreesLong;
|
||||
exports.degreesToRadians = degreesToRadians;
|
||||
exports.ecfToEci = ecfToEci;
|
||||
exports.ecfToLookAngles = ecfToLookAngles;
|
||||
exports.eciToEcf = eciToEcf;
|
||||
exports.eciToGeodetic = eciToGeodetic;
|
||||
exports.geodeticToEcf = geodeticToEcf;
|
||||
exports.radiansLat = radiansLat;
|
||||
exports.radiansLong = radiansLong;
|
||||
exports.radiansToDegrees = radiansToDegrees;
|
||||
var _constants = require("./constants");
|
||||
function radiansToDegrees(radians) {
|
||||
return radians * _constants.rad2deg;
|
||||
}
|
||||
function degreesToRadians(degrees) {
|
||||
return degrees * _constants.deg2rad;
|
||||
}
|
||||
function degreesLat(radians) {
|
||||
if (radians < -_constants.pi / 2 || radians > _constants.pi / 2) {
|
||||
throw new RangeError('Latitude radians must be in range [-pi/2; pi/2].');
|
||||
}
|
||||
return radiansToDegrees(radians);
|
||||
}
|
||||
function degreesLong(radians) {
|
||||
if (radians < -_constants.pi || radians > _constants.pi) {
|
||||
throw new RangeError('Longitude radians must be in range [-pi; pi].');
|
||||
}
|
||||
return radiansToDegrees(radians);
|
||||
}
|
||||
function radiansLat(degrees) {
|
||||
if (degrees < -90 || degrees > 90) {
|
||||
throw new RangeError('Latitude degrees must be in range [-90; 90].');
|
||||
}
|
||||
return degreesToRadians(degrees);
|
||||
}
|
||||
function radiansLong(degrees) {
|
||||
if (degrees < -180 || degrees > 180) {
|
||||
throw new RangeError('Longitude degrees must be in range [-180; 180].');
|
||||
}
|
||||
return degreesToRadians(degrees);
|
||||
}
|
||||
function geodeticToEcf(_ref) {
|
||||
var longitude = _ref.longitude,
|
||||
latitude = _ref.latitude,
|
||||
height = _ref.height;
|
||||
var a = 6378.137;
|
||||
var b = 6356.7523142;
|
||||
var f = (a - b) / a;
|
||||
var e2 = 2 * f - f * f;
|
||||
var normal = a / Math.sqrt(1 - e2 * (Math.sin(latitude) * Math.sin(latitude)));
|
||||
var x = (normal + height) * Math.cos(latitude) * Math.cos(longitude);
|
||||
var y = (normal + height) * Math.cos(latitude) * Math.sin(longitude);
|
||||
var z = (normal * (1 - e2) + height) * Math.sin(latitude);
|
||||
return {
|
||||
x: x,
|
||||
y: y,
|
||||
z: z
|
||||
};
|
||||
}
|
||||
function eciToGeodetic(eci, gmst) {
|
||||
// http://www.celestrak.com/columns/v02n03/
|
||||
var a = 6378.137;
|
||||
var b = 6356.7523142;
|
||||
var R = Math.sqrt(eci.x * eci.x + eci.y * eci.y);
|
||||
var f = (a - b) / a;
|
||||
var e2 = 2 * f - f * f;
|
||||
var longitude = Math.atan2(eci.y, eci.x) - gmst;
|
||||
while (longitude < -_constants.pi) {
|
||||
longitude += _constants.twoPi;
|
||||
}
|
||||
while (longitude > _constants.pi) {
|
||||
longitude -= _constants.twoPi;
|
||||
}
|
||||
var kmax = 20;
|
||||
var k = 0;
|
||||
var latitude = Math.atan2(eci.z, Math.sqrt(eci.x * eci.x + eci.y * eci.y));
|
||||
var C;
|
||||
while (k++ < kmax) {
|
||||
C = 1 / Math.sqrt(1 - e2 * (Math.sin(latitude) * Math.sin(latitude)));
|
||||
latitude = Math.atan2(eci.z + a * C * e2 * Math.sin(latitude), R);
|
||||
}
|
||||
var height = R / Math.cos(latitude) - a * C;
|
||||
return {
|
||||
longitude: longitude,
|
||||
latitude: latitude,
|
||||
height: height
|
||||
};
|
||||
}
|
||||
function ecfToEci(ecf, gmst) {
|
||||
// ccar.colorado.edu/ASEN5070/handouts/coordsys.doc
|
||||
//
|
||||
// [X] [C -S 0][X]
|
||||
// [Y] = [S C 0][Y]
|
||||
// [Z]eci [0 0 1][Z]ecf
|
||||
//
|
||||
var X = ecf.x * Math.cos(gmst) - ecf.y * Math.sin(gmst);
|
||||
var Y = ecf.x * Math.sin(gmst) + ecf.y * Math.cos(gmst);
|
||||
var Z = ecf.z;
|
||||
return {
|
||||
x: X,
|
||||
y: Y,
|
||||
z: Z
|
||||
};
|
||||
}
|
||||
function eciToEcf(eci, gmst) {
|
||||
// ccar.colorado.edu/ASEN5070/handouts/coordsys.doc
|
||||
//
|
||||
// [X] [C -S 0][X]
|
||||
// [Y] = [S C 0][Y]
|
||||
// [Z]eci [0 0 1][Z]ecf
|
||||
//
|
||||
//
|
||||
// Inverse:
|
||||
// [X] [C S 0][X]
|
||||
// [Y] = [-S C 0][Y]
|
||||
// [Z]ecf [0 0 1][Z]eci
|
||||
var x = eci.x * Math.cos(gmst) + eci.y * Math.sin(gmst);
|
||||
var y = eci.x * -Math.sin(gmst) + eci.y * Math.cos(gmst);
|
||||
var z = eci.z;
|
||||
return {
|
||||
x: x,
|
||||
y: y,
|
||||
z: z
|
||||
};
|
||||
}
|
||||
function topocentric(observerGeodetic, satelliteEcf) {
|
||||
// http://www.celestrak.com/columns/v02n02/
|
||||
// TS Kelso's method, except I'm using ECF frame
|
||||
// and he uses ECI.
|
||||
var longitude = observerGeodetic.longitude,
|
||||
latitude = observerGeodetic.latitude;
|
||||
var observerEcf = geodeticToEcf(observerGeodetic);
|
||||
var rx = satelliteEcf.x - observerEcf.x;
|
||||
var ry = satelliteEcf.y - observerEcf.y;
|
||||
var rz = satelliteEcf.z - observerEcf.z;
|
||||
var topS = Math.sin(latitude) * Math.cos(longitude) * rx + Math.sin(latitude) * Math.sin(longitude) * ry - Math.cos(latitude) * rz;
|
||||
var topE = -Math.sin(longitude) * rx + Math.cos(longitude) * ry;
|
||||
var topZ = Math.cos(latitude) * Math.cos(longitude) * rx + Math.cos(latitude) * Math.sin(longitude) * ry + Math.sin(latitude) * rz;
|
||||
return {
|
||||
topS: topS,
|
||||
topE: topE,
|
||||
topZ: topZ
|
||||
};
|
||||
}
|
||||
function topocentricToLookAngles(tc) {
|
||||
var topS = tc.topS,
|
||||
topE = tc.topE,
|
||||
topZ = tc.topZ;
|
||||
var rangeSat = Math.sqrt(topS * topS + topE * topE + topZ * topZ);
|
||||
var El = Math.asin(topZ / rangeSat);
|
||||
var Az = Math.atan2(-topE, topS) + _constants.pi;
|
||||
return {
|
||||
azimuth: Az,
|
||||
elevation: El,
|
||||
rangeSat: rangeSat // Range in km
|
||||
};
|
||||
}
|
||||
function ecfToLookAngles(observerGeodetic, satelliteEcf) {
|
||||
var topocentricCoords = topocentric(observerGeodetic, satelliteEcf);
|
||||
return topocentricToLookAngles(topocentricCoords);
|
||||
}
|
||||
Reference in New Issue
Block a user