wmcalclockkbd: Move variable definitions from xutil.h -> xutil.c
[dockapps.git] / wmmoonclock / src / MoonRise.c
blobe8ff484d3ca854f991684d7d6cfe0a0f4e83ceae
1 #include <math.h>
2 #include "MoonRise.h"
3 #include "Moon.h"
5 #define DegPerRad 57.29577951308232087680
6 #define RadPerDeg 0.01745329251994329576
8 extern double Glon, SinGlat, CosGlat, TimeZone;
11 void MoonRise(int year, int month, int day, double LocalHour, double *UTRise, double *UTSet){
13 double UT, ym, y0, yp, SinH0;
14 double xe, ye, z1, z2, SinH(), hour24();
15 int Rise, Set, nz;
17 SinH0 = sin( 8.0/60.0 * RadPerDeg );
20 UT = 1.0+TimeZone;
21 *UTRise = -999.0;
22 *UTSet = -999.0;
23 Rise = Set = 0;
24 ym = SinH(year, month, day, UT-1.0) - SinH0;
26 while ( (UT <= 24.0+TimeZone) ) {
28 y0 = SinH(year, month, day, UT) - SinH0;
29 yp = SinH(year, month, day, UT+1.0) - SinH0;
31 Interp(ym, y0, yp, &xe, &ye, &z1, &z2, &nz);
33 switch(nz){
35 case 0:
36 break;
37 case 1:
38 if (ym < 0.0){
39 *UTRise = UT + z1;
40 Rise = 1;
41 } else {
42 *UTSet = UT + z1;
43 Set = 1;
45 break;
46 case 2:
47 if (ye < 0.0){
48 *UTRise = UT + z2;
49 *UTSet = UT + z1;
50 } else {
51 *UTRise = UT + z1;
52 *UTSet = UT + z2;
54 Rise = 1;
55 Set = 1;
56 break;
58 ym = yp;
59 UT += 2.0;
63 if (Rise){
64 *UTRise -= TimeZone;
65 *UTRise = hour24(*UTRise);
66 } else {
67 *UTRise = -999.0;
70 if (Set){
71 *UTSet -= TimeZone;
72 *UTSet = hour24(*UTSet);
73 } else {
74 *UTSet = -999.0;
80 void UTTohhmm(double UT, int *h, int *m){
83 if (UT < 0.0) {
84 *h = -1.0;
85 *m = -1.0;
86 } else {
87 *h = (int)UT;
88 *m = (int)((UT-(double)(*h))*60.0+0.5);
89 if (*m == 60) {
91 * If it was 23:60 this should become 24:00
92 * I prefer this designation to 00:00. So dont reset h to 0 when it goes above 24.
94 *h += 1;
95 *m = 0;
106 void Interp(double ym, double y0, double yp, double *xe, double *ye, double *z1, double *z2, int *nz){
108 double a, b, c, d, dx;
110 *nz = 0;
111 a = 0.5*(ym+yp)-y0;
112 b = 0.5*(yp-ym);
113 c = y0;
114 *xe = -b/(2.0*a);
115 *ye = (a*(*xe) + b) * (*xe) + c;
116 d = b*b - 4.0*a*c;
118 if (d >= 0){
119 dx = 0.5*sqrt(d)/fabs(a);
120 *z1 = *xe - dx;
121 *z2 = *xe+dx;
122 if (fabs(*z1) <= 1.0) *nz += 1;
123 if (fabs(*z2) <= 1.0) *nz += 1;
124 if (*z1 < -1.0) *z1 = *z2;
134 double SinH(int year, int month, int day, double UT){
136 double TU, frac(), jd();
137 double RA_Moon, DEC_Moon, gmst, lmst, Tau, Moon();
138 double angle2pi();
140 TU = (jd(year, month, day, UT) - 2451545.0)/36525.0;
142 /* this is more accurate, but wasteful for this -- use low res approx.
143 TU2 = TU*TU;
144 TU3 = TU2*TU;
145 Moon(TU, &LambdaMoon, &BetaMoon, &R, &AGE);
146 LambdaMoon *= RadPerDeg;
147 BetaMoon *= RadPerDeg;
148 epsilon = (23.43929167 - 0.013004166*TU - 1.6666667e-7*TU2 - 5.0277777778e-7*TU3)*RadPerDeg;
149 RA_Moon = angle2pi(atan2(sin(LambdaMoon)*cos(epsilon)-tan(BetaMoon)*sin(epsilon), cos(LambdaMoon)));
150 DEC_Moon = asin( sin(BetaMoon)*cos(epsilon) + cos(BetaMoon)*sin(epsilon)*sin(LambdaMoon));
153 MiniMoon(TU, &RA_Moon, &DEC_Moon);
154 RA_Moon *= 15.0*RadPerDeg;
155 DEC_Moon *= RadPerDeg;
158 * Compute Greenwich Mean Sidereal Time (gmst)
160 UT = 24.0*frac( UT/24.0 );
161 /* this is for the ephemeris meridian???
162 gmst = 6.697374558 + 1.0027379093*UT + (8640184.812866+(0.093104-6.2e-6*TU)*TU)*TU/3600.0;
164 gmst = UT + 6.697374558 + (8640184.812866+(0.093104-6.2e-6*TU)*TU)*TU/3600.0;
165 lmst = 24.0*frac( (gmst-Glon/15.0) / 24.0 );
167 Tau = 15.0*lmst*RadPerDeg - RA_Moon;
168 return( SinGlat*sin(DEC_Moon) + CosGlat*cos(DEC_Moon)*cos(Tau) );