mirror of https://github.com/XEphem/XEphem.git
235 lines
6.0 KiB
C
235 lines
6.0 KiB
C
/* code to compute lunar sunrise position and local sun angle.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
#include "astro.h"
|
|
|
|
static void Librations (double RAD, double LAMH, double BH, double OM,
|
|
double F, double L, double L1, double *L0, double *B0);
|
|
static void Moon (double RAD, double T, double T2, double LAM0, double R,
|
|
double M, double *F, double *L1, double *OM, double *LAM, double *B,
|
|
double *DR, double *LAMH, double *BH);
|
|
static void Sun (double RAD, double T, double T2, double *L, double *M,
|
|
double *R, double *LAM0);
|
|
|
|
/* given a Julian date and a lunar location, find selenographic colongitude of
|
|
* rising sun, lunar latitude of subsolar point, illuminated fraction, and alt
|
|
* of sun at the given location. Any pointer may be 0 if not interested.
|
|
* From Bruning and Talcott, October 1995 _Astronomy_, page 76.
|
|
* N.B. lunar coordinates use +E, but selenograhic colongs are +W.
|
|
*/
|
|
void
|
|
moon_colong (
|
|
double jd, /* jd */
|
|
double lt, /* lat of location on moon, rads +N +E */
|
|
double lg, /* long of location on moon, rads +N +E */
|
|
double *cp, /* selenographic colongitude (-lng of rising sun), rads */
|
|
double *kp, /* illuminated fraction of surface from Earth */
|
|
double *ap, /* sun altitude at location, rads */
|
|
double *sp) /* lunar latitude of subsolar point, rads */
|
|
{
|
|
double RAD = .0174533;
|
|
double T;
|
|
double T2;
|
|
double L, M, R, LAM0;
|
|
double F, L1, OM, LAM, B, DR, LAMH, BH;
|
|
double L0, B0;
|
|
double TEMP;
|
|
double C0;
|
|
double PSI;
|
|
double NUM, DEN;
|
|
double I, K;
|
|
double THETA, ETA;
|
|
double H;
|
|
|
|
T = (jd - 2451545)/36525.0;
|
|
T2 = T * T;
|
|
|
|
Sun(RAD, T, T2, &L, &M, &R, &LAM0);
|
|
Moon(RAD, T, T2, LAM0, R, M, &F, &L1, &OM, &LAM, &B, &DR, &LAMH, &BH);
|
|
Librations(RAD, LAMH, BH, OM, F, L, L1, &L0, &B0);
|
|
if (sp)
|
|
*sp = B0;
|
|
|
|
TEMP = L0 / 360;
|
|
L0 = ((TEMP) - (int)(TEMP)) * 360;
|
|
if (L0 < 0) L0 = L0 + 360;
|
|
if (L0 <= 90) C0 = 90 - L0; else C0 = 450 - L0;
|
|
if (cp) {
|
|
*cp = degrad(C0);
|
|
range (cp, 2*PI); /* prefer 0..360 +W */
|
|
}
|
|
|
|
if (kp) {
|
|
TEMP = cos(B * RAD) * cos(LAM - LAM0 * RAD);
|
|
PSI = acos(TEMP);
|
|
NUM = R * sin(PSI);
|
|
DEN = DR - R * TEMP;
|
|
I = atan(NUM / DEN);
|
|
if (NUM * DEN < 0) I = I + 3.14159;
|
|
if (NUM < 0) I = I + 3.14159;
|
|
K = (1 + cos(I)) / 2;
|
|
*kp = K;
|
|
}
|
|
|
|
if (ap) {
|
|
THETA = lt;
|
|
ETA = lg;
|
|
C0 = C0 * RAD;
|
|
TEMP = sin(B0) * sin(THETA) + cos(B0) * cos(THETA) * sin(C0+ETA);
|
|
H = asin(TEMP);
|
|
*ap = H;
|
|
}
|
|
}
|
|
|
|
static void
|
|
Librations (double RAD, double LAMH, double BH, double OM, double F,
|
|
double L, double L1, double *L0, double *B0)
|
|
{
|
|
double I, PSI, W, NUM, DEN, A, TEMP;
|
|
|
|
/* inclination of lunar equator */
|
|
I = 1.54242 * RAD;
|
|
|
|
/* nutation in longitude, in arcseconds */
|
|
PSI = -17.2 * sin(OM) - 1.32 * sin(2 * L) - .23 * sin(2 * L1) +
|
|
.21 * sin(2 * OM);
|
|
PSI = PSI * RAD / 3600;
|
|
|
|
/* optical librations */
|
|
W = (LAMH - PSI) - OM;
|
|
NUM = sin(W) * cos(BH) * cos(I) - sin(BH) * sin(I);
|
|
DEN = cos(W) * cos(BH);
|
|
A = atan(NUM / DEN);
|
|
if (NUM * DEN < 0) A = A + 3.14159;
|
|
if (NUM < 0) A = A + 3.14159;
|
|
*L0 = (A - F) / RAD;
|
|
TEMP = -sin(W) * cos(BH) * sin(I) - sin(BH) * cos(I);
|
|
*B0 = asin(TEMP);
|
|
}
|
|
|
|
static void
|
|
Moon (double RAD, double T, double T2, double LAM0, double R, double M,
|
|
double *F, double *L1, double *OM, double *LAM, double *B, double *DR,
|
|
double *LAMH, double *BH)
|
|
{
|
|
double T3, M1, D2, SUMR, SUML, DIST;
|
|
|
|
T3 = T * T2;
|
|
|
|
/* argument of the latitude of the Moon */
|
|
*F = (93.2721 + 483202 * T - .003403 * T2 - T3 / 3526000) * RAD;
|
|
|
|
/* mean longitude of the Moon */
|
|
*L1 = (218.316 + 481268. * T) * RAD;
|
|
|
|
/* longitude of the ascending node of Moon's mean orbit */
|
|
*OM = (125.045 - 1934.14 * T + .002071 * T2 + T3 / 450000) * RAD;
|
|
|
|
/* Moon's mean anomaly */
|
|
M1 = (134.963 + 477199 * T + .008997 * T2 + T3 / 69700) * RAD;
|
|
|
|
/* mean elongation of the Moon */
|
|
D2 = (297.85 + 445267 * T - .00163 * T2 + T3 / 545900) * 2 * RAD;
|
|
|
|
/* Lunar distance */
|
|
SUMR = -20954 * cos(M1) - 3699 * cos(D2 - M1) - 2956 * cos(D2);
|
|
*DR = 385000 + SUMR;
|
|
|
|
/* geocentric latitude */
|
|
*B = 5.128 * sin(*F) + .2806 * sin(M1 + *F) + .2777 * sin(M1 - *F) +
|
|
.1732 * sin(D2 - *F);
|
|
SUML = 6.289 * sin(M1) + 1.274 * sin(D2 - M1) + .6583 * sin(D2) +
|
|
.2136 * sin(2 * M1) - .1851 * sin(M) - .1143 * sin(2 * *F);
|
|
*LAM = *L1 + SUML * RAD;
|
|
DIST = *DR / R;
|
|
*LAMH = (LAM0 + 180 + DIST * cos(*B) * sin(LAM0 * RAD - *LAM) / RAD)
|
|
* RAD;
|
|
*BH = DIST * *B * RAD;
|
|
}
|
|
|
|
static void
|
|
Sun (double RAD, double T, double T2, double *L, double *M, double *R,
|
|
double *LAM0)
|
|
{
|
|
double T3, C, V, E, THETA, OM;
|
|
|
|
T3 = T2 * T;
|
|
|
|
/* mean longitude of the Sun */
|
|
*L = 280.466 + 36000.8 * T;
|
|
|
|
/* mean anomaly of the Sun */
|
|
*M = 357.529 + 35999 * T - .0001536 * T2 + T3 / 24490000;
|
|
*M = *M * RAD;
|
|
|
|
/* correction for Sun's elliptical orbit */
|
|
C = (1.915 - .004817 * T - .000014 * T2) * sin(*M) +
|
|
(.01999 - .000101 * T) * sin(2 * *M) + .00029 * sin(3 * *M);
|
|
|
|
/* true anomaly of the Sun */
|
|
V = *M + C * RAD;
|
|
|
|
/* eccentricity of Earth's orbit */
|
|
E = .01671 - .00004204 * T - .0000001236 * T2;
|
|
|
|
/* Sun-Earth distance */
|
|
*R = .99972 / (1 + E * cos(V)) * 145980000;
|
|
|
|
/* true geometric longitude of the Sun */
|
|
THETA = *L + C;
|
|
|
|
/* apparent longitude of the Sun */
|
|
OM = 125.04 - 1934.1 * T;
|
|
*LAM0 = THETA - .00569 - .00478 * sin(OM * RAD);
|
|
}
|
|
|
|
#ifdef TESTCOLONG
|
|
|
|
/* insure 0 <= *v < r.
|
|
*/
|
|
void
|
|
range (v, r)
|
|
double *v, r;
|
|
{
|
|
*v -= r*floor(*v/r);
|
|
}
|
|
|
|
/* To be sure the program is functioning properly, try the test case
|
|
* 2449992.5 (1 Oct 1995): the colongitude should be 3.69 degrees.
|
|
*/
|
|
int
|
|
main (int ac, char *av[])
|
|
{
|
|
double jd, lt, lg;
|
|
double c, k, a;
|
|
|
|
if (ac != 2) {
|
|
fprintf (stderr, "%s: JD\n", av[0]);
|
|
abort();
|
|
}
|
|
|
|
jd = atof(av[1]);
|
|
|
|
printf ("Latitude of lunar feature: ");
|
|
fscanf (stdin, "%lf", <);
|
|
lt = degrad(lt);
|
|
printf ("Longitude: ");
|
|
fscanf (stdin, "%lf", &lg);
|
|
lg = degrad(lg);
|
|
|
|
moon_colong (jd, lt, lg, &c, &k, &a);
|
|
|
|
printf ("Selenographic colongitude is %g\n", raddeg(c));
|
|
printf ("The illuminated fraction of the Moon is %g\n", k);
|
|
printf ("Altitude of Sun above feature is %g\n", raddeg(a));
|
|
|
|
return (0);
|
|
}
|
|
|
|
#endif
|
|
|