// astro.h // // Copyright (C) 2001-2009, the Celestia Development Team // Original version by Chris Laurel // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. #ifndef _CELENGINE_ASTRO_H_ #define _CELENGINE_ASTRO_H_ #include #include #include #include #include #define SOLAR_ABSMAG 4.83f #define LN_MAG 1.085736 #define LY_PER_PARSEC 3.26167 #define KM_PER_LY 9460730472580.8 // Old incorrect value; will be required for cel:// URL compatibility // #define OLD_KM_PER_LY 9466411842000.000 #define KM_PER_AU 149597870.7 #define AU_PER_LY (KM_PER_LY / KM_PER_AU) #define KM_PER_PARSEC (KM_PER_LY * LY_PER_PARSEC) // Julian year #define DAYS_PER_YEAR 365.25 #define SECONDS_PER_DAY 86400.0 #define MINUTES_PER_DAY 1440.0 #define HOURS_PER_DAY 24.0 #define MINUTES_PER_DEG 60.0 #define SECONDS_PER_DEG 3600.0 #define DEG_PER_HRA 15.0 #define EARTH_RADIUS 6378.14 #define JUPITER_RADIUS 71492.0 #define SOLAR_RADIUS 696000.0 class UniversalCoord; namespace astro { class Date { public: Date(); Date(int Y, int M, int D); Date(double); enum Format { Locale = 0, TZName = 1, UTCOffset = 2, ISO8601 = 3, }; const char* toCStr(Format format = Locale) const; operator double() const; static Date systemDate(); public: int year; int month; int day; int hour; int minute; int wday; // week day, 0 Sunday to 6 Saturday int utc_offset; // offset from utc in seconds std::string tzname; // timezone name double seconds; }; bool parseDate(const std::string&, Date&); // Time scale conversions // UTC - Coordinated Universal Time // TAI - International Atomic Time // TT - Terrestrial Time // TCB - Barycentric Coordinate Time // TDB - Barycentric Dynamical Time inline double secsToDays(double s) { return s * (1.0 / SECONDS_PER_DAY); } inline double daysToSecs(double d) { return d * SECONDS_PER_DAY; } // Convert to and from UTC dates double UTCtoTAI(const astro::Date& utc); astro::Date TAItoUTC(double tai); double UTCtoTDB(const astro::Date& utc); astro::Date TDBtoUTC(double tdb); astro::Date TDBtoLocal(double tdb); // Convert among uniform time scales double TTtoTAI(double tt); double TAItoTT(double tai); double TTtoTDB(double tt); double TDBtoTT(double tdb); // Conversions to and from Julian Date UTC--other time systems // should be preferred, since UTC Julian Dates aren't defined // during leapseconds. double JDUTCtoTAI(double utc); double TAItoJDUTC(double tai); // Magnitude conversions float lumToAbsMag(float lum); float lumToAppMag(float lum, float lyrs); float absMagToLum(float mag); float appMagToLum(float mag, float lyrs); template constexpr T absToAppMag(T absMag, T lyrs) { return (T) (absMag - 5 + 5 * log10(lyrs / LY_PER_PARSEC)); } template constexpr T appToAbsMag(T appMag, T lyrs) { return (T) (appMag + 5 - 5 * log10(lyrs / LY_PER_PARSEC)); } // Distance conversions template constexpr T lightYearsToParsecs(T ly) { return ly / (T) LY_PER_PARSEC; } template constexpr T parsecsToLightYears(T pc) { return pc * (T) LY_PER_PARSEC; } template constexpr T lightYearsToKilometers(T ly) { return ly * (T) KM_PER_LY; } template constexpr T kilometersToLightYears(T km) { return km / (T) KM_PER_LY; } template constexpr T lightYearsToAU(T ly) { return ly * (T) AU_PER_LY; } template constexpr T AUtoLightYears(T au) { return au / (T) AU_PER_LY; } template constexpr T AUtoKilometers(T au) { return au * (T) KM_PER_AU; } template constexpr T kilometersToAU(T km) { return km / (T) KM_PER_AU; } template constexpr T microLightYearsToKilometers(T ly) { return ly * ((T) KM_PER_LY * 1e-6); } template constexpr T kilometersToMicroLightYears(T km) { return km / ((T) KM_PER_LY * 1e-6); } template constexpr T microLightYearsToAU(T ly) { return ly * ((T) AU_PER_LY * 1e-6); } template constexpr T AUtoMicroLightYears(T au) { return au / ((T) AU_PER_LY * 1e-6); } constexpr double secondsToJulianDate(double sec) { return sec / SECONDS_PER_DAY; } constexpr double julianDateToSeconds(double jd) { return jd * SECONDS_PER_DAY; } bool isLengthUnit(std::string_view unitName); bool isTimeUnit(std::string_view unitName); bool isAngleUnit(std::string_view unitName); bool isMassUnit(std::string_view unitName); bool getLengthScale(std::string_view unitName, double& scale); bool getTimeScale(std::string_view unitName, double& scale); bool getAngleScale(std::string_view unitName, double& scale); bool getMassScale(std::string_view unitName, double& scale); void decimalToDegMinSec(double angle, int& degrees, int& minutes, double& seconds); double degMinSecToDecimal(int degrees, int minutes, double seconds); void decimalToHourMinSec(double angle, int& hours, int& minutes, double& seconds); Eigen::Vector3f equatorialToCelestialCart(float ra, float dec, float distance); Eigen::Vector3d equatorialToCelestialCart(double ra, double dec, double distance); Eigen::Vector3f equatorialToEclipticCartesian(float ra, float dec, float distance); Eigen::Quaterniond eclipticToEquatorial(); Eigen::Vector3d eclipticToEquatorial(const Eigen::Vector3d& v); Eigen::Quaterniond equatorialToGalactic(); Eigen::Vector3d equatorialToGalactic(const Eigen::Vector3d& v); void anomaly(double meanAnomaly, double eccentricity, double& trueAnomaly, double& eccentricAnomaly); double meanEclipticObliquity(double jd); // epoch J2000: 12 UT on 1 Jan 2000 constexpr inline double J2000 = 2451545.0; constexpr inline double speedOfLight = 299792.458; // km/s constexpr inline double G = 6.672e-11; // N m^2 / kg^2; gravitational constant constexpr inline double SolarMass = 1.989e30; constexpr inline double EarthMass = 5.972e24; constexpr inline double LunarMass = 7.346e22; constexpr inline double JupiterMass = 1.898e27; // Angle between J2000 mean equator and the ecliptic plane. // 23 deg 26' 21".448 (Seidelmann, _Explanatory Supplement to the // Astronomical Almanac_ (1992), eqn 3.222-1. constexpr inline double J2000Obliquity = 23.4392911_deg; constexpr inline double SOLAR_IRRADIANCE = 1367.6; // Watts / m^2 constexpr inline double SOLAR_POWER = 3.8462e26; // in Watts namespace literals { constexpr long double operator "" _au (long double au) { return AUtoKilometers(au); } constexpr long double operator "" _ly (long double ly) { return lightYearsToKilometers(ly); } constexpr long double operator "" _c (long double n) { return astro::speedOfLight * n; } } } // Convert a date structure to a Julian date std::ostream& operator<<(std::ostream& s, const astro::Date&); #endif // _CELENGINE_ASTRO_H_