1 const paCometData = require('./data/pa-cometdata.js');
  2 const paMacros = require('./pa-macros.js');
  3 const paUtils = require('./pa-utils.js');
  4 
  5 /**
  6  * Calculate position of an elliptical comet.
  7  */
  8 function positionOfEllipticalComet(lctHour, lctMin, lctSec, isDaylightSaving, zoneCorrectionHours, localDateDay, localDateMonth, localDateYear, cometName) {
  9     var daylightSaving = (isDaylightSaving) ? 1 : 0;
 10 
 11     var greenwichDateDay = paMacros.localCivilTimeGreenwichDay(lctHour, lctMin, lctSec, daylightSaving, zoneCorrectionHours, localDateDay, localDateMonth, localDateYear);
 12     var greenwichDateMonth = paMacros.localCivilTimeGreenwichMonth(lctHour, lctMin, lctSec, daylightSaving, zoneCorrectionHours, localDateDay, localDateMonth, localDateYear);
 13     var greenwichDateYear = paMacros.localCivilTimeGreenwichYear(lctHour, lctMin, lctSec, daylightSaving, zoneCorrectionHours, localDateDay, localDateMonth, localDateYear);
 14 
 15     var [comet_name, epoch_EpochOfPerihelion, peri_LongitudeOfPerihelion, node_LongitudeOfAscendingNode, period_PeriodOfOrbit, axis_SemiMajorAxisOfOrbit, ecc_EccentricityOfOrbit, incl_InclinationOfOrbit] = paCometData.getCometEllipticalData(cometName);
 16 
 17     var timeSinceEpochYears = (paMacros.civilDateToJulianDate(greenwichDateDay, greenwichDateMonth, greenwichDateYear) - paMacros.civilDateToJulianDate(0.0, 1, greenwichDateYear)) / 365.242191 + greenwichDateYear - Number(epoch_EpochOfPerihelion);
 18     var mcDeg = 360 * timeSinceEpochYears / Number(period_PeriodOfOrbit);
 19     var mcRad = paUtils.degreesToRadians(mcDeg - 360 * Math.floor(mcDeg / 360));
 20     var eccentricity = Number(ecc_EccentricityOfOrbit);
 21     var trueAnomalyDeg = paMacros.degrees(paMacros.trueAnomaly(mcRad, eccentricity));
 22     var lcDeg = trueAnomalyDeg + Number(peri_LongitudeOfPerihelion);
 23     var rAU = Number(axis_SemiMajorAxisOfOrbit) * (1 - eccentricity * eccentricity) / (1 + eccentricity * Math.cos(paUtils.degreesToRadians(trueAnomalyDeg)));
 24     var lcNodeRad = paUtils.degreesToRadians(lcDeg - Number(node_LongitudeOfAscendingNode));
 25     var psiRad = Math.asin(Math.sin(lcNodeRad) * Math.sin(paUtils.degreesToRadians(Number(incl_InclinationOfOrbit))));
 26 
 27     var y = Math.sin(lcNodeRad) * Math.cos(paUtils.degreesToRadians(Number(incl_InclinationOfOrbit)));
 28     var x = Math.cos(lcNodeRad);
 29 
 30     var ldDeg = paMacros.degrees(Math.atan2(y, x)) + Number(node_LongitudeOfAscendingNode);
 31     var rdAU = rAU * Math.cos(psiRad);
 32 
 33     var earthLongitudeLeDeg = paMacros.sunLong(lctHour, lctMin, lctSec, daylightSaving, zoneCorrectionHours, localDateDay, localDateMonth, localDateYear) + 180.0;
 34     var earthRadiusVectorAU = paMacros.sunDist(lctHour, lctMin, lctSec, daylightSaving, zoneCorrectionHours, localDateDay, localDateMonth, localDateYear);
 35 
 36     var leLdRad = paUtils.degreesToRadians(earthLongitudeLeDeg - ldDeg);
 37     var aRad = (rdAU < earthRadiusVectorAU) ? Math.atan2((rdAU * Math.sin(leLdRad)), (earthRadiusVectorAU - rdAU * Math.cos(leLdRad))) : Math.atan2((earthRadiusVectorAU * Math.sin(-leLdRad)), (rdAU - earthRadiusVectorAU * Math.cos(leLdRad)));
 38 
 39     var cometLongDeg1 = (rdAU < earthRadiusVectorAU) ? 180.0 + earthLongitudeLeDeg + paMacros.degrees(aRad) : paMacros.degrees(aRad) + ldDeg;
 40     var cometLongDeg = cometLongDeg1 - 360 * Math.floor(cometLongDeg1 / 360);
 41     var cometLatDeg = paMacros.degrees(Math.atan(rdAU * Math.tan(psiRad) * Math.sin(paUtils.degreesToRadians(cometLongDeg1 - ldDeg)) / (earthRadiusVectorAU * Math.sin(-leLdRad))));
 42     var cometRAHours1 = paMacros.decimalDegreesToDegreeHours(paMacros.ecRA(cometLongDeg, 0, 0, cometLatDeg, 0, 0, greenwichDateDay, greenwichDateMonth, greenwichDateYear));
 43     var cometDecDeg1 = paMacros.ecDec(cometLongDeg, 0, 0, cometLatDeg, 0, 0, greenwichDateDay, greenwichDateMonth, greenwichDateYear);
 44     var cometDistanceAU = Math.sqrt(Math.pow(earthRadiusVectorAU, 2) + Math.pow(rAU, 2) - 2.0 * earthRadiusVectorAU * rAU * Math.cos(paUtils.degreesToRadians(lcDeg - earthLongitudeLeDeg)) * Math.cos(psiRad));
 45 
 46     var cometRAHour = paMacros.decimalHoursHour(cometRAHours1 + 0.008333);
 47     var cometRAMin = paMacros.decimalHoursMinute(cometRAHours1 + 0.008333);
 48     var cometDecDeg = paMacros.decimalDegreesDegrees(cometDecDeg1 + 0.008333);
 49     var cometDecMin = paMacros.decimalDegreesMinutes(cometDecDeg1 + 0.008333);
 50     var cometDistEarth = paUtils.round(cometDistanceAU, 2);
 51 
 52     return [cometRAHour, cometRAMin, cometDecDeg, cometDecMin, cometDistEarth];
 53 }
 54 
 55 /**
 56  * Calculate position of a parabolic comet.
 57  */
 58 function positionOfParabolicComet(lctHour, lctMin, lctSec, isDaylightSaving, zoneCorrectionHours, localDateDay, localDateMonth, localDateYear, cometName) {
 59     var daylightSaving = (isDaylightSaving) ? 1 : 0;
 60 
 61     var greenwichDateDay = paMacros.localCivilTimeGreenwichDay(lctHour, lctMin, lctSec, daylightSaving, zoneCorrectionHours, localDateDay, localDateMonth, localDateYear);
 62     var greenwichDateMonth = paMacros.localCivilTimeGreenwichMonth(lctHour, lctMin, lctSec, daylightSaving, zoneCorrectionHours, localDateDay, localDateMonth, localDateYear);
 63     var greenwichDateYear = paMacros.localCivilTimeGreenwichYear(lctHour, lctMin, lctSec, daylightSaving, zoneCorrectionHours, localDateDay, localDateMonth, localDateYear);
 64 
 65     var [comet_name, epochPeriDay, epochPeriMonth, epochPeriYear, argPeri, node, periDist, incl] = paCometData.getCometParabolicData(cometName);
 66 
 67     var perihelionEpochDay = Number(epochPeriDay);
 68     var perihelionEpochMonth = Number(epochPeriMonth);
 69     var perihelionEpochYear = Number(epochPeriYear);
 70     var qAU = Number(periDist);
 71     var inclinationDeg = Number(incl);
 72     var perihelionDeg = Number(argPeri);
 73     var nodeDeg = Number(node);
 74 
 75     var [cometLongDeg, cometLatDeg, cometDistAU] = paMacros.pCometLongLatDist(lctHour, lctMin, lctSec, daylightSaving, zoneCorrectionHours, localDateDay, localDateMonth, localDateYear, perihelionEpochDay, perihelionEpochMonth, perihelionEpochYear, qAU, inclinationDeg, perihelionDeg, nodeDeg);
 76 
 77     var cometRAHours = paMacros.decimalDegreesToDegreeHours(paMacros.ecRA(cometLongDeg, 0, 0, cometLatDeg, 0, 0, greenwichDateDay, greenwichDateMonth, greenwichDateYear));
 78     var cometDecDeg1 = paMacros.ecDec(cometLongDeg, 0, 0, cometLatDeg, 0, 0, greenwichDateDay, greenwichDateMonth, greenwichDateYear);
 79 
 80     var cometRAHour = paMacros.decimalHoursHour(cometRAHours);
 81     var cometRAMin = paMacros.decimalHoursMinute(cometRAHours);
 82     var cometRASec = paMacros.decimalHoursSecond(cometRAHours);
 83     var cometDecDeg = paMacros.decimalDegreesDegrees(cometDecDeg1);
 84     var cometDecMin = paMacros.decimalDegreesMinutes(cometDecDeg1);
 85     var cometDecSec = paMacros.decimalDegreesSeconds(cometDecDeg1);
 86     var cometDistEarth = paUtils.round(cometDistAU, 2);
 87 
 88     return [cometRAHour, cometRAMin, cometRASec, cometDecDeg, cometDecMin, cometDecSec, cometDistEarth];
 89 }
 90 
 91 
 92 module.exports = {
 93     positionOfEllipticalComet,
 94     positionOfParabolicComet
 95 };