'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); /** * @copyright 2013 Sonia Keys * @copyright 2016 commenthol * @license MIT * @module sexagesimal */ /** * Sexagesimal functions */ /** * Angle represents a general purpose angle. * Unit is radians. */ class Angle { /** * constructs a new Angle value from sign, degree, minute, and second * components. * @param {Number|Boolean} angleOrNeg - angle in radians or sign, true if negative (required to attribute -0°30') * __Four arguments__ * @param {Number} [d] - (int) degree * @param {Number} [m] - (int) minute * @param {Number} [s] - (float) second */ constructor (angleOrNeg, d, m, s) { if (arguments.length === 1) { this.angle = Number(angleOrNeg); } else { this.setDMS(!!angleOrNeg, d, m, s); } } /** * SetDMS sets the value of an FAngle from sign, degree, minute, and second * components. * The receiver is returned as a convenience. * @param {Boolean} neg - sign, true if negative * @param {Number} d - (int) degree * @param {Number} m - (int) minute * @param {Number} s - (float) second * @returns {Angle} */ setDMS (neg = false, d = 0, m = 0, s = 0.0) { this.angle = (DMSToDeg(neg, d, m, s) * Math.PI / 180); return this } /** * sets angle * @param {Number} angle - (float) angle in radians * @returns {Angle} */ setAngle (angle) { this.angle = angle; return this } /** * Rad returns the angle in radians. * @returns {Number} angle in radians */ rad () { return this.angle } /** * Deg returns the angle in degrees. * @returns {Number} angle in degree */ deg () { return this.angle * 180 / Math.PI } /** * toDMS converts to parsed sexagesimal angle component. */ toDMS () { return degToDMS(this.deg()) } /** * Print angle in degree using `d°m´s.ss″` * @param {Number} [precision] - precision of `s.ss` * @returns {String} */ toString (precision) { let [neg, d, m, s] = this.toDMS(); s = round(s, precision).toString().replace(/^0\./, '.'); const str = (neg ? '-' : '') + (d + '°') + (m + '′') + (s + '″'); return str } /** * Print angle in degree using `d°.ff` * @param {Number} [precision] - precision of `.ff` * @returns {String} */ toDegString (precision) { let [i, s] = modf(this.deg()); s = round(s, precision).toString().replace(/^0\./, '.'); const str = (i + '°') + s; return str } } /** * HourAngle represents an angle corresponding to angular rotation of * the Earth in a specified time. * * Unit is radians. */ class HourAngle extends Angle { /** * NewHourAngle constructs a new HourAngle value from sign, hour, minute, * and second components. * @param {Boolean} neg * @param {Number} h - (int) * @param {Number} m - (int) * @param {Number} s - (float) * @constructor */ /** * SetDMS sets the value of an FAngle from sign, degree, minute, and second * components. * The receiver is returned as a convenience. * @param {Boolean} neg - sign, true if negative * @param {Number} h - (int) hour * @param {Number} m - (int) minute * @param {Number} s - (float) second * @returns {Angle} */ setDMS (neg = false, h = 0, m = 0, s = 0.0) { this.angle = (DMSToDeg(neg, h, m, s) * 15 * Math.PI / 180); return this } /** * Hour returns the hour angle as hours of time. * @returns hour angle */ hour () { return this.angle * 12 / Math.PI // 12 = 180 / 15 } deg () { return this.hour() } /** * Print angle in `HʰMᵐs.ssˢ` * @param {Number} precision - precision of `s.ss` * @returns {String} */ toString (precision) { let [neg, h, m, s] = this.toDMS(); s = round(s, precision).toString().replace(/^0\./, '.'); const str = (neg ? '-' : '') + (h + 'ʰ') + (m + 'ᵐ') + (s + 'ˢ'); return str } } /** * DMSToDeg converts from parsed sexagesimal angle components to decimal * degrees. * @param {Boolean} neg - sign, true if negative * @param {Number} d - (int) degree * @param {Number} m - (int) minute * @param {Number} s - (float) second * @returns {Number} angle in degree */ function DMSToDeg (neg, d, m, s) { s = (((d * 60 + m) * 60) + s) / 3600; if (neg) { return -s } return s } /** * DegToDMS converts from decimal degrees to parsed sexagesimal angle component. * @param {Number} deg - angle in degree * @returns {Array} [neg, d, m, s] * {Boolean} neg - sign, true if negative * {Number} d - (int) degree * {Number} m - (int) minute * {Number} s - (float) second */ function degToDMS (deg) { const neg = (deg < 0); deg = Math.abs(deg); let [d, s] = modf(deg % 360); const [m, s1] = modf(s * 60); s = round(s1 * 60); // may introduce an error < 1e13 return [neg, d, m, s] } class RA extends HourAngle { /** * constructs a new RA value from hour, minute, and second components. * Negative values are not supported, RA wraps values larger than 24 * to the range [0,24) hours. * @param {Number} h - (int) hour * @param {Number} m - (int) minute * @param {Number} s - (float) second */ constructor (h = 0, m = 0, s = 0) { super(false, h, m, s); const args = [].slice.call(arguments); if (args.length === 1) { this.angle = h; } else { const hr = DMSToDeg(false, h, m, s) % 24; this.angle = hr * 15 * Math.PI / 180; } } hour () { const h = this.angle * 12 / Math.PI; return (24 + (h % 24)) % 24 } } /** * Time Angle * Unit is time in seconds. */ class Time { /** * @param {boolean|number} negOrTimeInSecs - set `true` if negative; if type is number than time in seconds * @param {number} [h] - (int) hour * @param {number} [m] - (int) minute * @param {number} [s] - (float) second * @example * new sexa.Time(SECS_OF_DAY) * new sexa.Time(false, 15, 22, 7) */ constructor (negOrTimeInSecs, h, m, s) { if (typeof negOrTimeInSecs === 'number') { this.time = negOrTimeInSecs; } else { this.setHMS(negOrTimeInSecs, h, m, s); } } setHMS (neg = false, h = 0, m = 0, s = 0) { s += ((h * 60 + m) * 60); if (neg) { s = -s; } this.time = s; } /** * @returns {Number} time in seconds. */ sec () { return this.time } /** * @returns {Number} time in minutes. */ min () { return this.time / 60 } /** * @returns {Number} time in hours. */ hour () { return this.time / 3600 } /** * @returns {Number} time in days. */ day () { return this.time / 3600 / 24 } /** * @returns {Number} time in radians, where 1 day = 2 Pi radians. */ rad () { return this.time * Math.PI / 12 / 3600 } /** * convert time to HMS * @returns {Array} [neg, h, m, s] * {Boolean} neg - sign, true if negative * {Number} h - (int) hour * {Number} m - (int) minute * {Number} s - (float) second */ toHMS () { let t = this.time; const neg = (t < 0); t = (neg ? -t : t); const h = Math.trunc(t / 3600); t = t - (h * 3600); const m = Math.trunc(t / 60); const s = t - (m * 60); return [neg, h, m, s] } /** * Print time using `HʰMᵐsˢ.ss` * @param {Number} precision - precision of `.ss` * @returns {String} */ toString (precision) { const [neg, h, m, s] = this.toHMS(); let [si, sf] = modf(s); if (precision === 0) { si = round(s, 0); sf = 0; } else { sf = round(sf, precision).toString().substr(1); } const str = (neg ? '-' : '') + (h + 'ʰ') + (m + 'ᵐ') + (si + 'ˢ') + (sf || ''); return str } } // units const angleFromDeg = (deg) => deg * Math.PI / 180; const angleFromMin = (min) => min / 60 * Math.PI / 180; const angleFromSec = (sec) => sec / 3600 * Math.PI / 180; const degFromAngle = (angle) => angle * 180 / Math.PI; const secFromAngle = (angle) => angle * 3600 * 180 / Math.PI; const secFromHourAngle = (ha) => ha * 240 * 180 / Math.PI; /** * separate fix `i` from fraction `f` * @private * @param {Number} float * @returns {Array} [i, f] * {Number} i - (int) fix value * {Number} f - (float) fractional portion; always > 1 */ function modf (float) { const i = Math.trunc(float); const f = Math.abs(float - i); return [i, f] } /** * Rounds `float` value by precision * @private * @param {Number} float - value to round * @param {Number} [precision] - (int) number of post decimal positions * @return {Number} rounded `float` */ function round (float, precision = 10) { return parseFloat(float.toFixed(precision)) } var sexa = { Angle, HourAngle, DMSToDeg, degToDMS, RA, Time, angleFromDeg, angleFromMin, angleFromSec, degFromAngle, secFromAngle, secFromHourAngle }; exports.Angle = Angle; exports.DMSToDeg = DMSToDeg; exports.HourAngle = HourAngle; exports.RA = RA; exports.Time = Time; exports.angleFromDeg = angleFromDeg; exports.angleFromMin = angleFromMin; exports.angleFromSec = angleFromSec; exports["default"] = sexa; exports.degFromAngle = degFromAngle; exports.degToDMS = degToDMS; exports.secFromAngle = secFromAngle; exports.secFromHourAngle = secFromHourAngle;