1 #include <math.h> /* for sin, cos, fabs, sqrt, atan, etc */
3 #define DegPerRad 57.29577951308232087680
4 #define RadPerDeg 0.01745329251994329576
6 extern double Glon
, SinGlat
, CosGlat
, TimeZone
;
8 double cosEPS
= 0.91748;
9 double sinEPS
= 0.39778;
10 double P2
= 6.283185307;
12 int Interp(double ym
, double y0
, double yp
, double *xe
, double *ye
, double *z1
, double *z2
, int *nz
){
21 *ye
= (a
*(*xe
) + b
) * (*xe
) + c
;
27 dx
= 0.5*sqrt(d
)/fabs(a
);
30 if (fabs(*z1
) <= 1.0) *nz
+= 1;
31 if (fabs(*z2
) <= 1.0) *nz
+= 1;
32 if (*z1
< -1.0) *z1
= *z2
;
40 void SunRise(int year
, int month
, int day
, double LocalHour
, double *UTRise
, double *UTSet
){
43 double xe
, ye
, z1
, z2
, SinH(), hour24();
47 SinH0
= sin( -50.0/60.0 * RadPerDeg
);
54 ym
= SinH(year
, month
, day
, UT
-1.0) - SinH0
;
56 while ( (UT
<= 24.0+TimeZone
) ) {
59 y0
= SinH(year
, month
, day
, UT
) - SinH0
;
60 yp
= SinH(year
, month
, day
, UT
+1.0) - SinH0
;
62 Interp(ym
, y0
, yp
, &xe
, &ye
, &z1
, &z2
, &nz
);
96 *UTRise
= hour24(*UTRise
);
103 *UTSet
= hour24(*UTSet
);
110 double SinH(int year
, int month
, int day
, double UT
){
112 double TU
, frac(), jd();
113 double RA_Sun
, DEC_Sun
, gmst
, lmst
, Tau
;
114 double M
, DL
, L
, SL
, X
, Y
, Z
, RHO
;
117 TU
= (jd(year
, month
, day
, UT
+62.0/3600.0) - 2451545.0)/36525.0;
119 M
= P2
*frac(0.993133 + 99.997361*TU
);
120 DL
= 6893.0*sin(M
) + 72.0*sin(2.0*M
);
121 L
= P2
*frac(0.7859453 + M
/P2
+ (6191.2*TU
+DL
)/1296e3
);
123 X
= cos(L
); Y
= cosEPS
*SL
; Z
= sinEPS
*SL
; RHO
= sqrt(1.0-Z
*Z
);
124 DEC_Sun
= atan2(Z
, RHO
);
125 RA_Sun
= (48.0/P2
)*atan(Y
/(X
+RHO
));
126 if (RA_Sun
< 0) RA_Sun
+= 24.0;
128 RA_Sun
= RA_Sun
*15.0*RadPerDeg
;
131 * Compute Greenwich Mean Sidereal Time (gmst)
133 UT
= 24.0*frac( UT
/24.0 );
135 gmst
= 6.697374558 + 1.0*UT
+ (8640184.812866+(0.093104-6.2e-6*TU
)*TU
)*TU
/3600.0;
136 lmst
= 24.0*frac( (gmst
-Glon
/15.0) / 24.0 );
138 Tau
= 15.0*lmst
*RadPerDeg
- RA_Sun
;
139 return( SinGlat
*sin(DEC_Sun
) + CosGlat
*cos(DEC_Sun
)*cos(Tau
) );
146 * Compute the Julian Day number for the given date.
147 * Julian Date is the number of days since noon of Jan 1 4713 B.C.
149 double jd(ny
, nm
, nd
, UT
)
153 double B
, C
, D
, JD
, day
;
158 if ((nm
== 1) || (nm
== 2)){
163 if (((double)ny
+nm
/12.0+day
/365.25)>=(1582.0+10.0/12.0+15.0/365.25)){
166 A
= ((int)(ny
/ 100.0));
167 B
= 2.0 - A
+ (int)(A
/4.0);
174 C
= (int)((365.25*(double)ny
) - 0.75);
177 C
= (int)(365.25*(double)ny
);
180 D
= (int)(30.6001*(double)(nm
+1));
183 JD
= B
+ C
+ D
+ day
+ 1720994.5;
194 n
= (int)(hour
/24.0) - 1;
197 else if (hour
> 24.0){
198 n
= (int)(hour
/24.0);
206 double frac(double x
){
209 return( (x
<0) ? x
+1.0 : x
);