UNPKG

meeusjs

Version:

Implementation of the Astronomical Algorithms of Jean Meeus in Javascript

280 lines (246 loc) 8.02 kB
// Copyright (c) 2016 Fabio Soldati, www.peakfinder.org // License MIT: http://www.opensource.org/licenses/MIT /** * Represents a geographical point in ecliptic coordinates with latitude and longitude coordinates * and an optional height. * @constructor * @param {number} lat - The latitude of the location in radians. * @param {number} lng - The longitude of the location in radians. Remark: geographic longitudes are measured positively westwards! * @param {?number} h - The height above the sea level. */ A.EclCoord = function (lat, lng, h) { if (isNaN(lat) || isNaN(lng)) { throw new Error('Invalid EclCoord object: (' + lat + ', ' + lng + ')'); } this.lat = lat; this.lng = lng; if (h !== undefined) { this.h = h; } }; A.EclCoord.prototype = { /** * Returns a pretty printed string in the WGS84 format. * @return {String} Pretty printed string. */ toWgs84String: function () { // (Number) -> String return A.Math.formatNum(this.lat * 180 / Math.PI) + ', ' + A.Math.formatNum(-this.lng * 180 / Math.PI); } }; /** * Create a new EclCoord object from the given wgs coordinates. * * @param {number} lat - The latitude of the location degrees. * @param {number} lng - The longitude of the location degrees. * @param {?number} h - The height above the sea level. */ A.EclCoord.fromWgs84 = function(wgs84lat, wgs84lng, h) { return new A.EclCoord(wgs84lat * Math.PI / 180, -wgs84lng * Math.PI / 180, h); }; /** * Represents a geographical point in equatorial coordinates with right ascension and declination. * @constructor * @param {number} ra - The right ascension in radians. * @param {number} lng - The declination in radians. */ A.EqCoord = function (ra, dec) { // (Number, Number, Number) if (isNaN(ra) || isNaN(dec)) { throw new Error('Invalid EqCoord object: (' + ra + ', ' + dec + ')'); } this.ra = ra; this.dec = dec; }; A.EqCoord.prototype = { /** * Returns a pretty printed string in degrees. * @return {String} Pretty printed string. */ toString: function () { // (Number) -> String return "ra:" + A.Math.formatNum(this.ra * 180 / Math.PI) + ', dec:' + A.Math.formatNum(this.dec * 180 / Math.PI); } }; /** * Represents a geographical point in horizontal coordinates with azimuth and altitude. * @constructor * @param {number} az - The azimuth in radians. * @param {number} alt - The altitude in radians. */ A.HzCoord = function (az, alt) { // (Number, Number, Number) if (isNaN(az) || isNaN(alt)) { throw new Error('Invalid HzCoord object: (' + az + ', ' + alt + ')'); } this.az = az; this.alt = alt; }; A.HzCoord.prototype = { /** * Returns a pretty printed string in degrees. * @return {String} Pretty printed string. */ toString: function () { // (Number) -> String return "azi:" + A.Math.formatNum(this.az * 180 / Math.PI) + ', alt:' + A.Math.formatNum(this.alt * 180 / Math.PI); } }; /** * A.Coord includes some static functions for coordinate transformations * @module A.Coord */ A.Coord = { /** * DMSToDeg converts from parsed sexagesimal angle components to decimal degrees. * * @function dmsToDeg * @static * * @param {boolean} neg - set to true if negative * @param {number} d - degrees * @param {number} m - minutes * @param {number} s - seconds * @return {number} decimal degrees */ dmsToDeg: function(neg, d, m, s) { s = (((d*60+m)*60) + s) / 3600; if (neg) { return -s; } return s; }, /** * Returns radian value from an angle. * * @function calcAngle * @static * * @param {boolean} neg - set to true if negative * @param {number} d - degrees * @param {number} m - minutes * @param {number} s - seconds * @return {number} degrees in radians */ calcAngle: function(neg, d, m, s) { return A.Coord.dmsToDeg(neg, d, m, s) * Math.PI / 180; }, /** * Returns a radian value from hour, minute, and second components. <br> * * Negative values are not supported, and NewRA wraps values larger than 24 * to the range [0,24) hours. * * @function calcRA * @static * * @param {number} h - hours * @param {number} m - minutes * @param {number} s - seconds * @return {number} degrees in radians */ calcRA: function(h, m, s) { var r = A.Coord.dmsToDeg(false, h, m, s) % 24; return r * 15 * Math.PI / 180; }, /** * Returns a pretty formatted HMS string from the given seconds * * @function secondsToHMSStr * @static * @param {number} sec - seconds * @return {string} formatted string */ secondsToHMSStr: function(sec) { var days = Math.floor(sec / 86400); sec = A.Math.pMod(sec, 86400); var hours = Math.floor(sec/3600) % 24; var minutes = Math.floor(sec/60) % 60; var seconds = Math.floor(sec % 60); return (days !== 0 ? days + "d " : "") + (hours < 10 ? "0" : "") + hours + ":" + (minutes < 10 ? "0" : "") + minutes + ":" + (seconds < 10 ? "0" : "") + seconds; }, /** * Returns a pretty formatted HM string from the given seconds * * @function secondsToHMStr * @static * @param {number} sec - seconds * @return {string} formatted string */ secondsToHMStr: function(sec) { var days = Math.floor(sec / 86400); sec = A.Math.pMod(sec, 86400); var hours = Math.floor(sec/3600) % 24; var minutes = Math.floor(sec/60) % 60; return (days !== 0 ? days + "d " : "") + (hours < 10 ? "0" : "") + hours + ":" + (minutes < 10 ? "0" : "") + minutes; }, /** * EqToEcl converts equatorial coordinates to ecliptic coordinates. * @function eqToEcl * @static * * @param {EqCoord} eqcoord - equatorial coordinates, in radians * @param {number} epsilon - obliquity of the ecliptic * * @return {EclCoord} ecliptic coordinates of observer on Earth */ eqToEcl: function(eqcoord, epsilon) { var sra = Math.sin(eqcoord.ra); var cra = Math.cos(eqcoord.ra); var sdec = Math.sin(eqcoord.dec); var cdec = Math.cos(eqcoord.dec); var sepsilon = Math.sin(epsilon); var cepsilon = Math.cos(epsilon); return new A.EclCoord( Math.atan2(sra * cepsilon + (sdec / cdec) * sepsilon, cra), // (13.1) p. 93 Math.asin(sdec * cepsilon - cdec * sepsilon * sra) // (13.2) p. 93 ); }, /** * EclToEq converts ecliptic coordinates to equatorial coordinates. * @function eclToEq * @static * * @param {EclCoord} latlng - ecliptic coordinates of observer on Earth * @param {number} epsilon - obliquity of the ecliptic * * @return {EqCoord} equatorial coordinates, in radians */ eclToEq: function(eclCoord, epsilon) { var slat = Math.sin(eclCoord.lat); var clat = Math.cos(eclCoord.lat); var slng = Math.sin(eclCoord.lng); var clng = Math.cos(eclCoord.lng); var sepsilon = Math.sin(epsilon); var cepsilon = Math.cos(epsilon); var ra = Math.atan2(slat * cepsilon - (slng / clng) * sepsilon, clat); // (13.3) p. 93 if (ra < 0) { ra += 2 * Math.PI; } return new A.EqCoord( ra, Math.asin(slng * cepsilon + clng * sepsilon * slat) // (13.4) p. 93 ); }, /** * EqToHz computes Horizontal coordinates from equatorial coordinates. <br> * Sidereal time must be consistent with the equatorial coordinates. * If coordinates are apparent, sidereal time must be apparent as well. * * @function eqToHz * @static * * @param {EqCoord} eqcoord - equatorial coordinates, in radians * @param {EclCoord} latlng - ecliptic coordinates of observer on Earth * @param {number} st - sidereal time at Greenwich at time of observation in radians. * @return {HzCoord} horizontal coordinates, in radians */ eqToHz: function(eqcoord, eclCoord, strad) { var H = strad - eclCoord.lng - eqcoord.ra; var sH = Math.sin(H); var cH = Math.cos(H); var slat = Math.sin(eclCoord.lat); var clat = Math.cos(eclCoord.lat); var sdec = Math.sin(eqcoord.dec); var cdec = Math.cos(eqcoord.dec); return new A.HzCoord( Math.atan2(sH, cH * slat - (sdec / cdec) * clat), // (13.5) p. 93 Math.asin(slat * sdec + clat * cdec * cH) // (13.6) p. 93 ); } };