@@ -124,135 +124,128 @@ double calcSunRadVector(double T)
124124 return 1.000001018 * (1 - e * e) / (1 + e * cos (v)); // in AUs
125125}
126126
127- double calcSunApparentLong (double T)
128- {
129- double O = calcSunTrueLong (T);
130- double omega = radians (125.04 - 1934.136 * T);
131- return O - 0.00569 - 0.00478 * sin (omega); // in degrees
132- }
133-
134- double calcMeanObliquityOfEcliptic (double T)
135- {
136- return 23 + (26 + (21.448 - T * (46.815 + T * (0.00059 - 0.001813 * T))) / 60 ) / 60 ; // in degrees
137- }
138-
139- // See Astronomical Algorithms 2nd edition errata
127+ /*
128+ // These expressions require double-precision arithmetic
129+ //
140130double calcNutationLongitude(double T)
141131{
142132 double omega = radians(125.04452 - 1934.136261 * T);
143133 double L1 = radians(280.4665 + 36000.7698 * T);
144134 double L2 = radians(218.3165 + 481267.8813 * T);
145- return -17.2 * sin (omega) - 1.32 * sin (2 * L1 ) - 0.23 * sin (2 * L2 ) + 0.21 * sin (2 * omega); // in arcseconds
135+ return ( -17.2 * sin(omega) - 1.32 * sin(2 * L1) - 0.23 * sin(2 * L2) + 0.21 * sin(2 * omega)) / 3600 ; // in degrees
146136}
147137
148138double calcNutationObliquity(double T)
149139{
150140 double omega = radians(125.04452 - 1934.136261 * T);
151141 double L1 = radians(280.4665 + 36000.7698 * T);
152142 double L2 = radians(218.3165 + 481267.8813 * T);
153- return 9.20 * cos (omega) + 0.57 * cos (2 * L1 ) + 0.10 * cos (2 * L2 ) - 0.09 * cos (omega); // in arcseconds
143+ return ( 9.20 * cos(omega) + 0.57 * cos(2 * L1) + 0.10 * cos(2 * L2) - 0.09 * cos(2 * omega)) / 3600 ; // in degrees
154144}
145+ */
155146
156- double calcObliquityCorrectionV1 (double T)
147+ double calcNutationLongitude (double T)
148+ {
149+ double omega = radians (125.04 - 1934.136 * T);
150+ return -0.00478 * sin (omega); // in degrees
151+ }
152+
153+ double calcNutationObliquity (double T)
157154{
158- double epsilon0 = calcMeanObliquityOfEcliptic (T);
159155 double omega = radians (125.04 - 1934.136 * T);
160- return epsilon0 + 0.00256 * cos (omega); // in degrees
156+ return 0.00256 * cos (omega); // in degrees
161157}
162158
163- double calcObliquityCorrectionV2 (double T)
159+ double calcSunApparentLong (double T)
160+ {
161+ return calcSunTrueLong (T) - 0.00569 + calcNutationLongitude (T); // in degrees
162+ }
163+
164+ double calcMeanObliquityOfEcliptic (double T)
165+ {
166+ return 23 + (26 + (21.448 - T * (46.815 + T * (0.00059 - 0.001813 * T))) / 60 ) / 60 ; // in degrees
167+ }
168+
169+ double calcObliquityCorrection (double T)
164170{
165171 double epsilon0 = calcMeanObliquityOfEcliptic (T);
166172 double delta_epsilon = calcNutationObliquity (T);
167- return epsilon0 + delta_epsilon / 3600 ; // in degrees
173+ return epsilon0 + delta_epsilon; // in degrees
168174}
169175
170176double calcSunRtAscension (double T)
171177{
172- double epsilon = radians (calcObliquityCorrectionV1 (T));
178+ double epsilon = radians (calcObliquityCorrection (T));
173179 double lambda = radians (calcSunApparentLong (T));
174180 return degrees (atan2 (cos (epsilon) * sin (lambda), cos (lambda))); // in degrees
175181}
176182
177183double calcSunDeclination (double T)
178184{
179- double epsilon = radians (calcObliquityCorrectionV1 (T));
180- double lambda1 = radians (calcSunApparentLong (T));
181- return degrees (asin (sin (epsilon) * sin (lambda1 ))); // in degrees
185+ double epsilon = radians (calcObliquityCorrection (T));
186+ double lambda = radians (calcSunApparentLong (T));
187+ return degrees (asin (sin (epsilon) * sin (lambda ))); // in degrees
182188}
183189
184- // We neglect the very small variation of delta_psi during time ΔT
185190double calcNutationRtAscension (double T)
186191{
187192 double delta_psi = calcNutationLongitude (T);
188- double epsilon = radians (calcObliquityCorrectionV2 (T));
189- return delta_psi * cos (epsilon) / 3600 ; // in degrees
193+ double epsilon = radians (calcObliquityCorrection (T));
194+ return delta_psi * cos (epsilon); // in degrees
190195}
191196
192197// Valid only at 0h UT, Greenwich (JD ending in .5)
193- double calcMeanSiderealTime (double JD )
198+ double calcGrMeanSiderealTime (double JD )
194199{
195200 double T = calcJulianCent (JD );
196201 return wrapTo360 (100.46061837 + T * (36000.770053608 + T * (0.000387933 - T / 38710000 ))); // in degrees
197202}
198203
199- double calcApparentSiderealTime (double JD )
204+ // We neglect the very small variation of Δψ during time ΔT
205+ double calcGrApparentSiderealTime (double JD )
200206{
201207 double T = calcJulianCent (JD );
202- return calcMeanSiderealTime (JD ) + calcNutationRtAscension (T); // in degrees
208+ return calcGrMeanSiderealTime (JD ) + calcNutationRtAscension (T); // in degrees
203209}
204210
205- // We neglect the small variation of delta_psi during time m
206- double calcSiderealTimeInstant (double GAST , double m)
211+ // We neglect the small variation of Δψ during time m
212+ double calcGrSiderealTimeInstant (double GAST , double m)
207213{
208214 return wrapTo360 (GAST + 360.985647 * m); // in degrees
209215}
210216
211217/*
212218// Alternate implementation
213219//
214- // Valid only at 0h UT, Greenwich (JD ending in .5)
215- double calcMeanSiderealTime(double JD)
220+ double calcGrMeanSiderealTimeInstant(double JD, double m)
216221{
217- double T = calcJulianCent(JD);
218- return wrapTo360(100.46061837 + T * (36000.770053608 + T * (0.000387933 - T / 38710000))); // in degrees
219- }
220-
221- double calcMeanSiderealTimeInstant(double JD, double m)
222- {
223- double theta0 = calcMeanSiderealTime(JD);
222+ double theta0 = calcGrMeanSiderealTime(JD);
224223 return wrapTo360(theta0 + 360.985647 * m); // in degrees
225224}
226225
227- double calcApparentSiderealTime(double JD)
228- {
229- double T = calcJulianCent(JD);
230- return calcMeanSiderealTime(JD) + calcNutationRtAscension(T); // in degrees
231- }
232-
233- double calcApparentSiderealTimeInstant(double JD, double m)
226+ double calcGrApparentSiderealTimeInstant(double JD, double m)
234227{
235228 double T = calcJulianCentSplit(JD, m);
236- return calcMeanSiderealTimeInstant (JD, m) + calcNutationRtAscension(T); // in degrees
229+ return calcGrMeanSiderealTimeInstant (JD, m) + calcNutationRtAscension(T); // in degrees
237230}
238231*/
239232
240- double calcSolarAzimuth (double ha , double decl, double lat)
233+ double calcSunAzimuth (double HA , double decl, double lat)
241234{
242- return degrees (atan2 (sin (radians (ha )), cos (radians (ha )) * sin (radians (lat)) -
235+ return degrees (atan2 (sin (radians (HA )), cos (radians (HA )) * sin (radians (lat)) -
243236 tan (radians (decl)) * cos (radians (lat)))); // in degrees
244237}
245238
246- double calcSolarElevation (double ha , double decl, double lat)
239+ double calcSunElevation (double HA , double decl, double lat)
247240{
248241 return degrees (asin (sin (radians (lat)) * sin (radians (decl)) +
249- cos (radians (lat)) * cos (radians (decl)) * cos (radians (ha )))); // in degrees
242+ cos (radians (lat)) * cos (radians (decl)) * cos (radians (HA )))); // in degrees
250243}
251244
252245// Approximate atmospheric refraction correction
253246// National Oceanic and Atmospheric Administration (NOAA)
254247//
255- double calcRefractionCorr (double elev)
248+ double calcRefraction (double elev)
256249{
257250 if (elev > 85.0 )
258251 return 0.0 ;
@@ -276,7 +269,7 @@ double equationOfTimeSmart(double T)
276269 double e = calcEccentricityEarthOrbit (T);
277270 double L = radians (calcGeomMeanLongSun (T));
278271 double M = radians (calcGeomMeanAnomalySun (T));
279- double epsilon = radians (calcObliquityCorrectionV2 (T));
272+ double epsilon = radians (calcObliquityCorrection (T));
280273 double y = tan (epsilon / 2 ) * tan (epsilon / 2 );
281274 return degrees (y * sin (2 * L) - 2 * e * sin (M) + 4 * e * y * sin (M) * cos (2 * L) - 0.5 * y * y * sin (4 * L) -
282275 1.25 * e * e * sin (2 * M)); // in degrees
@@ -290,7 +283,7 @@ double equationOfTimeHughes(double T)
290283 double e = calcEccentricityEarthOrbit (T);
291284 double L = radians (calcGeomMeanLongSun (T));
292285 double M = radians (calcGeomMeanAnomalySun (T));
293- double epsilon = radians (calcObliquityCorrectionV2 (T));
286+ double epsilon = radians (calcObliquityCorrection (T));
294287 double y = tan (epsilon / 2 ) * tan (epsilon / 2 );
295288 return degrees (0.00000447 * T + 0.00000149 * T * T - 2 * e * sin (M) - 1.25 * e * e * sin (2 * M) +
296289 y * sin (2 * L) - 0.5 * y * y * sin (4 * L) + 4 * e * y * sin (M) * cos (2 * L) +
@@ -303,13 +296,10 @@ double equationOfTimeHughes(double T)
303296//
304297double equationOfTimeMeeus (double T)
305298{
306- double alpha = wrapTo360 (calcSunRtAscension (T));
307- double delta_psi = calcNutationLongitude (T);
308- double epsilon = radians (calcObliquityCorrectionV2 (T));
309299 double t = T / 10 ;
310300 double L0 = wrapTo360 (280.4664567 + t * (360007.6982779 + t * (0.03032028 + t * (1 / 49931.0 - t * (1 / 15300.0 +
311301 t / 2000000 )))));
312- return L0 - 0.0057183 - alpha + delta_psi * cos (epsilon) / 3600 ; // in degrees
302+ return wrapTo180 ( L0 - 0.0057183 - calcSunRtAscension (T) - calcNutationRtAscension (T)) ; // in degrees
313303}
314304
315305// Polynomial Expressions for Delta T (ΔT) by Fred Espenak
@@ -444,16 +434,16 @@ void calcHorizontalCoordinates(int year, int month, int day, int hour, int minut
444434 double delta = calcSunDeclination (T);
445435
446436 // Find apparent sidereal time at Greenwich
447- double theta0 = calcApparentSiderealTime (JD );
448- theta0 = calcSiderealTimeInstant (theta0, m);
437+ double theta0 = calcGrApparentSiderealTime (JD );
438+ theta0 = calcGrSiderealTimeInstant (theta0, m);
449439
450440 // Find local angle hour
451441 double H = theta0 + longitude - alpha;
452442
453443 // Write results, in degrees
454- azimuth = 180 + calcSolarAzimuth (H, delta, latitude);
455- elevation = calcSolarElevation (H, delta, latitude);
456- elevation += calcRefractionCorr (elevation);
444+ azimuth = 180 + calcSunAzimuth (H, delta, latitude);
445+ elevation = calcSunElevation (H, delta, latitude);
446+ elevation += calcRefraction (elevation);
457447}
458448
459449// Calculate the Sun's radius vector (distance), in AUs
@@ -492,7 +482,7 @@ void calcSunriseSunset(int year, int month, int day, double latitude, double lon
492482 double delta3 = calcSunDeclination (T3 );
493483
494484 // Find apparent sidereal time at Greenwich
495- double theta0 = calcApparentSiderealTime (JD );
485+ double theta0 = calcGrApparentSiderealTime (JD );
496486
497487 // Local angle hour at sunrise or sunset (NaN if body is circumpolar)
498488 double H0 = degrees (acos ((sin (radians (h0)) - sin (radians (latitude)) * sin (radians (delta2))) /
@@ -512,25 +502,25 @@ void calcSunriseSunset(int year, int month, int day, double latitude, double lon
512502 {
513503 double n0 = m0 + delta_t / 86400 ;
514504 double transit_alpha = interpolateCoordinates (n0, alpha1, alpha2, alpha3);
515- double theta00 = calcSiderealTimeInstant (theta0, m0);
516- double transit_ha = wrapTo180 (theta00 + longitude - transit_alpha);
505+ double transit_theta0 = calcGrSiderealTimeInstant (theta0, m0);
506+ double transit_ha = wrapTo180 (transit_theta0 + longitude - transit_alpha);
517507 double transit_corr = -transit_ha / 360 ;
518508
519509 double n1 = m1 + delta_t / 86400 ;
520510 double rise_alpha = interpolateCoordinates (n1, alpha1, alpha2, alpha3);
521511 double rise_delta = interpolateCoordinates (n1, delta1, delta2, delta3);
522- double theta01 = calcSiderealTimeInstant (theta0, m1);
523- double rise_ha = theta01 + longitude - rise_alpha;
524- double rise_elev = calcSolarElevation (rise_ha, rise_delta, latitude);
512+ double rise_theta0 = calcGrSiderealTimeInstant (theta0, m1);
513+ double rise_ha = rise_theta0 + longitude - rise_alpha;
514+ double rise_elev = calcSunElevation (rise_ha, rise_delta, latitude);
525515 double rise_corr = (rise_elev - h0) /
526516 (360.0 * cos (radians (rise_delta)) * cos (radians (latitude)) * sin (radians (rise_ha)));
527517
528518 double n2 = m2 + delta_t / 86400 ;
529519 double set_alpha = interpolateCoordinates (n2, alpha1, alpha2, alpha3);
530520 double set_delta = interpolateCoordinates (n2, delta1, delta2, delta3);
531- double theta02 = calcSiderealTimeInstant (theta0, m2);
532- double set_ha = theta02 + longitude - set_alpha;
533- double set_elev = calcSolarElevation (set_ha, set_delta, latitude);
521+ double set_theta0 = calcGrSiderealTimeInstant (theta0, m2);
522+ double set_ha = set_theta0 + longitude - set_alpha;
523+ double set_elev = calcSunElevation (set_ha, set_delta, latitude);
534524 double set_corr = (set_elev - h0) /
535525 (360.0 * cos (radians (set_delta)) * cos (radians (latitude)) * sin (radians (set_ha)));
536526
0 commit comments