5 void CalcEphem(date
, UT
, c
)
6 long int date
; /* integer containing the date (e.g. 960829) */
7 double UT
; /* Universal Time */
8 CTrans
*c
; /* structure containing all the relevent coord trans info */
12 double TU
, TU2
, TU3
, T0
, gmst
;
14 double eccen
, epsilon
;
15 double days
, M
, E
, nu
, lambnew
;
16 double r0
, earth_sun_distance
;
17 double RA
, DEC
, RA_Moon
, DEC_Moon
;
18 double TDT
, AGE
, LambdaMoon
, BetaMoon
, R
;
19 double jd(), hour24(), angle2pi(), angle360(), kepler(), Moon(), NewMoon();
20 double Ta
, Tb
, Tc
, frac();
21 double SinGlat
, CosGlat
, SinGlon
, CosGlon
, Tau
, lmst
, x
, y
, z
;
22 double SinTau
, CosTau
, SinDec
, CosDec
;
29 year
= (int)(date
/10000);
30 month
= (int)( (date
- year
*10000)/100 );
31 day
= (int)( date
- year
*10000 - month
*100 );
36 c
->doy
= DayofYear(year
, month
, day
);
37 c
->dow
= DayofWeek(year
, month
, day
, c
->dowstr
);
42 * Compute Greenwich Mean Sidereal Time (gmst)
43 * The TU here is number of Julian centuries
44 * since 2000 January 1.5
45 * From the 1996 astronomical almanac
47 TU
= (jd(year
, month
, day
, 0.0) - 2451545.0)/36525.0;
50 T0
= (6.0 + 41.0/60.0 + 50.54841/3600.0) + 8640184.812866/3600.0*TU
51 + 0.093104/3600.0*TU2
- 6.2e-6/3600.0*TU3
;
53 c
->gmst
= hour24(T0
+ UT
*1.002737909);
56 /* convert to radians for ease later on */
57 gmst
= c
->gmst
*15.0*M_PI
/180.0;
59 lmst
= 24.0*frac( (c
->gmst
- c
->Glon
/15.0) / 24.0 );
68 * Construct Transformation Matrix from GEI to GSE systems
72 * mean ecliptic longitude of sun at epoch TU (varep)
73 * elciptic longitude of perigee at epoch TU (varpi)
74 * eccentricity of orbit at epoch TU (eccen)
76 * The TU here is the number of Julian centuries since
77 * 1900 January 0.0 (= 2415020.0)
79 TDT
= UT
+ 59.0/3600.0;
80 TU
= (jd(year
, month
, day
, TDT
) - 2415020.0)/36525.0;
81 varep
= (279.6966778 + 36000.76892*TU
+ 0.0003025*TU
*TU
)*RadPerDeg
;
82 varpi
= (281.2208444 + 1.719175*TU
+ 0.000452778*TU
*TU
)*RadPerDeg
;
83 eccen
= 0.01675104 - 0.0000418*TU
- 0.000000126*TU
*TU
;
84 c
->eccentricity
= eccen
;
89 * Compute the Obliquity of the Ecliptic at epoch TU
90 * The TU in this formula is the number of Julian
91 * centuries since epoch 2000 January 1.5
93 TU
= (jd(year
, month
, day
, TDT
) - jd(2000, 1, 1, 12.0))/36525.0;
94 epsilon
= (23.43929167 - 0.013004166*TU
- 1.6666667e-7*TU
*TU
95 - 5.0277777778e-7*TU
*TU
*TU
)*RadPerDeg
;
101 * Number of Days since epoch 1990.0 (days)
102 * The Mean Anomaly (M)
103 * The True Anomaly (nu)
104 * The Eccentric Anomaly via Keplers equation (E)
108 days
= jd(year
, month
, day
, TDT
) - jd(year
, month
, day
, TDT
);
109 M
= angle2pi(2.0*M_PI
/365.242191*days
+ varep
- varpi
);
110 E
= kepler(M
, eccen
);
111 nu
= 2.0*atan( sqrt((1.0+eccen
)/(1.0-eccen
))*tan(E
/2.0) );
112 lambnew
= angle2pi(nu
+ varpi
);
113 c
->lambda_sun
= lambnew
;
117 * Compute distance from earth to the sun
119 r0
= 1.495985e8
; /* in km */
120 earth_sun_distance
= r0
*(1-eccen
*eccen
)/(1.0 + eccen
*cos(nu
))/6371.2;
121 c
->earth_sun_dist
= earth_sun_distance
;
128 * Compute Right Ascension and Declination of the Sun
130 RA
= angle360(atan2(sin(lambnew
)*cos(epsilon
), cos(lambnew
))*180.0/M_PI
);
131 DEC
= asin(sin(epsilon
)*sin(lambnew
))*180.0/M_PI
;
141 * Compute Moon Phase and AGE Stuff. The AGE that comes out of Moon()
142 * is actually the Phase converted to days. Since AGE is actually defined
143 * to be time since last NewMoon, we need to figure out what the JD of the
144 * last new moon was. Thats done below....
146 TU
= (jd(year
, month
, day
, TDT
) - 2451545.0)/36525.0;
147 c
->MoonPhase
= Moon(TU
, &LambdaMoon
, &BetaMoon
, &R
, &AGE
);
148 LambdaMoon
*= RadPerDeg
;
149 BetaMoon
*= RadPerDeg
;
152 RA_Moon
= angle360(atan2(sin(LambdaMoon
)*cos(epsilon
)-tan(BetaMoon
)*sin(epsilon
), cos(LambdaMoon
))*DegPerRad
);
153 DEC_Moon
= asin( sin(BetaMoon
)*cos(epsilon
) + cos(BetaMoon
)*sin(epsilon
)*sin(LambdaMoon
))*DegPerRad
;
154 c
->RA_moon
= RA_Moon
;
155 c
->DEC_moon
= DEC_Moon
;
159 * Compute Alt/Az coords
161 Tau
= (15.0*lmst
- RA_Moon
)*RadPerDeg
;
162 CosGlat
= cos(c
->Glat
*RadPerDeg
); SinGlat
= sin(c
->Glat
*RadPerDeg
);
163 CosGlon
= cos(c
->Glon
*RadPerDeg
); SinGlon
= sin(c
->Glon
*RadPerDeg
);
164 CosTau
= cos(Tau
); SinTau
= sin(Tau
);
165 SinDec
= sin(DEC_Moon
*RadPerDeg
); CosDec
= cos(DEC_Moon
*RadPerDeg
);
166 x
= CosDec
*CosTau
*SinGlat
- SinDec
*CosGlat
;
168 z
= CosDec
*CosTau
*CosGlat
+ SinDec
*SinGlat
;
169 c
->A_moon
= DegPerRad
*atan2(y
, x
);
170 c
->h_moon
= DegPerRad
*asin(z
);
171 c
->Visible
= (c
->h_moon
< 0.0) ? 0 : 1;
176 * Compute accurate AGE of the Moon
178 Tb
= TU
- AGE
/36525.0; /* should be very close to minimum */
179 Ta
= Tb
- 0.4/36525.0;
180 Tc
= Tb
+ 0.4/36525.0;
181 c
->MoonAge
= (TU
- NewMoon(Ta
, Tb
, Tc
))*36525.0;
186 * Compute Earth-Moon distance
188 c
->EarthMoonDistance
= R
;
202 double E
, Eold
, eps
= 1.0e-8;
209 E
= Eold
+ (M
-Eold
+e
*sin(Eold
))
212 }while((fabs(E
-Eold
) > eps
) && (n
< 100));
219 int DayofYear(year
, month
, day
)
220 int year
, month
, day
;
223 return((int)(jd(year
, month
, day
, 0.0) - jd(year
, 1, 0, 0.0)));
229 int DayofWeek(year
, month
, day
, dowstr
)
230 int year
, month
, day
;
233 double JD
, A
, Afrac
, jd();
236 JD
= jd(year
, month
, day
, 0.0);
239 Afrac
= A
- (double)iA
;
240 n
= (int)(Afrac
*7.0 + 0.5);
243 strcpy(dowstr
, "Sunday");
246 strcpy(dowstr
, "Monday");
249 strcpy(dowstr
, "Tuesday");
252 strcpy(dowstr
, "Wednesday");
255 strcpy(dowstr
, "Thursday");
258 strcpy(dowstr
, "Friday");
261 strcpy(dowstr
, "Saturday");
272 * Compute the Julian Day number for the given date.
273 * Julian Date is the number of days since noon of Jan 1 4713 B.C.
275 double jd(ny
, nm
, nd
, UT
)
279 double A
, B
, C
, D
, JD
, day
;
284 if ((nm
== 1) || (nm
== 2)){
289 if (((double)ny
+nm
/12.0+day
/365.25)>=(1582.0+10.0/12.0+15.0/365.25)){
290 A
= ((int)(ny
/ 100.0));
291 B
= 2.0 - A
+ (int)(A
/4.0);
298 C
= (int)((365.25*(double)ny
) - 0.75);
301 C
= (int)(365.25*(double)ny
);
304 D
= (int)(30.6001*(double)(nm
+1));
307 JD
= B
+ C
+ D
+ day
+ 1720994.5;
318 n
= (int)(hour
/24.0) - 1;
321 else if (hour
> 24.0){
322 n
= (int)(hour
/24.0);
330 double angle2pi(angle
)
338 n
= (int)(angle
/a
) - 1;
350 double angle360(angle
)
356 n
= (int)(angle
/360.0) - 1;
357 return(angle
-n
*360.0);
359 else if (angle
> 360.0){
360 n
= (int)(angle
/360.0);
361 return(angle
-n
*360.0);
369 void Radec_to_Cart(ra
, dec
, r
)
370 double ra
, dec
; /* RA and DEC */
371 Vector
*r
; /* returns corresponding cartesian unit vector */
375 * Convert ra/dec from degrees to radians
382 * Compute cartesian coordinates (in GEI)
384 r
->x
= cos(dec
) * cos(ra
);
385 r
->y
= cos(dec
) * sin(ra
);
397 if ((year
%100 == 0)&&(year
%400 != 0)) return(0);
398 else if (year
%4 == 0) return(1);