1
1
/* SWISSEPH
2
- $Header: /home/dieter/sweph/RCS/swecl.c,v 1.75 2008/08/26 07:23:27 dieter Exp $
3
2
4
3
Ephemeris computations
5
4
Author: Dieter Koch
@@ -557,6 +556,10 @@ struct saros_data saros_data_lunar[NSAROS_LUNAR] = {
557
556
* attr[5] true altitude of sun above horizon at tjd
558
557
* attr[6] apparent altitude of sun above horizon at tjd
559
558
* attr[7] angular distance of moon from sun in degrees
559
+ * attr[8] magnitude acc. to NASA;
560
+ * = attr[0] for partial and attr[1] for annular and total eclipses
561
+ * attr[9] saros series number
562
+ * attr[10] saros series member number
560
563
* declare as attr[20] at least !
561
564
*/
562
565
int32 CALL_CONV swe_sol_eclipse_where (
@@ -1064,7 +1067,8 @@ static int32 eclipse_how( double tjd_ut, int32 ipl, char *starname, int32 ifl,
1064
1067
if (lsun > 0 ) {
1065
1068
attr [0 ] = lsunleft / rsun / 2 ;
1066
1069
} else {
1067
- attr [0 ] = 100 ;
1070
+ //attr[0] = 100;
1071
+ attr [0 ] = 1 ;
1068
1072
}
1069
1073
/*if (retc == SE_ECL_ANNULAR || retc == SE_ECL_TOTAL)
1070
1074
attr[0] = attr[1];*/
@@ -1076,7 +1080,8 @@ static int32 eclipse_how( double tjd_ut, int32 ipl, char *starname, int32 ifl,
1076
1080
lmoon = rmoon ;
1077
1081
lctr = dctr ;
1078
1082
if (retc == 0 || lsun == 0 ) {
1079
- attr [2 ] = 100 ;
1083
+ //attr[2] = 100;
1084
+ attr [2 ] = 1 ;
1080
1085
} else if (retc == SE_ECL_TOTAL || retc == SE_ECL_ANNULAR ) {
1081
1086
attr [2 ] = lmoon * lmoon / lsun / lsun ;
1082
1087
} else {
@@ -3008,7 +3013,6 @@ void CALL_CONV swe_set_lapse_rate(double lapse_rate)
3008
3013
* * SE_TRUE_TO_APP
3009
3014
*
3010
3015
* function returns:
3011
- * function returns:
3012
3016
* double *dret; * array of 4 doubles; declare 20 doubles !
3013
3017
* - dret[0] true altitude, if possible; otherwise input value
3014
3018
* - dret[1] apparent altitude, if possible; otherwise input value
@@ -3018,14 +3022,14 @@ void CALL_CONV swe_set_lapse_rate(double lapse_rate)
3018
3022
* The body is above the horizon if the dret[0] != dret[1]
3019
3023
*
3020
3024
* case 1, conversion from true altitude to apparent altitude
3021
- * - apparent altitude, if body appears above is observable above ideal horizon
3025
+ * - apparent altitude, if body is observable above ideal horizon
3022
3026
* - true altitude (the input value), otherwise
3023
3027
* "ideal horizon" is the horizon as seen above an ideal sphere (as seen
3024
3028
* from a plane over the ocean with a clear sky)
3025
3029
* case 2, conversion from apparent altitude to true altitude
3026
3030
* - the true altitude resulting from the input apparent altitude, if this value
3027
3031
* is a plausible apparent altitude, i.e. if it is a position above the ideal
3028
- * horizon
3032
+ * horizon, taking into account the dip of the horizon
3029
3033
* - the input altitude otherwise
3030
3034
*
3031
3035
* The body is above the horizon if the dret[0] != dret[1]
@@ -3087,6 +3091,7 @@ double CALL_CONV swe_refrac_extended(double inalt, double geoalt, double atpress
3087
3091
} else {
3088
3092
refr = calc_astronomical_refr (inalt ,atpress ,attemp );
3089
3093
trualt = inalt - refr ;
3094
+ //printf("inalt=%f, dip=%f\n", inalt, dip);
3090
3095
if (dret != NULL ) {
3091
3096
if (inalt > dip ) {
3092
3097
dret [0 ]= trualt ;
@@ -3100,7 +3105,11 @@ double CALL_CONV swe_refrac_extended(double inalt, double geoalt, double atpress
3100
3105
dret [3 ]= dip ;
3101
3106
}
3102
3107
}
3103
- if (trualt > dip )
3108
+ // Apparent altitude cannot be below dip.
3109
+ // True altitude is only returned if apparent altitude is hgher than dip.
3110
+ // Othwise the apparent altitude is returned.
3111
+ //if (trualt > dip)
3112
+ if (inalt >= dip ) // bug fix dieter, 4 feb 20
3104
3113
return trualt ;
3105
3114
else
3106
3115
return inalt ;
@@ -3739,7 +3748,8 @@ int32 CALL_CONV swe_lun_eclipse_when_loc(double tjd_start, int32 ifl,
3739
3748
*/
3740
3749
#define EULER 2.718281828459
3741
3750
#define NMAG_ELEM (SE_VESTA + 1)
3742
- #define MAG_HILTON_2005
3751
+ #define MAG_HILTON_2005 0
3752
+ #define MAG_MALLAMA_2018 1
3743
3753
/* Magnitudes according to:
3744
3754
* - "Explanatory Supplement to the Astronomical Almanac" 1986.
3745
3755
* Magnitudes for Mercury and Venus:
@@ -3784,9 +3794,8 @@ int32 CALL_CONV swe_pheno(double tjd, int32 ipl, int32 iflag, double *attr, char
3784
3794
{
3785
3795
int i ;
3786
3796
double xx [6 ], xx2 [6 ], xxs [6 ], lbr [6 ], lbr2 [6 ], dt = 0 , dd ;
3787
- double i100 ;
3788
3797
double fac ;
3789
- double T , in , om , sinB , u1 , u2 , du ;
3798
+ double T , in , om , sinB ;
3790
3799
double ph1 , ph2 , me [2 ];
3791
3800
int32 iflagp , epheflag , retflag , epheflag2 ;
3792
3801
char serr2 [AS_MAXCH ];
@@ -3906,7 +3915,114 @@ int32 CALL_CONV swe_pheno(double tjd, int32 ipl, int32 iflag, double *attr, char
3906
3915
attr [4 ] = mag_elem [ipl ][0 ] - 2.5 * log10 (fac );
3907
3916
#endif
3908
3917
/*printf("1 = %f, 2 = %f\n", mag, mag2);*/
3918
+ #if MAG_HILTON_2005
3919
+ } else if (ipl == SE_MERCURY ) {
3920
+ /* valid range is actually 2.1° < i < 169.5° */
3921
+ double i100 = attr [0 ] / 100.0 ;
3922
+ attr [4 ] = -0.60 + 4.98 * i100 - 4.88 * i100 * i100 + 3.02 * i100 * i100 * i100 ;
3923
+ attr [4 ] += 5 * log10 (lbr2 [2 ] * lbr [2 ]);
3924
+ if (attr [0 ] < 2.1 || attr [0 ] > 169.5 )
3925
+ sprintf (serr2 , "magnitude value for Mercury at phase angle i=%.1f is bad; formula is valid only for 2.1 < i < 169.5" , attr [0 ]);
3926
+ } else if (ipl == SE_VENUS ) {
3927
+ double i100 = attr [0 ] / 100.0 ;
3928
+ if (attr [0 ] < 163.6 ) /* actual valid range is 2.2° < i < 163.6° */
3929
+ attr [4 ] = -4.47 + 1.03 * i100 + 0.57 * i100 * i100 + 0.13 * i100 * i100 * i100 ;
3930
+ else /* actual valid range is 163.6° < i < 170.2° */
3931
+ attr [4 ] = 0.98 - 1.02 * i100 ;
3932
+ attr [4 ] += 5 * log10 (lbr2 [2 ] * lbr [2 ]);
3933
+ if (attr [0 ] < 2.2 || attr [0 ] > 170.2 )
3934
+ sprintf (serr2 , "magnitude value for Venus at phase angle i=%.1f is bad; formula is valid only for 2.2 < i < 170.2" , attr [0 ]);
3935
+ #endif
3936
+ #if MAG_MALLAMA_2018
3937
+ // see: A. Mallama, J.Hilton,
3938
+ // "ComputingApparentPlanetaryMagnitudesforTheAstronomicalAlmanac" (2018)
3939
+ // https://arxiv.org/ftp/arxiv/papers/1808/1808.01973.pdf
3940
+ } else if (ipl == SE_MERCURY ) {
3941
+ double a = attr [0 ];
3942
+ double a2 = a * a ; double a3 = a2 * a ; double a4 = a3 * a ; double a5 = a4 * a ; double a6 = a5 * a ;
3943
+ attr [4 ] = -0.613 + a * 6.3280E-02 - a2 * 1.6336E-03 + a3 * 3.3644E-05 - a4 * 3.4265E-07 + a5 * 1.6893E-09 - a6 * 3.0334E-12 ;
3944
+ attr [4 ] += 5 * log10 (lbr2 [2 ] * lbr [2 ]);
3945
+ } else if (ipl == SE_VENUS ) {
3946
+ double a = attr [0 ];
3947
+ double a2 = a * a ; double a3 = a2 * a ; double a4 = a3 * a ;
3948
+ if (a <= 163.7 )
3949
+ attr [4 ] = -4.384 - a * 1.044E-03 + a2 * 3.687E-04 - a3 * 2.814E-06 + a4 * 8.938E-09 ;
3950
+ else
3951
+ attr [4 ] = 236.05828 - a * 2.81914E+00 + a2 * 8.39034E-03 ;
3952
+ attr [4 ] += 5 * log10 (lbr2 [2 ] * lbr [2 ]);
3953
+ if (attr [0 ] > 179.0 )
3954
+ sprintf (serr2 , "magnitude value for Venus at phase angle i=%.1f is bad; formula is valid only for i < 179.0" , attr [0 ]);
3955
+ } else if (ipl == SE_MARS ) {
3956
+ double a = attr [0 ];
3957
+ double a2 = a * a ;
3958
+ /* With the following formulae, the terms +L(λe)+L(LS) have been omitted.
3959
+ * They are "the magnitude corrections for the longitude of the sub-Earth
3960
+ * meridian of the illuminated disk and the longitude of the vernal
3961
+ * equinox,respectively".
3962
+ * The apparent magnitude of Mars changes considerably within hours,
3963
+ * depending on the surface that is seen.
3964
+ * Note that the maximum phase angle of mars as seen from earth is
3965
+ * about 45°.
3966
+ * The deviation of this simplified solution from Horizons is
3967
+ * smaller than 0.1m.
3968
+ */
3969
+ if (a <= 50.0 )
3970
+ attr [4 ] = -1.601 + a * 0.02267 - a2 * 0.0001302 ;
3971
+ else // irrelevant to earth-centered observation
3972
+ attr [4 ] = -0.367 - a * 0.02573 + a2 * 0.0003445 ;
3973
+ attr [4 ] += 5 * log10 (lbr2 [2 ] * lbr [2 ]);
3974
+ } else if (ipl == SE_JUPITER ) {
3975
+ /* the phase angle of Jupiter never exceeds 12°. */
3976
+ double a = attr [0 ];
3977
+ double a2 = a * a ;
3978
+ attr [4 ] = -9.395 - a * 3.7E-04 + a2 * 6.16E-04 ;
3979
+ attr [4 ] += 5 * log10 (lbr2 [2 ] * lbr [2 ]);
3909
3980
} else if (ipl == SE_SATURN ) {
3981
+ double a = attr [0 ];
3982
+ double sinB2 ;
3983
+ T = (tjd - dt - J2000 ) / 36525.0 ;
3984
+ in = (28.075216 - 0.012998 * T + 0.000004 * T * T ) * DEGTORAD ;
3985
+ om = (169.508470 + 1.394681 * T + 0.000412 * T * T ) * DEGTORAD ;
3986
+ // B is "mean tilt of the ring plane to the Earth and Sun (If the Earth
3987
+ // and Sun are on opposite sides of the ring plane B = 0)" according to Hilton:
3988
+ // https://syrte.obspm.fr/astro/journees2019/journees_pdf/SessionV_1/HiltonStewart_final.pdf
3989
+ // Mallama does not provide B. We derive it from
3990
+ // Meeus, p. 301ff. (German version 329ff.)
3991
+ // There are small differences from Horizons < 0.02m.
3992
+ sinB = (sin (in ) * cos (lbr [1 ] * DEGTORAD )
3993
+ * sin (lbr [0 ] * DEGTORAD - om )
3994
+ - cos (in ) * sin (lbr [1 ] * DEGTORAD ));
3995
+ sinB2 = (sin (in ) * cos (lbr2 [1 ] * DEGTORAD )
3996
+ * sin (lbr2 [0 ] * DEGTORAD - om )
3997
+ - cos (in ) * sin (lbr2 [1 ] * DEGTORAD ));
3998
+ sinB = fabs (sin ((asin (sinB ) + asin (sinB2 )) / 2.0 ));/**/
3999
+ attr [4 ] = -8.914 - 1.825 * sinB + 0.026 * a - 0.378 * sinB * pow (2.7182818 ,-2.25 * a );
4000
+ attr [4 ] += 5 * log10 (lbr2 [2 ] * lbr [2 ]);
4001
+ } else if (ipl == SE_URANUS ) {
4002
+ // This is a simplified solution ignoring the term depending on
4003
+ // sub-Earth latitude. The difference from Horizons is +-0.03m.
4004
+ double a = attr [0 ];
4005
+ double a2 = a * a ;
4006
+ double fi_ = 0 ; // sub-Earth latitude in deg; ignored here
4007
+ attr [4 ] = -7.110 - 8.4E-04 * fi_ + a * 6.587E-3 + a2 * 1.045E-4 ;
4008
+ attr [4 ] += 5 * log10 (lbr2 [2 ] * lbr [2 ]);
4009
+ // instead of the term with fi_, we do subtract the 0.05m.
4010
+ // the remaining error is +-0.03m
4011
+ attr [4 ] -= 0.05 ;
4012
+ } else if (ipl == SE_NEPTUNE ) {
4013
+ if (tjd < 2444239.5 ) {
4014
+ attr [4 ] = -6.89 ;
4015
+ } else if (tjd <= 2451544.5 ) {
4016
+ attr [4 ] = -6.89 - 0.0055 * (tjd - 2444239.5 ) / 365.25 ;
4017
+ // Mallama has 0.0054, but that would make the curve discontinuos
4018
+ // Nevertheless, JPL Horizons has 0.0054 and the discontinuity
4019
+ } else {
4020
+ attr [4 ] = -7.00 ;
4021
+ }
4022
+ attr [4 ] += 5 * log10 (lbr2 [2 ] * lbr [2 ]);
4023
+ #else
4024
+ } else if (ipl == SE_SATURN ) {
4025
+ double u1 , u2 , du ;
3910
4026
/* rings are considered according to Meeus, p. 301ff. (German version 329ff.) */
3911
4027
T = (tjd - dt - J2000 ) / 36525.0 ;
3912
4028
in = (28.075216 - 0.012998 * T + 0.000004 * T * T ) * DEGTORAD ;
@@ -3928,34 +4044,17 @@ int32 CALL_CONV swe_pheno(double tjd, int32 ipl, int32 iflag, double *attr, char
3928
4044
+ mag_elem [ipl ][2 ] * sinB * sinB
3929
4045
+ mag_elem [ipl ][3 ] * du
3930
4046
+ mag_elem [ipl ][0 ];
3931
- #ifdef MAG_HILTON_2005
3932
- } else if (ipl == SE_MERCURY ) {
3933
- /* valid range is actually 2.1° < i < 169.5° */
3934
- i100 = attr [0 ] / 100.0 ;
3935
- attr [4 ] = -0.60 + 4.98 * i100 - 4.88 * i100 * i100 + 3.02 * i100 * i100 * i100 ;
3936
- attr [4 ] += 5 * log10 (lbr2 [2 ] * lbr [2 ]);
3937
- if (attr [0 ] < 2.1 || attr [0 ] > 169.5 )
3938
- sprintf (serr2 , "magnitude value for Mercury at phase angle i=%.1f is bad; formula is valid only for 2.1 < i < 169.5" , attr [0 ]);
3939
- } else if (ipl == SE_VENUS ) {
3940
- i100 = attr [0 ] / 100.0 ;
3941
- if (attr [0 ] < 163.6 ) /* actual valid range is 2.2° < i < 163.6° */
3942
- attr [4 ] = -4.47 + 1.03 * i100 + 0.57 * i100 * i100 + 0.13 * i100 * i100 * i100 ;
3943
- else /* actual valid range is 163.6° < i < 170.2° */
3944
- attr [4 ] = 0.98 - 1.02 * i100 ;
3945
- attr [4 ] += 5 * log10 (lbr2 [2 ] * lbr [2 ]);
3946
- if (attr [0 ] < 2.2 || attr [0 ] > 170.2 )
3947
- sprintf (serr2 , "magnitude value for Venus at phase angle i=%.1f is bad; formula is valid only for 2.2 < i < 170.2" , attr [0 ]);
3948
4047
#endif
3949
4048
} else if (ipl < SE_CHIRON ) {
3950
4049
attr [4 ] = 5 * log10 (lbr2 [2 ] * lbr [2 ])
3951
4050
+ mag_elem [ipl ][1 ] * attr [0 ] /100.0
3952
4051
+ mag_elem [ipl ][2 ] * attr [0 ] * attr [0 ] / 10000.0
3953
4052
+ mag_elem [ipl ][3 ] * attr [0 ] * attr [0 ] * attr [0 ] / 1000000.0
3954
4053
+ mag_elem [ipl ][0 ];
3955
- } else if (ipl < NMAG_ELEM || ipl > SE_AST_OFFSET ) { /* asteroids */
4054
+ } else if (ipl < NMAG_ELEM || ipl > SE_AST_OFFSET ) { /* other planets, asteroids */
3956
4055
ph1 = pow (EULER , -3.33 * pow (tan (attr [0 ] * DEGTORAD / 2 ), 0.63 ));
3957
4056
ph2 = pow (EULER , -1.87 * pow (tan (attr [0 ] * DEGTORAD / 2 ), 1.22 ));
3958
- if (ipl < NMAG_ELEM ) { /* main asteroids */
4057
+ if (ipl < NMAG_ELEM ) { /* other planets, main asteroids */
3959
4058
me [0 ] = mag_elem [ipl ][0 ];
3960
4059
me [1 ] = mag_elem [ipl ][1 ];
3961
4060
} else if (ipl == SE_AST_OFFSET + 1566 ) {
@@ -4226,7 +4325,7 @@ static int32 rise_set_fast(
4226
4325
if (dt > 0.1 ) dt = 0.1 ;
4227
4326
else if (dt < -0.1 ) dt = -0.1 ;
4228
4327
dtsum += dt ;
4229
- if (0 && fabs (dt ) > 5.0 / 86400.0 && nloop < 20 )
4328
+ if (( 0 ) && fabs (dt ) > 5.0 / 86400.0 && nloop < 20 )
4230
4329
nloop ++ ;
4231
4330
tr -= dt ;
4232
4331
}
0 commit comments