From 80b0ef2447722937b8a0d11cb7262a408892e9a5 Mon Sep 17 00:00:00 2001 From: laheller Date: Sat, 25 Jan 2025 21:01:00 +0100 Subject: [PATCH 1/2] Add Visual Studio project/solution. Provide external functions for language binding. --- source/c/Astronomy.sln | 28 ++++ source/c/Astronomy.vcxproj | 137 +++++++++++++++++++ source/c/README.Windows.md | 13 ++ source/c/astronomy.h | 265 +++++++++++++++++++------------------ 4 files changed, 314 insertions(+), 129 deletions(-) create mode 100644 source/c/Astronomy.sln create mode 100644 source/c/Astronomy.vcxproj create mode 100644 source/c/README.Windows.md diff --git a/source/c/Astronomy.sln b/source/c/Astronomy.sln new file mode 100644 index 00000000..1ddd368f --- /dev/null +++ b/source/c/Astronomy.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35527.113 d17.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Astronomy", "Astronomy.vcxproj", "{E5211E34-82B2-4995-80C3-AAB72E89C6CF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E5211E34-82B2-4995-80C3-AAB72E89C6CF}.Debug|x64.ActiveCfg = Debug|x64 + {E5211E34-82B2-4995-80C3-AAB72E89C6CF}.Debug|x64.Build.0 = Debug|x64 + {E5211E34-82B2-4995-80C3-AAB72E89C6CF}.Debug|x86.ActiveCfg = Debug|Win32 + {E5211E34-82B2-4995-80C3-AAB72E89C6CF}.Debug|x86.Build.0 = Debug|Win32 + {E5211E34-82B2-4995-80C3-AAB72E89C6CF}.Release|x64.ActiveCfg = Release|x64 + {E5211E34-82B2-4995-80C3-AAB72E89C6CF}.Release|x64.Build.0 = Release|x64 + {E5211E34-82B2-4995-80C3-AAB72E89C6CF}.Release|x86.ActiveCfg = Release|Win32 + {E5211E34-82B2-4995-80C3-AAB72E89C6CF}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/source/c/Astronomy.vcxproj b/source/c/Astronomy.vcxproj new file mode 100644 index 00000000..4523e959 --- /dev/null +++ b/source/c/Astronomy.vcxproj @@ -0,0 +1,137 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + {E5211E34-82B2-4995-80C3-AAB72E89C6CF} + Win32Proj + 10.0 + + + + DynamicLibrary + true + v143 + + + DynamicLibrary + false + v143 + + + DynamicLibrary + true + v143 + + + DynamicLibrary + false + v143 + + + + + + + + + + + + + + + + + + + + + true + + + true + + + true + + + true + + + + WIN32;_DEBUG;_WINDOWS;_USRDLL;ASTRONOMY_EXPORTS;%(PreprocessorDefinitions) + Level3 + + + true + Windows + + + + + _DEBUG;_WINDOWS;_USRDLL;ASTRONOMY_EXPORTS;%(PreprocessorDefinitions) + Level3 + stdcpp17 + stdc17 + false + + + true + Windows + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;ASTRONOMY_EXPORTS;%(PreprocessorDefinitions) + Level3 + + + true + Windows + true + true + + + + + NDEBUG;_WINDOWS;_USRDLL;ASTRONOMY_EXPORTS;%(PreprocessorDefinitions) + Level3 + stdcpp17 + stdc17 + false + + + true + Windows + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/source/c/README.Windows.md b/source/c/README.Windows.md new file mode 100644 index 00000000..70e4ec6f --- /dev/null +++ b/source/c/README.Windows.md @@ -0,0 +1,13 @@ +# Astronomy Engine (C/C++) for Windows platform + +We include the project file (.vcxproj) and solution file (.sln) so that you can easily build the Astronomy Engine on the Windows platform using Visual Studio. + +## Build + +Open and build the `Astronomy.sln` file in Visual Studio (2022 and newer). +Please note that the `Desktop development with C++` workload is required to build the Astronomy Engine in Visual Studio. +A dynamic link library file `Astronomy.dll` is created on a successful build as an output. + +## Language bindings possibility + +The Astronomy Engine (C/C++) project is built in a way that allows to create [language binding](https://en.wikipedia.org/wiki/Language_binding) for other programming languages that support _external functions_. This way one can call C/C++ functions from Pascal language for example. diff --git a/source/c/astronomy.h b/source/c/astronomy.h index 9c73a196..25ca75c9 100644 --- a/source/c/astronomy.h +++ b/source/c/astronomy.h @@ -30,6 +30,13 @@ #include /* for size_t */ +#ifdef _WIN32 +#pragma pack(1) +#define _PREFIX __declspec(dllexport) +#else +#define _PREFIX +#endif // _WIN32 + #ifdef __cplusplus extern "C" { #endif @@ -642,10 +649,10 @@ typedef astro_func_result_t (* astro_search_func_t) (void *context, astro_time_t */ typedef double (* astro_deltat_func) (double ut); -double Astronomy_DeltaT_EspenakMeeus(double ut); -double Astronomy_DeltaT_JplHorizons(double ut); +_PREFIX double Astronomy_DeltaT_EspenakMeeus(double ut); +_PREFIX double Astronomy_DeltaT_JplHorizons(double ut); -void Astronomy_SetDeltaTFunction(astro_deltat_func func); +_PREFIX void Astronomy_SetDeltaTFunction(astro_deltat_func func); /** * @brief Indicates whether a body (especially Mercury or Venus) is best seen in the morning or evening. @@ -1158,45 +1165,45 @@ typedef struct astro_grav_sim_s astro_grav_sim_t; /*---------- functions ----------*/ -void Astronomy_Reset(void); -double Astronomy_VectorLength(astro_vector_t vector); -astro_angle_result_t Astronomy_AngleBetween(astro_vector_t a, astro_vector_t b); -const char *Astronomy_BodyName(astro_body_t body); -astro_body_t Astronomy_BodyCode(const char *name); -astro_observer_t Astronomy_MakeObserver(double latitude, double longitude, double height); +_PREFIX void Astronomy_Reset(void); +_PREFIX double Astronomy_VectorLength(astro_vector_t vector); +_PREFIX astro_angle_result_t Astronomy_AngleBetween(astro_vector_t a, astro_vector_t b); +_PREFIX const char *Astronomy_BodyName(astro_body_t body); +_PREFIX astro_body_t Astronomy_BodyCode(const char *name); +_PREFIX astro_observer_t Astronomy_MakeObserver(double latitude, double longitude, double height); #if !defined(ASTRONOMY_ENGINE_NO_CURRENT_TIME) -astro_time_t Astronomy_CurrentTime(void); +_PREFIX astro_time_t Astronomy_CurrentTime(void); #endif -astro_time_t Astronomy_MakeTime(int year, int month, int day, int hour, int minute, double second); -astro_time_t Astronomy_TimeFromUtc(astro_utc_t utc); -astro_utc_t Astronomy_UtcFromTime(astro_time_t time); -astro_status_t Astronomy_FormatTime(astro_time_t time, astro_time_format_t format, char *text, size_t size); -astro_time_t Astronomy_TimeFromDays(double ut); -astro_time_t Astronomy_TerrestrialTime(double tt); -astro_time_t Astronomy_AddDays(astro_time_t time, double days); -double Astronomy_SiderealTime(astro_time_t *time); -astro_func_result_t Astronomy_HelioDistance(astro_body_t body, astro_time_t time); -astro_vector_t Astronomy_HelioVector(astro_body_t body, astro_time_t time); -astro_vector_t Astronomy_GeoVector(astro_body_t body, astro_time_t time, astro_aberration_t aberration); -astro_vector_t Astronomy_GeoMoon(astro_time_t time); -astro_spherical_t Astronomy_EclipticGeoMoon(astro_time_t time); -astro_state_vector_t Astronomy_GeoMoonState(astro_time_t time); -astro_state_vector_t Astronomy_GeoEmbState(astro_time_t time); -astro_libration_t Astronomy_Libration(astro_time_t time); -astro_state_vector_t Astronomy_BaryState(astro_body_t body, astro_time_t time); -astro_state_vector_t Astronomy_HelioState(astro_body_t body, astro_time_t time); - -double Astronomy_MassProduct(astro_body_t body); -double Astronomy_PlanetOrbitalPeriod(astro_body_t body); - -astro_state_vector_t Astronomy_LagrangePoint( +_PREFIX astro_time_t Astronomy_MakeTime(int year, int month, int day, int hour, int minute, double second); +_PREFIX astro_time_t Astronomy_TimeFromUtc(astro_utc_t utc); +_PREFIX astro_utc_t Astronomy_UtcFromTime(astro_time_t time); +_PREFIX astro_status_t Astronomy_FormatTime(astro_time_t time, astro_time_format_t format, char *text, size_t size); +_PREFIX astro_time_t Astronomy_TimeFromDays(double ut); +_PREFIX astro_time_t Astronomy_TerrestrialTime(double tt); +_PREFIX astro_time_t Astronomy_AddDays(astro_time_t time, double days); +_PREFIX double Astronomy_SiderealTime(astro_time_t *time); +_PREFIX astro_func_result_t Astronomy_HelioDistance(astro_body_t body, astro_time_t time); +_PREFIX astro_vector_t Astronomy_HelioVector(astro_body_t body, astro_time_t time); +_PREFIX astro_vector_t Astronomy_GeoVector(astro_body_t body, astro_time_t time, astro_aberration_t aberration); +_PREFIX astro_vector_t Astronomy_GeoMoon(astro_time_t time); +_PREFIX astro_spherical_t Astronomy_EclipticGeoMoon(astro_time_t time); +_PREFIX astro_state_vector_t Astronomy_GeoMoonState(astro_time_t time); +_PREFIX astro_state_vector_t Astronomy_GeoEmbState(astro_time_t time); +_PREFIX astro_libration_t Astronomy_Libration(astro_time_t time); +_PREFIX astro_state_vector_t Astronomy_BaryState(astro_body_t body, astro_time_t time); +_PREFIX astro_state_vector_t Astronomy_HelioState(astro_body_t body, astro_time_t time); + +_PREFIX double Astronomy_MassProduct(astro_body_t body); +_PREFIX double Astronomy_PlanetOrbitalPeriod(astro_body_t body); + +_PREFIX astro_state_vector_t Astronomy_LagrangePoint( int point, astro_time_t time, astro_body_t major_body, astro_body_t minor_body ); -astro_state_vector_t Astronomy_LagrangePointFast( +_PREFIX astro_state_vector_t Astronomy_LagrangePointFast( int point, astro_state_vector_t major_state, double major_mass, @@ -1204,9 +1211,9 @@ astro_state_vector_t Astronomy_LagrangePointFast( double minor_mass ); -astro_jupiter_moons_t Astronomy_JupiterMoons(astro_time_t time); +_PREFIX astro_jupiter_moons_t Astronomy_JupiterMoons(astro_time_t time); -astro_equatorial_t Astronomy_Equator( +_PREFIX astro_equatorial_t Astronomy_Equator( astro_body_t body, astro_time_t *time, astro_observer_t observer, @@ -1214,79 +1221,79 @@ astro_equatorial_t Astronomy_Equator( astro_aberration_t aberration ); -astro_vector_t Astronomy_ObserverVector( +_PREFIX astro_vector_t Astronomy_ObserverVector( astro_time_t *time, astro_observer_t observer, astro_equator_date_t equdate ); -astro_state_vector_t Astronomy_ObserverState( +_PREFIX astro_state_vector_t Astronomy_ObserverState( astro_time_t *time, astro_observer_t observer, astro_equator_date_t equdate ); -astro_observer_t Astronomy_VectorObserver(astro_vector_t *vector, astro_equator_date_t equdate); +_PREFIX astro_observer_t Astronomy_VectorObserver(astro_vector_t *vector, astro_equator_date_t equdate); -double Astronomy_ObserverGravity(double latitude, double height); +_PREFIX double Astronomy_ObserverGravity(double latitude, double height); -astro_ecliptic_t Astronomy_SunPosition(astro_time_t time); -astro_ecliptic_t Astronomy_Ecliptic(astro_vector_t eqj); -astro_angle_result_t Astronomy_EclipticLongitude(astro_body_t body, astro_time_t time); +_PREFIX astro_ecliptic_t Astronomy_SunPosition(astro_time_t time); +_PREFIX astro_ecliptic_t Astronomy_Ecliptic(astro_vector_t eqj); +_PREFIX astro_angle_result_t Astronomy_EclipticLongitude(astro_body_t body, astro_time_t time); -astro_horizon_t Astronomy_Horizon( +_PREFIX astro_horizon_t Astronomy_Horizon( astro_time_t *time, astro_observer_t observer, double ra, double dec, astro_refraction_t refraction); -astro_angle_result_t Astronomy_AngleFromSun(astro_body_t body, astro_time_t time); -astro_elongation_t Astronomy_Elongation(astro_body_t body, astro_time_t time); -astro_elongation_t Astronomy_SearchMaxElongation(astro_body_t body, astro_time_t startTime); -astro_angle_result_t Astronomy_PairLongitude(astro_body_t body1, astro_body_t body2, astro_time_t time); +_PREFIX astro_angle_result_t Astronomy_AngleFromSun(astro_body_t body, astro_time_t time); +_PREFIX astro_elongation_t Astronomy_Elongation(astro_body_t body, astro_time_t time); +_PREFIX astro_elongation_t Astronomy_SearchMaxElongation(astro_body_t body, astro_time_t startTime); +_PREFIX astro_angle_result_t Astronomy_PairLongitude(astro_body_t body1, astro_body_t body2, astro_time_t time); /** @cond DOXYGEN_SKIP */ /* Provided for backward compatibility. Newer code can use Astronomy_PairLongitude. */ #define Astronomy_LongitudeFromSun(body,time) (Astronomy_PairLongitude((body), BODY_SUN, (time))) /** @endcond */ -astro_search_result_t Astronomy_SearchRelativeLongitude(astro_body_t body, double targetRelLon, astro_time_t startTime); -astro_angle_result_t Astronomy_MoonPhase(astro_time_t time); -astro_search_result_t Astronomy_SearchMoonPhase(double targetLon, astro_time_t startTime, double limitDays); -astro_moon_quarter_t Astronomy_SearchMoonQuarter(astro_time_t startTime); -astro_moon_quarter_t Astronomy_NextMoonQuarter(astro_moon_quarter_t mq); -astro_lunar_eclipse_t Astronomy_SearchLunarEclipse(astro_time_t startTime); -astro_lunar_eclipse_t Astronomy_NextLunarEclipse(astro_time_t prevEclipseTime); -astro_global_solar_eclipse_t Astronomy_SearchGlobalSolarEclipse(astro_time_t startTime); -astro_global_solar_eclipse_t Astronomy_NextGlobalSolarEclipse(astro_time_t prevEclipseTime); -astro_local_solar_eclipse_t Astronomy_SearchLocalSolarEclipse(astro_time_t startTime, astro_observer_t observer); -astro_local_solar_eclipse_t Astronomy_NextLocalSolarEclipse(astro_time_t prevEclipseTime, astro_observer_t observer); -astro_transit_t Astronomy_SearchTransit(astro_body_t body, astro_time_t startTime); -astro_transit_t Astronomy_NextTransit(astro_body_t body, astro_time_t prevTransitTime); -astro_node_event_t Astronomy_SearchMoonNode(astro_time_t startTime); -astro_node_event_t Astronomy_NextMoonNode(astro_node_event_t prevNode); - -astro_search_result_t Astronomy_Search( +_PREFIX astro_search_result_t Astronomy_SearchRelativeLongitude(astro_body_t body, double targetRelLon, astro_time_t startTime); +_PREFIX astro_angle_result_t Astronomy_MoonPhase(astro_time_t time); +_PREFIX astro_search_result_t Astronomy_SearchMoonPhase(double targetLon, astro_time_t startTime, double limitDays); +_PREFIX astro_moon_quarter_t Astronomy_SearchMoonQuarter(astro_time_t startTime); +_PREFIX astro_moon_quarter_t Astronomy_NextMoonQuarter(astro_moon_quarter_t mq); +_PREFIX astro_lunar_eclipse_t Astronomy_SearchLunarEclipse(astro_time_t startTime); +_PREFIX astro_lunar_eclipse_t Astronomy_NextLunarEclipse(astro_time_t prevEclipseTime); +_PREFIX astro_global_solar_eclipse_t Astronomy_SearchGlobalSolarEclipse(astro_time_t startTime); +_PREFIX astro_global_solar_eclipse_t Astronomy_NextGlobalSolarEclipse(astro_time_t prevEclipseTime); +_PREFIX astro_local_solar_eclipse_t Astronomy_SearchLocalSolarEclipse(astro_time_t startTime, astro_observer_t observer); +_PREFIX astro_local_solar_eclipse_t Astronomy_NextLocalSolarEclipse(astro_time_t prevEclipseTime, astro_observer_t observer); +_PREFIX astro_transit_t Astronomy_SearchTransit(astro_body_t body, astro_time_t startTime); +_PREFIX astro_transit_t Astronomy_NextTransit(astro_body_t body, astro_time_t prevTransitTime); +_PREFIX astro_node_event_t Astronomy_SearchMoonNode(astro_time_t startTime); +_PREFIX astro_node_event_t Astronomy_NextMoonNode(astro_node_event_t prevNode); + +_PREFIX astro_search_result_t Astronomy_Search( astro_search_func_t func, void *context, astro_time_t t1, astro_time_t t2, double dt_tolerance_seconds); -astro_search_result_t Astronomy_SearchSunLongitude( +_PREFIX astro_search_result_t Astronomy_SearchSunLongitude( double targetLon, astro_time_t startTime, double limitDays); -astro_hour_angle_t Astronomy_SearchHourAngleEx( +_PREFIX astro_hour_angle_t Astronomy_SearchHourAngleEx( astro_body_t body, astro_observer_t observer, double hourAngle, astro_time_t startTime, int direction); -astro_func_result_t Astronomy_HourAngle( +_PREFIX astro_func_result_t Astronomy_HourAngle( astro_body_t body, astro_time_t *time, astro_observer_t observer); @@ -1302,7 +1309,7 @@ astro_func_result_t Astronomy_HourAngle( /** @endcond */ -astro_search_result_t Astronomy_SearchRiseSetEx( +_PREFIX astro_search_result_t Astronomy_SearchRiseSetEx( astro_body_t body, astro_observer_t observer, astro_direction_t direction, @@ -1310,7 +1317,7 @@ astro_search_result_t Astronomy_SearchRiseSetEx( double limitDays, double metersAboveGround); -astro_search_result_t Astronomy_SearchAltitude( +_PREFIX astro_search_result_t Astronomy_SearchAltitude( astro_body_t body, astro_observer_t observer, astro_direction_t direction, @@ -1318,55 +1325,55 @@ astro_search_result_t Astronomy_SearchAltitude( double limitDays, double altitude); -astro_atmosphere_t Astronomy_Atmosphere(double elevationMeters); - -astro_axis_t Astronomy_RotationAxis(astro_body_t body, astro_time_t *time); - -astro_seasons_t Astronomy_Seasons(int year); -astro_illum_t Astronomy_Illumination(astro_body_t body, astro_time_t time); -astro_illum_t Astronomy_SearchPeakMagnitude(astro_body_t body, astro_time_t startTime); -astro_apsis_t Astronomy_SearchLunarApsis(astro_time_t startTime); -astro_apsis_t Astronomy_NextLunarApsis(astro_apsis_t apsis); -astro_apsis_t Astronomy_SearchPlanetApsis(astro_body_t body, astro_time_t startTime); -astro_apsis_t Astronomy_NextPlanetApsis(astro_body_t body, astro_apsis_t apsis); - -astro_rotation_t Astronomy_IdentityMatrix(void); -astro_rotation_t Astronomy_InverseRotation(astro_rotation_t rotation); -astro_rotation_t Astronomy_CombineRotation(astro_rotation_t a, astro_rotation_t b); -astro_rotation_t Astronomy_Pivot(astro_rotation_t rotation, int axis, double angle); -astro_vector_t Astronomy_VectorFromSphere(astro_spherical_t sphere, astro_time_t time); -astro_spherical_t Astronomy_SphereFromVector(astro_vector_t vector); -astro_equatorial_t Astronomy_EquatorFromVector(astro_vector_t vector); -astro_vector_t Astronomy_VectorFromHorizon(astro_spherical_t sphere, astro_time_t time, astro_refraction_t refraction); -astro_spherical_t Astronomy_HorizonFromVector(astro_vector_t vector, astro_refraction_t refraction); -astro_vector_t Astronomy_RotateVector(astro_rotation_t rotation, astro_vector_t vector); -astro_state_vector_t Astronomy_RotateState(astro_rotation_t rotation, astro_state_vector_t state); - -astro_rotation_t Astronomy_Rotation_EQD_EQJ(astro_time_t *time); -astro_rotation_t Astronomy_Rotation_EQD_ECL(astro_time_t *time); -astro_rotation_t Astronomy_Rotation_EQD_ECT(astro_time_t *time); -astro_rotation_t Astronomy_Rotation_EQD_HOR(astro_time_t *time, astro_observer_t observer); -astro_rotation_t Astronomy_Rotation_EQJ_EQD(astro_time_t *time); -astro_rotation_t Astronomy_Rotation_EQJ_ECT(astro_time_t *time); -astro_rotation_t Astronomy_Rotation_EQJ_ECL(void); -astro_rotation_t Astronomy_Rotation_EQJ_HOR(astro_time_t *time, astro_observer_t observer); -astro_rotation_t Astronomy_Rotation_ECL_EQD(astro_time_t *time); -astro_rotation_t Astronomy_Rotation_ECL_EQJ(void); -astro_rotation_t Astronomy_Rotation_ECL_HOR(astro_time_t *time, astro_observer_t observer); -astro_rotation_t Astronomy_Rotation_ECT_EQJ(astro_time_t *time); -astro_rotation_t Astronomy_Rotation_ECT_EQD(astro_time_t *time); -astro_rotation_t Astronomy_Rotation_HOR_EQD(astro_time_t *time, astro_observer_t observer); -astro_rotation_t Astronomy_Rotation_HOR_EQJ(astro_time_t *time, astro_observer_t observer); -astro_rotation_t Astronomy_Rotation_HOR_ECL(astro_time_t *time, astro_observer_t observer); -astro_rotation_t Astronomy_Rotation_EQJ_GAL(void); -astro_rotation_t Astronomy_Rotation_GAL_EQJ(void); - -double Astronomy_Refraction(astro_refraction_t refraction, double altitude); -double Astronomy_InverseRefraction(astro_refraction_t refraction, double bent_altitude); - -astro_constellation_t Astronomy_Constellation(double ra, double dec); - -astro_status_t Astronomy_GravSimInit( +_PREFIX astro_atmosphere_t Astronomy_Atmosphere(double elevationMeters); + +_PREFIX astro_axis_t Astronomy_RotationAxis(astro_body_t body, astro_time_t *time); + +_PREFIX astro_seasons_t Astronomy_Seasons(int year); +_PREFIX astro_illum_t Astronomy_Illumination(astro_body_t body, astro_time_t time); +_PREFIX astro_illum_t Astronomy_SearchPeakMagnitude(astro_body_t body, astro_time_t startTime); +_PREFIX astro_apsis_t Astronomy_SearchLunarApsis(astro_time_t startTime); +_PREFIX astro_apsis_t Astronomy_NextLunarApsis(astro_apsis_t apsis); +_PREFIX astro_apsis_t Astronomy_SearchPlanetApsis(astro_body_t body, astro_time_t startTime); +_PREFIX astro_apsis_t Astronomy_NextPlanetApsis(astro_body_t body, astro_apsis_t apsis); + +_PREFIX astro_rotation_t Astronomy_IdentityMatrix(void); +_PREFIX astro_rotation_t Astronomy_InverseRotation(astro_rotation_t rotation); +_PREFIX astro_rotation_t Astronomy_CombineRotation(astro_rotation_t a, astro_rotation_t b); +_PREFIX astro_rotation_t Astronomy_Pivot(astro_rotation_t rotation, int axis, double angle); +_PREFIX astro_vector_t Astronomy_VectorFromSphere(astro_spherical_t sphere, astro_time_t time); +_PREFIX astro_spherical_t Astronomy_SphereFromVector(astro_vector_t vector); +_PREFIX astro_equatorial_t Astronomy_EquatorFromVector(astro_vector_t vector); +_PREFIX astro_vector_t Astronomy_VectorFromHorizon(astro_spherical_t sphere, astro_time_t time, astro_refraction_t refraction); +_PREFIX astro_spherical_t Astronomy_HorizonFromVector(astro_vector_t vector, astro_refraction_t refraction); +_PREFIX astro_vector_t Astronomy_RotateVector(astro_rotation_t rotation, astro_vector_t vector); +_PREFIX astro_state_vector_t Astronomy_RotateState(astro_rotation_t rotation, astro_state_vector_t state); + +_PREFIX astro_rotation_t Astronomy_Rotation_EQD_EQJ(astro_time_t *time); +_PREFIX astro_rotation_t Astronomy_Rotation_EQD_ECL(astro_time_t *time); +_PREFIX astro_rotation_t Astronomy_Rotation_EQD_ECT(astro_time_t *time); +_PREFIX astro_rotation_t Astronomy_Rotation_EQD_HOR(astro_time_t *time, astro_observer_t observer); +_PREFIX astro_rotation_t Astronomy_Rotation_EQJ_EQD(astro_time_t *time); +_PREFIX astro_rotation_t Astronomy_Rotation_EQJ_ECT(astro_time_t *time); +_PREFIX astro_rotation_t Astronomy_Rotation_EQJ_ECL(void); +_PREFIX astro_rotation_t Astronomy_Rotation_EQJ_HOR(astro_time_t *time, astro_observer_t observer); +_PREFIX astro_rotation_t Astronomy_Rotation_ECL_EQD(astro_time_t *time); +_PREFIX astro_rotation_t Astronomy_Rotation_ECL_EQJ(void); +_PREFIX astro_rotation_t Astronomy_Rotation_ECL_HOR(astro_time_t *time, astro_observer_t observer); +_PREFIX astro_rotation_t Astronomy_Rotation_ECT_EQJ(astro_time_t *time); +_PREFIX astro_rotation_t Astronomy_Rotation_ECT_EQD(astro_time_t *time); +_PREFIX astro_rotation_t Astronomy_Rotation_HOR_EQD(astro_time_t *time, astro_observer_t observer); +_PREFIX astro_rotation_t Astronomy_Rotation_HOR_EQJ(astro_time_t *time, astro_observer_t observer); +_PREFIX astro_rotation_t Astronomy_Rotation_HOR_ECL(astro_time_t *time, astro_observer_t observer); +_PREFIX astro_rotation_t Astronomy_Rotation_EQJ_GAL(void); +_PREFIX astro_rotation_t Astronomy_Rotation_GAL_EQJ(void); + +_PREFIX double Astronomy_Refraction(astro_refraction_t refraction, double altitude); +_PREFIX double Astronomy_InverseRefraction(astro_refraction_t refraction, double bent_altitude); + +_PREFIX astro_constellation_t Astronomy_Constellation(double ra, double dec); + +_PREFIX astro_status_t Astronomy_GravSimInit( astro_grav_sim_t **simOut, astro_body_t originBody, astro_time_t time, @@ -1374,23 +1381,23 @@ astro_status_t Astronomy_GravSimInit( const astro_state_vector_t *bodyStateArray ); -astro_status_t Astronomy_GravSimUpdate( +_PREFIX astro_status_t Astronomy_GravSimUpdate( astro_grav_sim_t *sim, astro_time_t time, int numBodies, astro_state_vector_t *bodyStateArray ); -astro_state_vector_t Astronomy_GravSimBodyState( +_PREFIX astro_state_vector_t Astronomy_GravSimBodyState( astro_grav_sim_t *sim, astro_body_t body ); -astro_time_t Astronomy_GravSimTime(const astro_grav_sim_t *sim); -int Astronomy_GravSimNumBodies(const astro_grav_sim_t *sim); -astro_body_t Astronomy_GravSimOrigin(const astro_grav_sim_t *sim); -void Astronomy_GravSimSwap(astro_grav_sim_t *sim); -void Astronomy_GravSimFree(astro_grav_sim_t *sim); +_PREFIX astro_time_t Astronomy_GravSimTime(const astro_grav_sim_t *sim); +_PREFIX int Astronomy_GravSimNumBodies(const astro_grav_sim_t *sim); +_PREFIX astro_body_t Astronomy_GravSimOrigin(const astro_grav_sim_t *sim); +_PREFIX void Astronomy_GravSimSwap(astro_grav_sim_t *sim); +_PREFIX void Astronomy_GravSimFree(astro_grav_sim_t *sim); /** * @brief A function for which to solve a light-travel time problem. @@ -1404,20 +1411,20 @@ void Astronomy_GravSimFree(astro_grav_sim_t *sim); */ typedef astro_vector_t (* astro_position_func_t) (void *context, astro_time_t time); -astro_vector_t Astronomy_CorrectLightTravel( +_PREFIX astro_vector_t Astronomy_CorrectLightTravel( void *context, astro_position_func_t func, astro_time_t time ); -astro_vector_t Astronomy_BackdatePosition( +_PREFIX astro_vector_t Astronomy_BackdatePosition( astro_time_t time, astro_body_t observerBody, astro_body_t targetBody, astro_aberration_t aberration ); -astro_status_t Astronomy_DefineStar( +_PREFIX astro_status_t Astronomy_DefineStar( astro_body_t body, double ra, double dec, From 137ede5cabf30d8c5a648e378c342f597e8708bc Mon Sep 17 00:00:00 2001 From: laheller Date: Sat, 25 Jan 2025 22:32:38 +0100 Subject: [PATCH 2/2] Add FreePascal language support and demo. --- demo/pascal/Demo.pas | 126 ++++++ demo/pascal/README.md | 13 + source/pascal/Astronomy.pas | 802 ++++++++++++++++++++++++++++++++++++ source/pascal/README.md | 15 + 4 files changed, 956 insertions(+) create mode 100644 demo/pascal/Demo.pas create mode 100644 demo/pascal/README.md create mode 100644 source/pascal/Astronomy.pas create mode 100644 source/pascal/README.md diff --git a/demo/pascal/Demo.pas b/demo/pascal/Demo.pas new file mode 100644 index 00000000..2d3411c4 --- /dev/null +++ b/demo/pascal/Demo.pas @@ -0,0 +1,126 @@ +program Demo; + +{$mode objfpc}{$H+} + +uses + Classes, + SysUtils, + Astronomy; + +const + Months: array[1..12] of string = ( + 'January', 'February', 'March', 'April', + 'May', 'June', 'July', 'August', + 'September', 'October', 'November', 'December'); + + // Observer site: Slovakia/Bratislava + Latitude: Double = 48.143889; + Longitude: Double = 17.109722; + Elevation: Double = 124; + + // ICRS equatorial coordinates of the star HD1 (Henry Draper catalog, star #1) + RA_ICRS: Double = 1.2961219444444443; // degrees + DE_ICRS: Double = 67.84007388888888; // degrees + +var + at1: AstroTime; + st1: Double; + ptr: PAstroTime; + mph: AstroAngleResult; + MoonPhase: string; + lap: AstroApsis; + sss: AstroSeasons; + obs: AstroObserver; + coo: AstroEquatorial; + +function ToDateString(Event: AstroTime): string; +var + t: AstroUTC; +begin + t := Astronomy_UtcFromTime(Event); + ToDateString := '' + IntToStr(t.Year) + '. ' + Months[t.Month] + '. ' + IntToStr(t.Day) + '. '; +end; + +BEGIN + at1 := Astronomy_MakeTime(2025, 1, 20, 22, 20, 0.5); + WriteLn('Astro time for 2025-Jan-20 at 22:20:30 -> ', at1.UT:20:6, #10#13); + + // Define an observer site + obs.Latitude := Latitude; + obs.Longitude := Longitude; + obs.Height := Elevation; + + at1 := Astronomy_CurrentTime(); + WriteLn('Current astro time: ', at1.UT:20:6, #10#13); + + WriteLn('Body name: ', Astronomy_BodyName(AstroBody.BODY_SUN), #10#13); + + WriteLn('Body code for "Earth": [', Astronomy_BodyCode(PChar('Earth')), ']', #10#13); + + // Calculate Greenwich sidereal time using current time + ptr := New(PAstroTime); + ptr^.UT := at1.UT; + ptr^.TT := at1.TT; + ptr^.ST := 0 / 0; // gives NaN, must be set, otherwise GAST calculation doesn't work + st1 := Astronomy_SiderealTime(ptr); + WriteLn('Greenwich apparent sidereal time: ', st1:20:6, ' hours', #10#13); + + // Get the current moon phase + mph := Astronomy_MoonPhase(at1); + if mph.Status <> AstroStatus.ASTRO_SUCCESS then + WriteLn('An error occured during the Moon phase calculation!') + else begin + if (mph.Angle = 0) or (mph.Angle = 360) then MoonPhase := 'New Moon'; + if (mph.Angle > 0) and (mph.Angle < 90) then MoonPhase := 'Waxing Crescent'; + if mph.Angle = 90 then MoonPhase := 'First quarter'; + if (mph.Angle > 90) and (mph.Angle < 180) then MoonPhase := 'Waxing Gibbous'; + if mph.Angle = 180 then MoonPhase := 'Full Moon'; + if (mph.Angle > 180) and (mph.Angle < 270) then MoonPhase := 'Waning Gibbous'; + if mph.Angle = 270 then MoonPhase := 'Last quarter'; + if (mph.Angle > 270) and (mph.Angle < 360) then MoonPhase := 'Waning Crescent'; + WriteLn('Current Moon phase: ' + MoonPhase + #10#13); + end; + + // Search for the first lunar apsis event since now + lap := Astronomy_SearchLunarApsis(at1); + if lap.Status <> AstroStatus.ASTRO_SUCCESS then + WriteLn('An error occured during the Moon apsis calculation!') + else + WriteLn('Next Lunar ', lap.Kind, ' occurs at ', ToDateString(lap.Time), ' at the distance of ', lap.DistKM:12:3, ' km from Earth.'); + + // Search for next lunar apsis event + lap := Astronomy_NextLunarApsis(lap); + if lap.Status <> AstroStatus.ASTRO_SUCCESS then + WriteLn('An error occured during the Moon apsis calculation!') + else + WriteLn('Next Lunar ', lap.Kind, ' occurs at ', ToDateString(lap.Time), ' at the distance of ', lap.DistKM:12:3, ' km from Earth.', #10#13); + + // Search for seasons in 2025 + sss := Astronomy_Seasons(2025); + if sss.Status <> AstroStatus.ASTRO_SUCCESS then + WriteLn('An error occured during the 2025 seasons calculation!') + else begin + WriteLn('2025 march equinox occurs at: ', ToDateString(sss.MarEquinox)); + WriteLn('2025 june solstice occurs at: ', ToDateString(sss.JunSolstice)); + WriteLn('2025 sept equinox occurs at: ', ToDateString(sss.SepEquinox)); + WriteLn('2025 dec solstice occurs at: ', ToDateString(sss.DecSolstice), #10#13); + end; + + // Find equatorial coordinates of date for the star HD1 as seen from Slovakia/Bratislava + if Astronomy_DefineStar(AstroBody.BODY_STAR1, RA_ICRS / 15.0, DE_ICRS, 1000.0) <> AstroStatus.ASTRO_SUCCESS then + WriteLn('An error occured during defining a custom star!') + else begin + coo := Astronomy_Equator(AstroBody.BODY_STAR1, ptr, obs, AstroEquatorDate.EQUATOR_OF_DATE, AstroAberration.NO_ABERRATION); + if coo.Status <> AstroStatus.ASTRO_SUCCESS then + WriteLn('An error occured during the coordinate conversion!') + else begin + WriteLn('Equatorial coordinates of the HD1 star at ', ToDateString(at1)); + WriteLn('Right ascension: ', coo.RA:12:3, ' hours'); + WriteLn('Declination: ', coo.Dec:12:3, ' degrees'); + end; + end; + + // Release the dynamically allocated object used in the previous calculations + Dispose(ptr); +END. + diff --git a/demo/pascal/README.md b/demo/pascal/README.md new file mode 100644 index 00000000..0bd584c7 --- /dev/null +++ b/demo/pascal/README.md @@ -0,0 +1,13 @@ +# Astronomy Engine examples in Pascal +--- +### [Various](Demo.pas) +The demo program shows following astronomy calculations: +- Setting up the observer site +- Creating `AstroTime` object for a fixed date/time +- Creating `AstroTime` object for the `now` moment for later calcualtions +- Calculating and displaying the current Moon phase +- Calculating upcoming lunar apsis events +- Calculating the equinox and solstice events for the year 2025 +- Calculating the equatorial coordinates of date for the star HD1 from Henry Draper catalog for the current observer site + +To execute this demo (after build) you will also need the `Astronomy.dll` binary built from Astronomy Engine C/C++ project! diff --git a/source/pascal/Astronomy.pas b/source/pascal/Astronomy.pas new file mode 100644 index 00000000..36ce0083 --- /dev/null +++ b/source/pascal/Astronomy.pas @@ -0,0 +1,802 @@ +unit Astronomy; + +{$mode objfpc}{$H+} + +interface + +uses + Classes + { you can add units after this }; + +const + LibraryName = 'astronomy'; // should refer the astronomy.dll file + + C_AUDAY : Double = 173.1446326846693; + KM_PER_AU : Double = 1.4959787069098932e+8; + AU_PER_LY : Double = 63241.07708807546; + DEG2RAD : Double = 0.017453292519943296; + HOUR2RAD : Double = 0.2617993877991494365; + RAD2DEG : Double = 57.295779513082321; + RAD2HOUR : Double = 3.819718634205488; + SUN_RADIUS_KM : Double = 695700.0; + MERCURY_EQUATORIAL_RADIUS_KM : Double = 2440.5; + MERCURY_POLAR_RADIUS_KM : Double = 2438.3; + VENUS_RADIUS_KM : Double = 6051.8; + EARTH_EQUATORIAL_RADIUS_KM : Double = 6378.1366; + EARTH_FLATTENING : Double = 0.996647180302104; + EARTH_POLAR_RADIUS_KM : Double = 6378.1366 * 0.996647180302104; + MOON_EQUATORIAL_RADIUS_KM : Double = 1738.1; + MOON_POLAR_RADIUS_KM : Double = 1736.0; + MARS_EQUATORIAL_RADIUS_KM : Double = 3396.2; + MARS_POLAR_RADIUS_KM : Double = 3376.2; + JUPITER_EQUATORIAL_RADIUS_KM : Double = 71492.0; + JUPITER_POLAR_RADIUS_KM : Double = 66854.0; + JUPITER_MEAN_RADIUS_KM : Double = 69911.0; + IO_RADIUS_KM : Double = 1821.6; + EUROPA_RADIUS_KM : Double = 1560.8; + GANYMEDE_RADIUS_KM : Double = 2631.2; + CALLISTO_RADIUS_KM : Double = 2410.3; + SATURN_EQUATORIAL_RADIUS_KM : Double = 60268.0; + SATURN_POLAR_RADIUS_KM : Double = 54364.0; + URANUS_EQUATORIAL_RADIUS_KM : Double = 25559.0; + URANUS_POLAR_RADIUS_KM : Double = 24973.0; + NEPTUNE_EQUATORIAL_RADIUS_KM : Double = 24764.0; + NEPTUNE_POLAR_RADIUS_KM : Double = 24341.0; + PLUTO_RADIUS_KM : Double = 1188.3; + +type + // Status of the last operation. + AstroStatus = ( + ASTRO_SUCCESS = 0, // The operation was successful. + ASTRO_NOT_INITIALIZED = 1, // A placeholder that can be used for data that is not yet initialized. + ASTRO_INVALID_BODY = 2, // The celestial body was not valid. Different sets of bodies are supported depending on the function. + ASTRO_NO_CONVERGE = 3, // A numeric solver failed to converge. This should not happen unless there is a bug in Astronomy Engine. + ASTRO_BAD_TIME = 4, // The provided date/time is outside the range allowed by this function. + ASTRO_BAD_VECTOR = 5, // Vector magnitude is too small to be normalized into a unit vector. + ASTRO_SEARCH_FAILURE = 6, // Search was not able to find an ascending root crossing of the function in the specified time interval. + ASTRO_EARTH_NOT_ALLOWED = 7, // The Earth cannot be treated as a celestial body seen from an observer on the Earth itself. + ASTRO_NO_MOON_QUARTER = 8, // No lunar quarter occurs inside the specified time range. + ASTRO_WRONG_MOON_QUARTER = 9, // Internal error: Astronomy_NextMoonQuarter found the wrong moon quarter. + ASTRO_INTERNAL_ERROR = 10, // A self-check failed inside the code somewhere, indicating a bug needs to be fixed. + ASTRO_INVALID_PARAMETER = 11, // A parameter value passed to a function was not valid. + ASTRO_FAIL_APSIS = 12, // Special-case logic for finding Neptune/Pluto apsis failed. + ASTRO_BUFFER_TOO_SMALL = 13, // A provided buffer's size is too small to receive the requested data. + ASTRO_OUT_OF_MEMORY = 14, // An attempt to allocate memory failed. + ASTRO_INCONSISTENT_TIMES = 15 // The provided initial state vectors did not have matching times. + ); + + // A celestial body. + AstroBody = ( + BODY_INVALID = -1, // An invalid or undefined celestial body. + BODY_MERCURY = 0, // Mercury + BODY_VENUS = 1, // Venus + BODY_EARTH = 2, // Earth + BODY_MARS = 3, // Mars + BODY_JUPITER = 4, // Jupiter + BODY_SATURN = 5, // Saturn + BODY_URANUS = 6, // Uranus + BODY_NEPTUNE = 7, // Neptune + BODY_PLUTO = 8, // Pluto + BODY_SUN = 9, // Sun + BODY_MOON = 10, // Moon + BODY_EMB = 11, // Earth/Moon Barycenter + BODY_SSB = 12, // Solar System Barycenter + BODY_STAR1 = 101, // user-defined star #1 + BODY_STAR2 = 102, // user-defined star #2 + BODY_STAR3 = 103, // user-defined star #3 + BODY_STAR4 = 104, // user-defined star #4 + BODY_STAR5 = 105, // user-defined star #5 + BODY_STAR6 = 106, // user-defined star #6 + BODY_STAR7 = 107, // user-defined star #7 + BODY_STAR8 = 108 // user-defined star #8 + ); + + // Selects whether to correct for atmospheric refraction, and if so, how. + AstroRefraction = ( + REFRACTION_NONE = 0, // No atmospheric refraction correction (airless). + REFRACTION_NORMAL = 1, // Recommended correction for standard atmospheric refraction. + REFRACTION_JPLHOR = 2 // Used only for compatibility testing with JPL Horizons online tool. + ); + + // Indicates whether a body (especially Mercury or Venus) is best seen in the morning or evening. + AstroVisibility = ( + VISIBLE_MORNING = 0, // The body is best visible in the morning, before sunrise. + VISIBLE_EVENING = 1 // The body is best visible in the evening, after sunset. + ); + + // The type of apsis: pericenter (closest approach) or apocenter (farthest distance). + AstroApsisKind = ( + APSIS_PERICENTER = 0, // The body is at its closest approach to the object it orbits. + APSIS_APOCENTER = 1, // The body is at its farthest distance from the object it orbits. + APSIS_INVALID = 2 // Undefined or invalid apsis. + ); + + // The different kinds of lunar/solar eclipses. + AstroEclipseKind = ( + ECLIPSE_NONE = 0, // No eclipse found. + ECLIPSE_PENUMBRAL = 1, // A penumbral lunar eclipse. (Never used for a solar eclipse.) + ECLIPSE_PARTIAL = 2, // A partial lunar/solar eclipse. + ECLIPSE_ANNULAR = 3, // An annular solar eclipse. (Never used for a lunar eclipse.) + ECLIPSE_TOTAL = 4 // A total lunar/solar eclipse. + ); + + // Aberration calculation options. + AstroAberration = ( + ABERRATION = 0, // Request correction for aberration. + NO_ABERRATION = 1 // Do not correct for aberration. + ); + + // Selects the date for which the Earth's equator is to be used for representing equatorial coordinates. + AstroEquatorDate = ( + EQUATOR_J2000 = 0, // Represent equatorial coordinates in the J2000 epoch. + EQUATOR_OF_DATE = 1 // Represent equatorial coordinates using the Earth's equator at the given date and time. + ); + + // Selects whether to search for a rise time or a set time. + AstroDirection = ( + DIRECTION_SET = -1, // Search for the time a body finishes sinking below the horizon. + DIRECTION_RISE = 1 // Search for the time a body begins to rise above the horizon. + ); + + // Selects the output format of the function #Astronomy_FormatTime. + AstroTimeFormat = ( + TIME_FORMAT_DAY = 0, // Truncate to UTC calendar date only, e.g. `2020-12-31`. Buffer size must be at least 11 characters. + TIME_FORMAT_MINUTE = 1, // Round to nearest UTC minute, e.g. `2020-12-31T15:47Z`. Buffer size must be at least 18 characters. + TIME_FORMAT_SECOND = 2, // Round to nearest UTC second, e.g. `2020-12-31T15:47:32Z`. Buffer size must be at least 21 characters. + TIME_FORMAT_MILLI = 3 // Round to nearest UTC millisecond, e.g. `2020-12-31T15:47:32.397Z`. Buffer size must be at least 25 characters. + ); + + // Indicates whether a crossing through the ecliptic plane is ascending or descending. + AstroNodeKind = ( + DESCENDING_NODE = -1, // The body passes through the ecliptic plane from north to south. + INVALID_NODE = 0, // Placeholder value for a missing or invalid node. + ASCENDING_NODE = 1 // The body passes through the ecliptic plane from south to north. + ); + + // A date and time used for astronomical calculations. + AstroTime = packed record + UT: Double; // UT1/UTC number of days since noon on January 1, 2000. + TT: Double; // Terrestrial Time days since noon on January 1, 2000. + Psi: Double; // For internal use only. Used to optimize Earth tilt calculations. + Eps: Double; // For internal use only. Used to optimize Earth tilt calculations. + ST: Double; // For internal use only. Lazy-caches sidereal time (Earth rotation). + end; + + // Pointer to #AstroTime record. + PAstroTime = ^AstroTime; + + // A calendar date and time expressed in UTC. + AstroUTC = packed record + Year: Int32; // The year value, e.g. 2019. + Month: Int32; // The month value: 1=January, 2=February, ..., 12=December. + Day: Int32; // The day of the month in the range 1..31. + Hour: Int32; // The hour of the day in the range 0..23. + Minute: Int32; // The minute of the hour in the range 0..59. + Second: Double; // The floating point number of seconds in the range [0,60). + end; + + // A 3D Cartesian vector whose components are expressed in Astronomical Units (AU). + AstroVector = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + X: Double; // The Cartesian x-coordinate of the vector in AU. + Y: Double; // The Cartesian y-coordinate of the vector in AU. + Z: Double; // The Cartesian z-coordinate of the vector in AU. + T: AstroTime; // The date and time at which this vector is valid. + end; + + // Pointer to #AstroVector record + PAstroVector = ^AstroVector; + + // A state vector that contains a position (AU) and velocity (AU/day). + AstroStateVector = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + X: Double; // The Cartesian position x-coordinate of the vector in AU. + Y: Double; // The Cartesian position y-coordinate of the vector in AU. + Z: Double; // The Cartesian position z-coordinate of the vector in AU. + VX: Double; // The Cartesian velocity x-coordinate of the vector in AU/day. + VY: Double; // The Cartesian velocity y-coordinate of the vector in AU/day. + VZ: Double; // The Cartesian velocity z-coordinate of the vector in AU/day. + T: AstroTime; // The date and time at which this state vector is valid. + end; + + // Pointer to `AstroStateVector` record. + PAstroStateVector = ^AstroStateVector; + + // Spherical coordinates: latitude, longitude, distance. + AstroSpherical = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Lat: Double; // The latitude angle: -90..+90 degrees. + Lon: Double; // The longitude angle: 0..360 degrees. + Dist: Double; // Distance in AU. + end; + + // An angular value expressed in degrees. + AstroAngleResult = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Angle: Double; // An angle expressed in degrees. + end; + + // The location of an observer on (or near) the surface of the Earth. + AstroObserver = packed record + Latitude: Double; // Geographic latitude in degrees north (positive) or south (negative) of the equator. + Longitude: Double; // Geographic longitude in degrees east (positive) or west (negative) of the prime meridian at Greenwich, England. + Height: Double; // The height above (positive) or below (negative) sea level, expressed in meters. + end; + + // Equatorial angular and cartesian coordinates. + AstroEquatorial = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + RA: Double; // right ascension in sidereal hours. + Dec: Double; // declination in degrees + Dist: Double; // distance to the celestial body in AU. + Vec: AstroVector; // equatorial coordinates in cartesian vector form: x = March equinox, y = June solstice, z = north. + end; + + // Ecliptic angular and Cartesian coordinates. + AstroEcliptic = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Vec: AstroVector; // Cartesian ecliptic vector: x=equinox, y=90 degrees prograde in ecliptic plane, z=northward perpendicular to ecliptic. + ELat: Double; // Latitude in degrees north (positive) or south (negative) of the ecliptic plane. + ELon: Double; // Longitude in degrees around the ecliptic plane prograde from the equinox. + end; + + // Coordinates of a celestial body as seen by a topocentric observer. + AstroHorizon = packed record + Azimuth: Double; // Compass direction around the horizon in degrees. 0=North, 90=East, 180=South, 270=West. + Altitude: Double; // Angle in degrees above (positive) or below (negative) the observer's horizon. + RA: Double; // Right ascension in sidereal hours. + Dec: Double; // Declination in degrees. + end; + + // Contains a rotation matrix that can be used to transform one coordinate system to another. + AstroRotation = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Rot: array[1..3, 1..3] of Double; // A normalized 3x3 rotation matrix. + end; + + // Information about idealized atmospheric variables at a given elevation. + AstroAtmosphere = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Pressure: Double; // Atmospheric pressure in pascals + Temperature: Double; // Atmospheric temperature in kelvins + Density: Double; // Atmospheric density relative to sea level + end; + + // The result of a search for an astronomical event. + AstroSearchResult = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Time: AstroTime; // The time at which a searched-for event occurs. + end; + +{ The dates and times of changes of season for a given calendar year. + Call #Astronomy_Seasons to calculate this data structure for a given year. } + AstroSeasons = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + MarEquinox: AstroTime; // The date and time of the March equinox for the specified year. + JunSolstice: AstroTime; // The date and time of the June soltice for the specified year. + SepEquinox: AstroTime; // The date and time of the September equinox for the specified year. + DecSolstice: AstroTime; // The date and time of the December solstice for the specified year. + end; + + // A lunar quarter event (new moon, first quarter, full moon, or third quarter) along with its date and time. + AstroMoonQuarter = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Quarter: Int32; // 0=new moon, 1=first quarter, 2=full moon, 3=third quarter. + Time: AstroTime; // The date and time of the lunar quarter. + end; + + // A real value returned by a function whose ascending root is to be found. + AstroFuncResult = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Value: Double; // The value returned by a function whose ascending root is to be found. + end; + + // Contains information about the visibility of a celestial body at a given date and time. + AstroElongation = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Time: AstroTime; // The date and time of the observation. + Visibility: AstroVisibility; // Whether the body is best seen in the morning or the evening. + Elongation: Double; // The angle in degrees between the body and the Sun, as seen from the Earth. + EclipticSeparation: Double; // The difference between the ecliptic longitudes of the body and the Sun, as seen from the Earth. + end; + + // Information about a celestial body crossing a specific hour angle. + AstroHourAngle = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Time: AstroTime; // The date and time when the body crosses the specified hour angle. + Hor: AstroHorizon; // Apparent coordinates of the body at the time it crosses the specified hour angle. + end; + + // Information about the brightness and illuminated shape of a celestial body. + AstroIllum = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Time: AstroTime; // The date and time of the observation. + Mag: Double; // The visual magnitude of the body. Smaller values are brighter. + PhaseAngle: Double; // The angle in degrees between the Sun and the Earth, as seen from the body. Indicates the body's phase as seen from the Earth. + PhaseFraction: Double; // A value in the range [0.0, 1.0] indicating what fraction of the body's apparent disc is illuminated, as seen from the Earth. + HelioDist: Double; // The distance between the Sun and the body at the observation time. + RingTilt: Double; // For Saturn, the tilt angle in degrees of its rings as seen from Earth. For all other bodies, 0. + end; + + // An apsis event: pericenter (closest approach) or apocenter (farthest distance). + AstroApsis = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Time: AstroTime; // The date and time of the apsis. + Kind: AstroApsisKind; // Whether this is a pericenter or apocenter event. + DistAU: Double; // The distance between the centers of the bodies in astronomical units. + DistKM: Double; // The distance between the centers of the bodies in kilometers. + end; + + // Information about a lunar eclipse. + AstroLunarEclipse = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Kind: AstroEclipseKind; // The type of lunar eclipse found. + Obscuration: Double; // The peak fraction of the Moon's apparent disc that is covered by the Earth's umbra. + Peak: AstroTime; // The time of the eclipse at its peak. + SDPenum: Double; // The semi-duration of the penumbral phase in minutes. + SDPartial: Double; // The semi-duration of the partial phase in minutes, or 0.0 if none. + SDTotal: Double; // The semi-duration of the total phase in minutes, or 0.0 if none. + end; + + // Reports the time and geographic location of the peak of a solar eclipse. + AstroGlobalSolarEclipse = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Kind: AstroEclipseKind; // The type of solar eclipse found. + Obscuration: Double; // The peak fraction of the Sun's apparent disc area obscured by the Moon (total and annular eclipses only). + Peak: AstroTime; // The date and time when the solar eclipse is darkest. This is the instant when the axis of the Moon's shadow cone passes closest to the Earth's center. + Distance: Double; // The distance between the Sun/Moon shadow axis and the center of the Earth, in kilometers. + Latitude: Double; // The geographic latitude at the center of the peak eclipse shadow. + Longitude: Double; // The geographic longitude at the center of the peak eclipse shadow. + end; + + // Holds a time and the observed altitude of the Sun at that time. + AstroEclipseEvent = packed record + Time: AstroTime; // The date and time of the event. + Altitude: Double; // The angular altitude of the center of the Sun above/below the horizon, at `time`, corrected for atmospheric refraction and expressed in degrees. + end; + + // Information about a solar eclipse as seen by an observer at a given time and geographic location. + AstroLocalSolarEclipse = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Kind: AstroEclipseKind; // The type of solar eclipse found: `ECLIPSE_PARTIAL`, `ECLIPSE_ANNULAR`, or `ECLIPSE_TOTAL`. + Obscuration: Double; // The fraction of the Sun's apparent disc area obscured by the Moon at the eclipse peak. + PartialBegin: AstroEclipseEvent; // The time and Sun altitude at the beginning of the eclipse. + TotalBegin: AstroEclipseEvent; // If this is an annular or a total eclipse, the time and Sun altitude when annular/total phase begins; otherwise invalid. + Peak: AstroEclipseEvent; // The time and Sun altitude when the eclipse reaches its peak. + TotalEnd: AstroEclipseEvent; // If this is an annular or a total eclipse, the time and Sun altitude when annular/total phase ends; otherwise invalid. + PartialEnd: AstroEclipseEvent; // The time and Sun altitude at the end of the eclipse. + end; + + // Information about a transit of Mercury or Venus, as seen from the Earth. + AstroTransit = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Start: AstroTime; // Date and time at the beginning of the transit. + Peak: AstroTime; // Date and time of the peak of the transit. + Finish: AstroTime; // Date and time at the end of the transit. + Separation: Double; // Angular separation in arcminutes between the centers of the Sun and the planet at time `peak`. + end; + + // Reports the constellation that a given celestial point lies within. + AstroConstellation = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Symbol: PChar; // 3-character mnemonic symbol for the constellation, e.g. "Ori". + Name: PChar; // Full name of constellation, e.g. "Orion". + RA1875: Double; // Right ascension expressed in B1875 coordinates. + Dec1875: Double; // Declination expressed in B1875 coordinates. + end; + + // Lunar libration angles, returned by #Astronomy_Libration. + AstroLibration = packed record + ELat: Double; // Sub-Earth libration ecliptic latitude angle, in degrees. + ELon: Double; // Sub-Earth libration ecliptic longitude angle, in degrees. + MLat: Double; // Moon's geocentric ecliptic latitude, in degrees. + MLon: Double; // Moon's geocentric ecliptic longitude, in degrees. + DistKM: Double; // Distance between the centers of the Earth and Moon in kilometers. + DiamDeg: Double; // The apparent angular diameter of the Moon, in degrees, as seen from the center of the Earth. + end; + + // Information about a body's rotation axis at a given time. + AstroAxis = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + RA: Double; // The J2000 right ascension of the body's north pole direction, in sidereal hours. + Dec: Double; // The J2000 declination of the body's north pole direction, in degrees. + Spin: Double; // Rotation angle of the body's prime meridian, in degrees. + North: AstroVector; // A J2000 dimensionless unit vector pointing in the direction of the body's north pole. + end; + + // Holds the positions and velocities of Jupiter's major 4 moons. + AstroJupiterMoons = packed record + IO: AstroStateVector; // Jovicentric position and velocity of Io. + Europa: AstroStateVector; // Jovicentric position and velocity of Europa. + Ganymede: AstroStateVector; // Jovicentric position and velocity of Ganymede. + Callisto: AstroStateVector; // Jovicentric position and velocity of Callisto. + end; + + // Information about an ascending or descending node of a body. + AstroNodeEvent = packed record + Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. + Time: AstroTime; // The time when the body passes through the ecliptic plane. + Kind: AstroNodeKind; // Either `ASCENDING_NODE` or `DESCENDING_NODE`, depending on the direction of the ecliptic plane crossing. + end; + + // A data type used for managing simulation of the gravitational forces on a small body. + AstroGravSim = packed record + end; + + // Pointer to `AstroGravSim` record. + PAstroGravSim = ^AstroGravSim; + + // A pointer to a function that is to be passed as a callback to #Astronomy_Search. + PAstroSearchFunc = function(Context: Pointer; Time: AstroTime): AstroFuncResult; cdecl; + + // A pointer to a function that calculates Delta T. + PAstroDeltaTFunc = function(UT: Double): Double; cdecl; + + // A pointer to a function for which to solve a light-travel time problem. + PAstroPositionFunc = function(Context: Pointer; Time: AstroTime): AstroVector; cdecl; + + // The default Delta T function used by Astronomy Engine. + function Astronomy_DeltaT_EspenakMeeus(UT: Double): Double; cdecl; external LibraryName; + + // A Delta T function that approximates the one used by the JPL Horizons tool + function Astronomy_DeltaT_JplHorizons(UT: Double): Double; cdecl; external LibraryName; + + // Changes the function Astronomy Engine uses to calculate Delta T. + procedure Astronomy_SetDeltaTFunction(Func: PAstroDeltaTFunc); cdecl; external LibraryName; + + // Frees up all dynamic memory allocated by Astronomy Engine. + procedure Astronomy_Reset(); cdecl; external LibraryName; + + // Calculates the length of the given vector. The returned length is expressed usually in AU. + function Astronomy_VectorLength(Vector: AstroVector): Double; cdecl; external LibraryName; + + // Calculates the angle between two vectors. The returned angle is expressed in degrees. + function Astronomy_AngleBetween(A: AstroVector; B: AstroVector): AstroAngleResult; cdecl; external LibraryName; + + // Finds the name of a celestial body. + function Astronomy_BodyName(Body: AstroBody): PChar; cdecl; external LibraryName; + +{ Returns the #AstroBody value corresponding to the given English name. + Valid parameter values are one of: Sun, Moon, Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto, EMB, SSB. } + function Astronomy_BodyCode(Name: PChar): AstroBody; cdecl; external LibraryName; + + // Creates an observer object that represents a location on or near the surface of the Earth. + function Astronomy_MakeObserver(Latitude: Double; Longitude: Double; Height: Double): AstroObserver; cdecl; external LibraryName; + + // Returns the computer's current date and time in the form of an #AstroTime. + function Astronomy_CurrentTime(): AstroTime; cdecl; external LibraryName; + + // Creates an #AstroTime value from a given calendar date and time. + function Astronomy_MakeTime(Year: Int32; Month: Int32; Day: Int32; Hour: Int32; Minute: Int32; Second: Double): AstroTime; cdecl; external LibraryName; + + // Creates an #AstroTime value from a given calendar date and time. + function Astronomy_TimeFromUtc(UTC: AstroUTC): AstroTime; cdecl; external LibraryName; + + // Determines the calendar year, month, day and time from an #AstroTime value. + function Astronomy_UtcFromTime(Time: AstroTime): AstroUTC; cdecl; external LibraryName; + + // Formats an #AstroTime value as an ISO 8601 string. + function Astronomy_FormatTime(Time: AstroTime; Format: AstroTimeFormat; Text: PChar; Size: Int64): AstroStatus; cdecl; external LibraryName; + + // Converts a J2000 day value to an #AstroTime value. + function Astronomy_TimeFromDays(UT: Double): AstroTime; cdecl; external LibraryName; + + // Converts a terrestrial time value into an #AstroTime value. + function Astronomy_TerrestrialTime(TT: Double): AstroTime; cdecl; external LibraryName; + + // Calculates the sum or difference of an #AstroTime with a specified floating point number of days. + function Astronomy_AddDays(Time: AstroTime; Days: Double): AstroTime; cdecl; external LibraryName; + + // Calculates Greenwich Apparent Sidereal Time (GAST) and returns in sidereal hours. + function Astronomy_SiderealTime(Time: PAstroTime): Double; cdecl; external LibraryName; + + // Calculates the distance from a body to the Sun at a given time. + function Astronomy_HelioDistance(Body: AstroBody; Time: AstroTime): AstroFuncResult; cdecl; external LibraryName; + + // Calculates heliocentric Cartesian coordinates of a body in the J2000 equatorial system. + function Astronomy_HelioVector(Body: AstroBody; Time: AstroTime): AstroVector; cdecl; external LibraryName; + + // Calculates geocentric Cartesian coordinates of a body in the J2000 equatorial system. + function Astronomy_GeoVector(Body: AstroBody; Time: AstroTime; Aberration: AstroAberration): AstroVector; cdecl; external LibraryName; + + // Calculates equatorial geocentric position of the Moon at a given time in the J2000 equatorial system. + function Astronomy_GeoMoon(Time: AstroTime): AstroVector; cdecl; external LibraryName; + + // Calculates spherical ecliptic geocentric postition of the Moon in the equatorial system of date. + function Astronomy_EclipticGeoMoon(Time: AstroTime): AstroSpherical; cdecl; external LibraryName; + + // Calculates equatorial geocentric postition of the Moon at a given time in the J2000 equatorial system. + function Astronomy_GeoMoonState(Time: AstroTime): AstroStateVector; cdecl; external LibraryName; + + // Calculates the geocentric position and velocity of the Earth/Moon barycenter in the J2000 equatorial system. + function Astronomy_GeoEmbState(Time: AstroTime): AstroStateVector; cdecl; external LibraryName; + + // Calculates the Moon's libration angles at a given moment in time. + function Astronomy_Libration(Time: AstroTime): AstroLibration; cdecl; external LibraryName; + + // Calculates barycentric position and velocity vectors for the given body (everything except stars). + function Astronomy_BaryState(Body: AstroBody; Time: AstroTime): AstroStateVector; cdecl; external LibraryName; + + // Calculates heliocentric position and velocity vectors for the given body (including stars). + function Astronomy_HelioState(Body: AstroBody; Time: AstroTime): AstroStateVector; cdecl; external LibraryName; + + // Returns the product of mass and universal gravitational constant of a Solar System body. + function Astronomy_MassProduct(Body: AstroBody): Double; cdecl; external LibraryName; + + // Returns the average number of days it takes for a planet to orbit the Sun. + function Astronomy_PlanetOrbitalPeriod(Body: AstroBody): Double; cdecl; external LibraryName; + + // Calculates one of the 5 Lagrange points for a pair of co-orbiting bodies. + function Astronomy_LagrangePoint(Point: Int32; Time: AstroTime; MajorBody: AstroBody; MinorBody: AstroBody): AstroStateVector; cdecl; external LibraryName; + + // Calculates one of the 5 Lagrange points from body masses and state vectors. + function Astronomy_LagrangePointFast(Point: Int32; MajorState: AstroStateVector; MajorMass: Double; MinorState: AstroStateVector; MinorMass: Double): AstroStateVector; cdecl; external LibraryName; + + // Calculates joviocentric positions and velocities of Jupiter's largest 4 moons. + function Astronomy_JupiterMoons(Time: AstroTime): AstroJupiterMoons; cdecl; external LibraryName; + + // Calculates equatorial coordinates of a celestial body as seen by an observer on the Earth's surface. + function Astronomy_Equator(Body: AstroBody; Time: PAstroTime; Observer: AstroObserver; EquDate: AstroEquatorDate; Aberration: AstroAberration): AstroEquatorial; cdecl; external LibraryName; + + // Calculates geocentric equatorial coordinates of an observer on the surface of the Earth. + function Astronomy_ObserverVector(Time: PAstroTime; Observer: AstroObserver; EquDate: AstroEquatorDate): AstroVector; cdecl; external LibraryName; + + // Calculates geocentric equatorial postition and velocity of an observer on the surface of the Earth. + function Astronomy_ObserverState(Time: PAstroTime; Observer: AstroObserver; EquDate: AstroEquatorDate): AstroStateVector; cdecl; external LibraryName; + + // Calculates the geographic location corresponding to an equatorial vector. + function Astronomy_VectorObserver(Vector: PAstroVector; EquDate: AstroEquatorDate): AstroObserver; cdecl; external LibraryName; + + // Calculates the gravitational acceleration experienced by an observer on the Earth and returns acceleration expressed in meters per second squared. + function Astronomy_ObserverGravity(Latitude: Double; Height: Double): Double; cdecl; external LibraryName; + + // Calculates geocentric ecliptic coordinates for the Sun. + function Astronomy_SunPosition(Time: AstroTime): AstroEcliptic; cdecl; external LibraryName; + + // Converts a J2000 mean equator (EQJ) vector to a true ecliptic of date (ETC) vector and angles. + function Astronomy_Ecliptic(EQJ: AstroVector): AstroEcliptic; cdecl; external LibraryName; + + // Calculates heliocentric ecliptic longitude of a body. + function Astronomy_EclipticLongitude(Body: AstroBody; Time: AstroTime): AstroAngleResult; cdecl; external LibraryName; + + // Calculates the apparent location of a body relative to the local horizon of an observer on the Earth. + function Astronomy_Horizon(Time: PAstroTime; Observer: AstroObserver; RA: Double; Dec: Double; Refraction: AstroRefraction): AstroHorizon; cdecl; external LibraryName; + + // Returns the angle between the given body and the Sun, as seen from the Earth. + function Astronomy_AngleFromSun(Body: AstroBody; Time: AstroTime): AstroAngleResult; cdecl; external LibraryName; + + // Determins visibility of a celestial body realtive to the Sun, as seen from the Earth. + function Astronomy_Elongation(Body: AstroBody; Time: AstroTime): AstroElongation; cdecl; external LibraryName; + + // Finds a date and time when Mercury or Venus reaches its maximum angle from the Sun as seen from the Earth. + function Astronomy_SearchMaxElongation(Body: AstroBody; StartTime: AstroTime): AstroElongation; cdecl; external LibraryName; + + // Returns one body's ecliptic longitude with respect to another, as seen from Earth. + function Astronomy_PairLongitude(Body1: AstroBody; Body2: AstroBody; Time: AstroTime): AstroAngleResult; cdecl; external LibraryName; + + // Searches for the time when the Earth and another planet are separated by a specified angle in eclipctic longitude, as seen from the Sun. + function Astronomy_SearchRelativeLongitude(Body: AstroBody; TargetRelLon: Double; StartTime: AstroTime): AstroSearchResult; cdecl; external LibraryName; + + // Returns the Moon's phase as an angle from 0 to 360 degrees. + function Astronomy_MoonPhase(Time: AstroTime): AstroAngleResult; cdecl; external LibraryName; + + // Searches for the time that the Moon reaches a specified phase. + function Astronomy_SearchMoonPhase(TargetLon: Double; StartTime: AstroTime; LimitDays: Double): AstroSearchResult; cdecl; external LibraryName; + + // Finds the first lunar quarter after the specified date and time. + function Astronomy_SearchMoonQuarter(StartTime: AstroTime): AstroMoonQuarter; cdecl; external LibraryName; + + // Continues searching for lunar quarters from previous search. + function Astronomy_NextMoonQuarter(MQ: AstroMoonQuarter): AstroMoonQuarter; cdecl; external LibraryName; + + // Searches for a lunar eclipse. + function Astronomy_SearchLunarEclipse(StartTime: AstroTime): AstroLunarEclipse; cdecl; external LibraryName; + + // Searches for the next lunar eclipse in a series. + function Astronomy_NextLunarEclipse(PrevEclipseTime: AstroTime): AstroLunarEclipse; cdecl; external LibraryName; + + // Searches for a solar eclipse visible anywhere on the Earth's surface. + function Astronomy_SearchGlobalSolarEclipse(StartTime: AstroTime): AstroGlobalSolarEclipse; cdecl; external LibraryName; + + // Searches for the next global solar eclipse in a series. + function Astronomy_NextGlobalSolarEclipse(PrevEclipseTime: AstroTime): AstroGlobalSolarEclipse; cdecl; external LibraryName; + + // Searches for a solar eclipse visible at specific location on the Earth's surface. + function Astronomy_SearchLocalSolarEclipse(StartTime: AstroTime; Observer: AstroObserver): AstroLocalSolarEclipse; cdecl; external LibraryName; + + // Searches for the next local solar eclipse in a series. + function Astronomy_NextLocalSolarEclipse(PrevEclipseTime: AstroTime; Observer: AstroObserver): AstroLocalSolarEclipse; cdecl; external LibraryName; + + // Searches for the first transit of Mercury or Venus after a given date. + function Astronomy_SearchTransit(Body: AstroBody; StartTime: AstroTime): AstroTransit; cdecl; external LibraryName; + + // Searches for another transit of Mercury or Venus. + function Astronomy_NextTransit(Body: AstroBody; PrevTransitTime: AstroTime): AstroTransit; cdecl; external LibraryName; + + // Searches for a time when the Moon's center crosses through the ecliptic plane. + function Astronomy_SearchMoonNode(StartTime: AstroTime): AstroNodeEvent; cdecl; external LibraryName; + + // Searches for the next time when the Moon's center crosses through the ecliptic plane. + function Astronomy_NextMoonNode(PrevNode: AstroNodeEvent): AstroNodeEvent; cdecl; external LibraryName; + + // Searches for a time at which a function's value increases through zero. + function Astronomy_Search(Func: PAstroSearchFunc; Context: Pointer; T1: AstroTime; T2: AstroTime; DTToleranceSeconds: Double): AstroSearchResult; cdecl; external LibraryName; + + // Searches for the time when the Sun reaches an apparent ecliptic longitude as seen from the Earth. + function Astronomy_SearchSunLongitude(TargetLon: Double; StartTime: AstroTime; LimitDays: Double): AstroSearchResult; cdecl; external LibraryName; + + // Searches for the time when the center of a body reaches a specified hour angle as seen by an observer on the Earth. + function Astronomy_SearchHourAngleEx(Body: AstroBody; Observer: AstroObserver; HourAngle: Double; StartTime: AstroTime; Direction: Int32): AstroHourAngle; cdecl; external LibraryName; + + // Finds the hour angle of a body for a given observer and time. + function Astronomy_HourAngle(Body: AstroBody; Time: PAstroTime; Observer: AstroObserver): AstroFuncResult; cdecl; external LibraryName; + + // Searches for the next time a celestial body rises or sets as seen by an observer on the Earth. + function Astronomy_SearchRiseSetEx(Body: AstroBody; Observer: AstroObserver; Direction: AstroDirection; StartTime: AstroTime; LimitDays: Double; MetersAboveGround: Double): AstroSearchResult; cdecl; external LibraryName; + + // Finds the next time the center of a body passes through a given altitude. + function Astronomy_SearchAltitude(Body: AstroBody; Observer: AstroObserver; Direction: AstroDirection; StartTime: AstroTime; LimitDays: Double; Altitude: Double): AstroSearchResult; cdecl; external LibraryName; + + // Calculates U.S. Standard Atmosphere (1976) variables as a function of elevation. + function Astronomy_Atmosphere(ElevationMeters: Double): AstroAtmosphere; cdecl; external LibraryName; + + // Calculates information about a body's rotation axis at a given time. + function Astronomy_RotationAxis(Body: AstroBody; Time: PAstroTime): AstroAxis; cdecl; external LibraryName; + + // Finds both equinoxes and both solstices for a given calendar year. + function Astronomy_Seasons(Year: Int32): AstroSeasons; cdecl; external LibraryName; + + // Finds visual magnitude, phase angle, and other illumination information about a celestial body. + function Astronomy_Illumination(Body: AstroBody; Time: AstroTime): AstroIllum; cdecl; external LibraryName; + + // Searches for the date and time Venus will next appear brightest as seen from the Earth. + function Astronomy_SearchPeakMagnitude(Body: AstroBody; StartTime: AstroTime): AstroIllum; cdecl; external LibraryName; + + // Finds the date and time of the Moon's closest distance (perigee) or farthest distance (apogee) with the respect to the Earth. + function Astronomy_SearchLunarApsis(StartTime: AstroTime): AstroApsis; cdecl; external LibraryName; + + // Finds the next lunar perigee or apogee event in a series. + function Astronomy_NextLunarApsis(Apsis: AstroApsis): AstroApsis; cdecl; external LibraryName; + + // Finds the date and time of a planet's perihelion (closest approach to the Sun) or aphelion (farthest distance from the Sun) after a given time. + function Astronomy_SearchPlanetApsis(Body: AstroBody; StartTime: AstroTime): AstroApsis; cdecl; external LibraryName; + + // Finds the next planetary perihelion or aphelion event in a series. + function Astronomy_NextPlanetApsis(Body: AstroBody; Apsis: AstroApsis): AstroApsis; cdecl; external LibraryName; + + // Creates an identity rotation matrix. + function Astronomy_IdentityMatrix(): AstroRotation; cdecl; external LibraryName; + + // Calculatues the inverse of a rotation matrix. + function Astronomy_InverseRotation(Rotation: AstroRotation): AstroRotation; cdecl; external LibraryName; + + // Creates a rotation based on applying one rotation followed by another. + function Astronomy_CombineRotation(A: AstroRotation; B: AstroRotation): AstroRotation; cdecl; external LibraryName; + + // Re-orients a rotation matrix by pivoting it by an angle around one of its axes. + function Astronomy_Pivot(Rotation: AstroRotation; Axis: Int32; Angle: Double): AstroRotation; cdecl; external LibraryName; + + // Converts spherical coordinates to Cartesian coordinates. + function Astronomy_VectorFromSphere(Sphere: AstroSpherical; Time: AstroTime): AstroVector; cdecl; external LibraryName; + + // Converts Cartesian coordinates to spherical coordinates. + function Astronomy_SphereFromVector(Vector: AstroVector): AstroSpherical; cdecl; external LibraryName; + + // Given an equatorial vector, calculates equatorial angular coordinates. + function Astronomy_EquatorFromVector(Vector: AstroVector): AstroEquatorial; cdecl; external LibraryName; + + // Given apparent angular horizontal coordinates in `sphere`, calculates horizontal vector. + function Astronomy_VectorFromHorizon(Sphere: AstroSpherical; Time: AstroTime; Refraction: AstroRefraction): AstroVector; cdecl; external LibraryName; + + // Converts Cartesian coordinates to horizontal coordinates. + function Astronomy_HorizonFromVector(Vector: AstroVector; Refraction: AstroRefraction): AstroSpherical; cdecl; external LibraryName; + + // Applies a rotation to a vector, yielding a rotated vector. + function Astronomy_RotateVector(Rotation: AstroRotation; Vector: AstroVector): AstroVector; cdecl; external LibraryName; + + // Applies a rotation to a state vector, yielding a rotated vector. + function Astronomy_RotateState(Rotation: AstroRotation; State: AstroStateVector): AstroStateVector; cdecl; external LibraryName; + + // Calculates a rotation matrix from equatorial of-date (EQD) to J2000 mean equator (EQJ). + function Astronomy_Rotation_EQD_EQJ(Time: PAstroTime): AstroRotation; cdecl; external LibraryName; + + // Calculates a rotation matrix from equatorial of-date (EQD) to J2000 mean ecliptic (ECL). + function Astronomy_Rotation_EQD_ECL(Time: PAstroTime): AstroRotation; cdecl; external LibraryName; + + // Returns a rotation matrix from equator of date (EQD) to true ecliptic of date (ECT). + function Astronomy_Rotation_EQD_ECT(Time: PAstroTime): AstroRotation; cdecl; external LibraryName; + + // Calculates a rotation matrix from equatorial of-date (EQD) to horizontal (HOR). + function Astronomy_Rotation_EQD_HOR(Time: PAstroTime; Observer: AstroObserver): AstroRotation; cdecl; external LibraryName; + + // Calculates a rotation matrix from J2000 mean equator (EQJ) to equatorial of-date (EQD). + function Astronomy_Rotation_EQJ_EQD(Time: PAstroTime): AstroRotation; cdecl; external LibraryName; + + // Calculates a rotation matrix from J2000 mean equator (EQJ) to true ecliptic of date (ECT). + function Astronomy_Rotation_EQJ_ECT(Time: PAstroTime): AstroRotation; cdecl; external LibraryName; + + // Calculates a rotation matrix from J2000 mean equator (EQJ) to J2000 mean ecliptic (ECL). + function Astronomy_Rotation_EQJ_ECL(): AstroRotation; cdecl; external LibraryName; + + // Calculates a rotation matrix from J2000 mean equator (EQJ) to horizontal (HOR). + function Astronomy_Rotation_EQJ_HOR(Time: PAstroTime; Observer: AstroObserver): AstroRotation; cdecl; external LibraryName; + + // Calculates a rotation matrix from J2000 mean ecliptic (ECL) to equatorial of-date (EQD). + function Astronomy_Rotation_ECL_EQD(Time: PAstroTime): AstroRotation; cdecl; external LibraryName; + + // Calculates a rotation matrix from J2000 mean ecliptic (ECL) to J2000 mean equator (EQJ). + function Astronomy_Rotation_ECL_EQJ(): AstroRotation; cdecl; external LibraryName; + + // Calculates a rotation matrix from J2000 mean ecliptic (ECL) to horizontal (HOR). + function Astronomy_Rotation_ECL_HOR(Time: PAstroTime; Observer: AstroObserver): AstroRotation; cdecl; external LibraryName; + + // Calculates a rotation matrix from true ecliptic of date (ECT) to J2000 mean equator (EQJ). + function Astronomy_Rotation_ECT_EQJ(Time: PAstroTime): AstroRotation; cdecl; external LibraryName; + + // Calulcates a rotation matrix from true ecliptic of date (ECT) to equator of date (EQD). + function Astronomy_Rotation_ECT_EQD(Time: PAstroTime): AstroRotation; cdecl; external LibraryName; + + // Calulcates a rotation matrix from horizontal (HOR) to equatorial of-date (EQD). + function Astronomy_Rotation_HOR_EQD(Time: PAstroTime; Observer: AstroObserver): AstroRotation; cdecl; external LibraryName; + + // Calulcates a rotation matrix from horizontal (HOR) to J2000 equatorial (EQJ). + function Astronomy_Rotation_HOR_EQJ(Time: PAstroTime; Observer: AstroObserver): AstroRotation; cdecl; external LibraryName; + + // Calulcates a rotation matrix from horizontal (HOR) to J2000 mean ecliptic (ECL). + function Astronomy_Rotation_HOR_ECL(Time: PAstroTime; Observer: AstroObserver): AstroRotation; cdecl; external LibraryName; + + // Calulcates a rotation matrix from J2000 mean ecliptic (EQJ) to galactic (GAL). + function Astronomy_Rotation_EQJ_GAL(): AstroRotation; cdecl; external LibraryName; + + // Calulcates a rotation matrix from galactic (GAL) to J2000 mean ecliptic (EQJ). + function Astronomy_Rotation_GAL_EQJ(): AstroRotation; cdecl; external LibraryName; + + // Calculates the amount of "lift" to an altitude angle caused by atmospheric refraction. + function Astronomy_Refraction(Refraction: AstroRefraction; Altitude: Double): Double; cdecl; external LibraryName; + + // Calculates the inverse of an atmospheric refraction angle. + function Astronomy_InverseRefraction(Refraction: AstroRefraction; BentAltitude: Double): Double; cdecl; external LibraryName; + + // Determines the constellation that contains the given point in the sky. + function Astronomy_Constellation(RA: Double; Dec: Double): AstroConstellation; cdecl; external LibraryName; + +{ Allocate and initialize a gravity step simulator. + Prepares to simulate a series of incremental time steps, + simulating the movement of zero or more small bodies through the Solar System + acting under gravitational attraction from the Sun and planets. } + function Astronomy_GravSimInit(SimOut: PAstroGravSim; OriginBody: AstroBody; Time: AstroTime; NumBodies: Int32; BodyStateArray: PAstroStateVector): AstroStatus; cdecl; external LibraryName; + + // Advances a gravity simulation by a small time step. + function Astronomy_GravSimUpdate(Sim: PAstroGravSim; Time: AstroTime; NumBodies: Int32; BodyStateArray: PAstroStateVector): AstroStatus; cdecl; external LibraryName; + + // Get the position and velocity of a Solar System body included in the simulation. + function Astronomy_GravSimBodyState(Sim: PAstroGravSim; Body: AstroBody): AstroStateVector; cdecl; external LibraryName; + + // Returns the time of the current simulation step. + function Astronomy_GravSimTime(Sim: PAstroGravSim): AstroTime; cdecl; external LibraryName; + + // Returns the number of small bodies represented in this simulation. + function Astronomy_GravSimNumBodies(Sim: PAstroGravSim): Int32; cdecl; external LibraryName; + + // Returns the body whose center is the coordinate origin that small bodies are referenced to. + function Astronomy_GravSimOrigin(Sim: PAstroGravSim): AstroBody; cdecl; external LibraryName; + + // Exchange the current time step with the previous time step. + procedure Astronomy_GravSimSwap(Sim: PAstroGravSim); cdecl; external LibraryName; + + // Releases memory allocated to a gravity simulator object. + procedure Astronomy_GravSimFree(Sim: PAstroGravSim); cdecl; external LibraryName; + + // Solve for light travel time of a vector function. + function Astronomy_CorrectLightTravel(Context: Pointer; Func: PAstroPositionFunc; Time: AstroTime): AstroVector; cdecl; external LibraryName; + + // Solve for light travel time correction of apparent position. + function Astronomy_BackdatePosition(Time: AstroTime; ObserverBody: AstroBody; TargetBody: AstroBody; Aberration: AstroAberration): AstroVector; cdecl; external LibraryName; + + // Assign equatorial coordinates to a user-defined star. + function Astronomy_DefineStar(Body: AstroBody; RA: Double; Dec: Double; DistanceLightYears: Double): AstroStatus; cdecl; external LibraryName; + +implementation + +end. + diff --git a/source/pascal/README.md b/source/pascal/README.md new file mode 100644 index 00000000..67547c6e --- /dev/null +++ b/source/pascal/README.md @@ -0,0 +1,15 @@ +# Astronomy Engine for FreePascal language +This is the programming reference for the [FreePascal](https://www.freepascal.org/) version of Astronomy Engine. It can be used directly from FreePascal (and probably also Delphi) programs. Other programming languages are supported. See the [home page](https://github.com/cosinekitty/astronomy) for more info. + +--- + +## Quick Start +To include Astronomy Engine in your own FreePascal program, all you need is the +file `Astronomy.pas` from this directory. + +To get started quickly, here are some [examples](../../demo/pascal/). + +## Pascal developer note +The `Astronomy.pas` Pascal unit (module) is a [wrapper library](https://en.wikipedia.org/wiki/Wrapper_library) that bridges the C and Pascal programming languages so that the Astronomy Engine C/C++ library can be used in the Pascal language. The C library binary (`Astronomy.dll` on Windows) is also required to use this Pascal module. This means one needs to put the binary file in the same directory where the Pascal program executable is located. + +To build Astronomy Engine C/C++ library (for Windows) check the [documentation](../c/README.Windows.md).