Skip to content

Commit 2e349a4

Browse files
authored
"Update astro constants with up-to-date standards" (#2371)
Split from #1952, as suggested by Askaniy themself, allowing this component of that PR to be updated even if the PSF itself remains work in progress.
1 parent 59214b8 commit 2e349a4

File tree

2 files changed

+126
-30
lines changed

2 files changed

+126
-30
lines changed

src/celastro/astro.cpp

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// astro.cpp
22
//
3-
// Copyright (C) 2001-2009, the Celestia Development Team
3+
// Copyright (C) 2001-present, the Celestia Development Team
44
// Original version by Chris Laurel <[email protected]>
55
//
66
// This program is free software; you can redistribute it and/or
@@ -54,20 +54,51 @@ negateIf(double& d, bool condition)
5454

5555
} // end unnamed namespace
5656

57+
58+
// Computes the luminosity of a perfectly reflective disc.
59+
// It is also used as an upper bound for the irradiance of an object when culling invisible objects.
60+
// The function translates luminosity into luminosity of the same units
61+
// (distanceFromSun and objRadius must also be in the same units).
62+
float reflectedLuminosity(float sunLuminosity,
63+
float distanceFromSun,
64+
float objRadius)
65+
{
66+
float lengthRatio = objRadius / distanceFromSun;
67+
return sunLuminosity * 0.25 * lengthRatio * lengthRatio;
68+
}
69+
70+
71+
// The following notation rules apply in the functions below and in the code in general:
72+
// - Luminosity is implied in solar units (in SI, flux is measured in W)
73+
// - Irradiance is implied in vegan units (in SI, it is measured in W/m^2)
74+
75+
// Absolute magnitude is the logarithmic inverse of luminosity.
76+
// Apparent magnitude is the logarithmic inverse of irradiance.
77+
78+
79+
// Luminosity conversions:
80+
5781
float
5882
lumToAbsMag(float lum)
5983
{
6084
return SOLAR_ABSMAG - std::log(lum) * LN_MAG;
6185
}
6286

63-
// Return the apparent magnitude of a star with lum times solar
64-
// luminosity viewed at lyrs light years
6587
float
6688
lumToAppMag(float lum, float lyrs)
6789
{
6890
return absToAppMag(lumToAbsMag(lum), lyrs);
6991
}
7092

93+
float
94+
lumToIrradiance(float lum, float km)
95+
{
96+
return lum * SOLAR_POWER / (math::sphereArea(km * 1000) * VEGAN_IRRADIANCE);
97+
}
98+
99+
100+
// Magnitude conversions:
101+
71102
float
72103
absMagToLum(float mag)
73104
{
@@ -80,6 +111,51 @@ appMagToLum(float mag, float lyrs)
80111
return absMagToLum(appToAbsMag(mag, lyrs));
81112
}
82113

114+
float
115+
absMagToIrradiance(float mag, float km)
116+
{
117+
return lumToIrradiance(absMagToLum(mag), km);
118+
}
119+
120+
121+
// Logarithmic magnitude system <-> linear irradiance system in Vega units:
122+
123+
float
124+
magToIrradiance(float mag)
125+
{
126+
return std::exp(- mag / LN_MAG);
127+
// slower solution:
128+
// return std::pow(10.0f, -0.4f * mag);
129+
}
130+
131+
float
132+
irradianceToMag(float irradiance)
133+
{
134+
return - std::log(irradiance) * LN_MAG;
135+
// equivalent solution:
136+
// return -2.5f * std::log10(irradiance);
137+
}
138+
139+
140+
// Faintest star magnitude system <-> exposure time:
141+
142+
float
143+
faintestMagToExposure(float faintestMag)
144+
{
145+
return std::exp(faintestMag / LN_MAG) * LOWEST_IRRADIATION;
146+
// slower solution:
147+
// return std::pow(10.0f, 0.4f * faintestMag) * LOWEST_IRRADIATION;
148+
}
149+
150+
float
151+
exposureToFaintestMag(float exposure)
152+
{
153+
return std::log(exposure / LOWEST_IRRADIATION) * LN_MAG;
154+
// equivalent solution:
155+
// return 2.5f * std::log10(exposure / LOWEST_IRRADIATION);
156+
}
157+
158+
83159
void
84160
decimalToDegMinSec(double angle, int& degrees, int& minutes, double& seconds)
85161
{
@@ -108,8 +184,7 @@ decimalToHourMinSec(double angle, int& hours, int& minutes, double& seconds)
108184
seconds = (B - (double) minutes) * 60.0;
109185
}
110186

111-
// Convert equatorial coordinates to Cartesian celestial (or ecliptical)
112-
// coordinates.
187+
// Convert equatorial coordinates to Cartesian celestial (or ecliptical) coordinates.
113188
Eigen::Vector3f
114189
equatorialToCelestialCart(float ra, float dec, float distance)
115190
{
@@ -129,8 +204,7 @@ equatorialToCelestialCart(float ra, float dec, float distance)
129204
return EQUATORIAL_TO_ECLIPTIC_MATRIX_F * Eigen::Vector3f(x, y, z);
130205
}
131206

132-
// Convert equatorial coordinates to Cartesian celestial (or ecliptical)
133-
// coordinates.
207+
// Convert equatorial coordinates to Cartesian celestial (or ecliptical) coordinates.
134208
Eigen::Vector3d
135209
equatorialToCelestialCart(double ra, double dec, double distance)
136210
{

src/celastro/astro.h

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// astro.h
22
//
3-
// Copyright (C) 2001-2009, the Celestia Development Team
3+
// Copyright (C) 2001-present, the Celestia Development Team
44
// Original version by Chris Laurel <[email protected]>
55
//
66
// This program is free software; you can redistribute it and/or
@@ -25,8 +25,36 @@
2525
namespace celestia::astro
2626
{
2727

28-
constexpr inline float SOLAR_ABSMAG = 4.83f;
29-
constexpr inline float LN_MAG = 1.0857362f; // 5/ln(100)
28+
// Angle between J2000 mean equator and the ecliptic plane: 23 deg 26' 21".448
29+
// Seidelmann, Explanatory Supplement to the Astronomical Almanac (1992), eqn 3.222-1
30+
constexpr inline double J2000Obliquity = 23.4392911_deg;
31+
32+
// CODATA 2022
33+
constexpr inline double speedOfLight = 299792.458; // km/s
34+
constexpr inline double G = 6.67430e-11; // N m^2 / kg^2
35+
36+
// IAU 2015 Resolution B3 + CODATA 2022
37+
constexpr inline double SolarMass = 1.3271244e20 / G; // kg
38+
constexpr inline double EarthMass = 3.986004e14 / G; // kg
39+
constexpr inline double LunarMass = 7.346e22; // kg
40+
constexpr inline double JupiterMass = 1.2668653e17 / G; // kg
41+
42+
// https://mips.as.arizona.edu/~cnaw/sun.html for Johnson V filter
43+
constexpr inline float SOLAR_ABSMAG = 4.81f;
44+
45+
// IAU 2015 Resolution B3
46+
constexpr inline float SOLAR_IRRADIANCE = 1361.0f; // W / m^2
47+
constexpr inline float SOLAR_POWER = 3.828e26f; // W
48+
49+
// Bessel (1979) for Johnson V filter
50+
constexpr inline float VEGAN_IRRADIANCE = 3.640e-11f; // W / m^2
51+
52+
// Auxiliary magnitude conversion factor
53+
constexpr inline float LN_MAG = 1.0857362f; // 5/ln(100)
54+
55+
// Lowest screen brightness of a point to render
56+
constexpr inline float LOWEST_IRRADIATION = 1.0f / 255.0f;
57+
// = 1.0f / (255.0f * 12.92f); after implementing gamma correction
3058

3159
namespace detail
3260
{
@@ -60,19 +88,27 @@ constexpr inline double SECONDS_PER_DEG = 3600.0;
6088
constexpr inline double DEG_PER_HRA = 15.0;
6189

6290
template<typename T>
63-
constexpr inline auto EARTH_RADIUS = detail::enable_if_fp<T>(6378.14L);
91+
constexpr inline auto EARTH_RADIUS = detail::enable_if_fp<T>(6378.1L); // IAU 2015 Resolution B3
6492

6593
template<typename T>
66-
constexpr inline auto JUPITER_RADIUS = detail::enable_if_fp<T>(71492.0L);
94+
constexpr inline auto JUPITER_RADIUS = detail::enable_if_fp<T>(71492.0L); // IAU 2015 Resolution B3
6795

6896
template<typename T>
69-
constexpr inline auto SOLAR_RADIUS = detail::enable_if_fp<T>(696000.0L);
97+
constexpr inline auto SOLAR_RADIUS = detail::enable_if_fp<T>(695700.0L); // IAU 2015 Resolution B3
98+
99+
float reflectedLuminosity(float sunLuminosity, float distanceFromSun, float objRadius);
70100

71101
// Magnitude conversions
72102
float lumToAbsMag(float lum);
73103
float lumToAppMag(float lum, float lyrs);
104+
float lumToIrradiance(float lum, float km);
74105
float absMagToLum(float mag);
75106
float appMagToLum(float mag, float lyrs);
107+
float absMagToIrradiance(float mag, float lyrs);
108+
float magToIrradiance(float mag);
109+
float irradianceToMag(float irradiance);
110+
float faintestMagToExposure(float faintestMag);
111+
float exposureToFaintestMag(float exposure);
76112

77113
template<class T>
78114
CELESTIA_CMATH_CONSTEXPR T
@@ -175,33 +211,19 @@ void anomaly(double meanAnomaly, double eccentricity,
175211
double& trueAnomaly, double& eccentricAnomaly);
176212
double meanEclipticObliquity(double jd);
177213

178-
constexpr inline double speedOfLight = 299792.458; // km/s
179-
constexpr inline double G = 6.672e-11; // N m^2 / kg^2; gravitational constant
180-
constexpr inline double SolarMass = 1.989e30;
181-
constexpr inline double EarthMass = 5.972e24;
182-
constexpr inline double LunarMass = 7.346e22;
183-
constexpr inline double JupiterMass = 1.898e27;
184-
185-
// Angle between J2000 mean equator and the ecliptic plane.
186-
// 23 deg 26' 21".448 (Seidelmann, _Explanatory Supplement to the
187-
// Astronomical Almanac_ (1992), eqn 3.222-1.
188-
constexpr inline double J2000Obliquity = 23.4392911_deg;
189-
190-
constexpr inline double SOLAR_IRRADIANCE = 1367.6; // Watts / m^2
191-
constexpr inline double SOLAR_POWER = 3.8462e26; // in Watts
192214

193215
namespace literals
194216
{
195217

196-
constexpr long double operator ""_au(long double au)
218+
constexpr long double operator "" _au (long double au)
197219
{
198220
return AUtoKilometers(au);
199221
}
200-
constexpr long double operator ""_ly(long double ly)
222+
constexpr long double operator "" _ly (long double ly)
201223
{
202224
return lightYearsToKilometers(ly);
203225
}
204-
constexpr long double operator ""_c(long double n)
226+
constexpr long double operator "" _c (long double n)
205227
{
206228
return speedOfLight * n;
207229
}

0 commit comments

Comments
 (0)