1 | /*
|
---|
2 | =============================================================================
|
---|
3 | moontx.c -- Calculate the current phase of the moon.
|
---|
4 | Version 2 -- 1989-01-10 -- D.N. Lynx Crowe
|
---|
5 |
|
---|
6 | Original code by Keith E. Brandt VIII 1984
|
---|
7 |
|
---|
8 | Based on routines from "Practical Astronomy with Your Calculator",
|
---|
9 | by Peter Duffett-Smith.
|
---|
10 |
|
---|
11 | Comments give the section of the book that particular piece
|
---|
12 | of code was adapted from.
|
---|
13 | =============================================================================
|
---|
14 | */
|
---|
15 |
|
---|
16 | #define MAINPROG 1
|
---|
17 |
|
---|
18 | #include "stdio.h"
|
---|
19 |
|
---|
20 | #ifdef VAX
|
---|
21 | #include "sys/time.h"
|
---|
22 | #else VAX
|
---|
23 | #include "time.h"
|
---|
24 | #endif VAX
|
---|
25 |
|
---|
26 | #include "math.h"
|
---|
27 |
|
---|
28 | #define EPOCH 1985
|
---|
29 | #define EPSILONg 279.611371 /* solar ecliptic long at EPOCH */
|
---|
30 | #define RHOg 282.680403 /* solar ecliptic long of perigee at EPOCH */
|
---|
31 | #define e 0.01671542 /* solar orbit eccentricity */
|
---|
32 | #define lzero 18.251907 /* lunar mean long at EPOCH */
|
---|
33 | #define Pzero 192.917585 /* lunar mean long of perigee at EPOCH */
|
---|
34 | #define Nzero 55.204723 /* lunar mean long of node at EPOCH */
|
---|
35 |
|
---|
36 | #ifndef PI
|
---|
37 | #define PI 3.141592654
|
---|
38 | #endif
|
---|
39 |
|
---|
40 | int
|
---|
41 | ly(yr)
|
---|
42 | int yr;
|
---|
43 | {
|
---|
44 | /* returns 1 if leapyear, 0 otherwise */
|
---|
45 |
|
---|
46 | return (yr % 4 == 0 && yr % 100 != 0 || yr % 400 == 0);
|
---|
47 | }
|
---|
48 |
|
---|
49 | double
|
---|
50 | dtor(deg)
|
---|
51 | double deg;
|
---|
52 | {
|
---|
53 | /* convert degrees to radians */
|
---|
54 |
|
---|
55 | return (deg * PI / 180);
|
---|
56 | }
|
---|
57 |
|
---|
58 | double
|
---|
59 | adj360(deg)
|
---|
60 | double *deg;
|
---|
61 | {
|
---|
62 | /* adjust value so 0 <= deg <= 360 */
|
---|
63 |
|
---|
64 | do {
|
---|
65 |
|
---|
66 | if (*deg < 0)
|
---|
67 | *deg += 360;
|
---|
68 | else if (*deg > 360)
|
---|
69 | *deg -= 360;
|
---|
70 |
|
---|
71 | } while (*deg < 0 || *deg > 360);
|
---|
72 | }
|
---|
73 |
|
---|
74 | double
|
---|
75 | potm(days)
|
---|
76 | double days;
|
---|
77 | {
|
---|
78 | double N;
|
---|
79 | double Msol;
|
---|
80 | double Ec;
|
---|
81 | double LambdaSol;
|
---|
82 | double l;
|
---|
83 | double Mm;
|
---|
84 | double Ev;
|
---|
85 | double Ac;
|
---|
86 | double A3;
|
---|
87 | double Mmprime;
|
---|
88 | double A4;
|
---|
89 | double lprime;
|
---|
90 | double V;
|
---|
91 | double ldprime;
|
---|
92 | double D;
|
---|
93 | double Nm;
|
---|
94 |
|
---|
95 | N = 360 * days / 365.2422; /* sec 42 #3 */
|
---|
96 | adj360(&N);
|
---|
97 |
|
---|
98 | Msol = N + EPSILONg - RHOg; /* sec 42 #4 */
|
---|
99 | adj360(&Msol);
|
---|
100 |
|
---|
101 | Ec = 360 / PI * e * sin(dtor(Msol)); /* sec 42 #5 */
|
---|
102 |
|
---|
103 | LambdaSol = N + Ec + EPSILONg; /* sec 42 #6 */
|
---|
104 | adj360(&LambdaSol);
|
---|
105 |
|
---|
106 | l = 13.1763966 * days + lzero; /* sec 61 #4 */
|
---|
107 | adj360(&l);
|
---|
108 |
|
---|
109 | Mm = l - (0.1114041 * days) - Pzero; /* sec 61 #5 */
|
---|
110 | adj360(&Mm);
|
---|
111 |
|
---|
112 | Nm = Nzero - (0.0529539 * days); /* sec 61 #6 */
|
---|
113 | adj360(&Nm);
|
---|
114 |
|
---|
115 | Ev = 1.2739 * sin(dtor(2*(l - LambdaSol) - Mm)); /* sec 61 #7 */
|
---|
116 |
|
---|
117 | Ac = 0.1858 * sin(dtor(Msol)); /* sec 61 #8 */
|
---|
118 | A3 = 0.37 * sin(dtor(Msol));
|
---|
119 |
|
---|
120 | Mmprime = Mm + Ev - Ac - A3; /* sec 61 #9 */
|
---|
121 |
|
---|
122 | Ec = 6.2886 * sin(dtor(Mmprime)); /* sec 61 #10 */
|
---|
123 |
|
---|
124 | A4 = 0.214 * sin(dtor(2 * Mmprime)); /* sec 61 #11 */
|
---|
125 |
|
---|
126 | lprime = l + Ev + Ec - Ac + A4; /* sec 61 #12 */
|
---|
127 |
|
---|
128 | V = 0.6583 * sin(dtor(2 * (lprime - LambdaSol))); /* sec 61 #13 */
|
---|
129 |
|
---|
130 | ldprime = lprime + V; /* sec 61 #14 */
|
---|
131 |
|
---|
132 | D = ldprime - LambdaSol; /* sec 63 #2 */
|
---|
133 |
|
---|
134 | return(50 * (1 - cos(dtor(D)))); /* sec 63 #3 */
|
---|
135 | }
|
---|
136 |
|
---|
137 | moontxt(buf)
|
---|
138 | char buf[];
|
---|
139 | {
|
---|
140 | char *cp = buf;
|
---|
141 | long *lo; /* used by time calls */
|
---|
142 | long curtime;
|
---|
143 | double days; /* days since EPOCH */
|
---|
144 | double phase; /* percent of lunar surface illuminated */
|
---|
145 | double phase2; /* percent of lunar surface illuminated one day later */
|
---|
146 | int i = EPOCH;
|
---|
147 | struct tm *pt; /* ptr to time structure */
|
---|
148 |
|
---|
149 | lo = &curtime;
|
---|
150 | time(lo); /* get system time */
|
---|
151 | pt = gmtime(lo); /* get ptr to gmt time struct */
|
---|
152 |
|
---|
153 | /* calculate days since EPOCH */
|
---|
154 |
|
---|
155 | days = (pt->tm_yday +1) + ((pt->tm_hour + (pt->tm_min / 60.0)
|
---|
156 | + (pt->tm_sec / 3600.0)) / 24.0);
|
---|
157 |
|
---|
158 | while (i < pt->tm_year + 1900)
|
---|
159 | days = days + 365 + ly(i++);
|
---|
160 |
|
---|
161 | phase = potm(days);
|
---|
162 | sprintf(cp,"The Moon is ");
|
---|
163 | cp += strlen(buf);
|
---|
164 |
|
---|
165 | if ((int)(phase + .5) == 100)
|
---|
166 | sprintf(cp,"Full");
|
---|
167 | else if ((int)(phase + 0.5) == 0)
|
---|
168 | sprintf(cp,"New");
|
---|
169 | else if ((int)(phase + 0.5) == 50) {
|
---|
170 |
|
---|
171 | phase2 = potm(++days);
|
---|
172 |
|
---|
173 | if (phase2 > phase)
|
---|
174 | sprintf(cp,"at the First Quarter");
|
---|
175 | else
|
---|
176 | sprintf(cp,"at the Last Quarter");
|
---|
177 |
|
---|
178 | } else if ((int)(phase + 0.5) > 50) {
|
---|
179 |
|
---|
180 | phase2 = potm(++days);
|
---|
181 |
|
---|
182 | if (phase2 > phase)
|
---|
183 | sprintf(cp,"Waxing ");
|
---|
184 | else
|
---|
185 | sprintf(cp,"Waning ");
|
---|
186 |
|
---|
187 | cp = buf + strlen(buf);
|
---|
188 | sprintf(cp,"Gibbous (%1.0f%% of Full)", phase);
|
---|
189 |
|
---|
190 | } else if ((int)(phase + 0.5) < 50) {
|
---|
191 |
|
---|
192 | phase2 = potm(++days);
|
---|
193 |
|
---|
194 | if (phase2 > phase)
|
---|
195 | sprintf(cp,"Waxing ");
|
---|
196 | else
|
---|
197 | sprintf(cp,"Waning ");
|
---|
198 |
|
---|
199 | cp = buf + strlen(buf);
|
---|
200 | sprintf(cp,"Crescent (%1.0f%% of Full)", phase);
|
---|
201 | }
|
---|
202 | }
|
---|
203 |
|
---|
204 | #if MAINPROG
|
---|
205 |
|
---|
206 | char mstring[128];
|
---|
207 |
|
---|
208 | main()
|
---|
209 | {
|
---|
210 | long curtime;
|
---|
211 |
|
---|
212 | moontxt(mstring);
|
---|
213 | time(&curtime);
|
---|
214 |
|
---|
215 | printf("%s", ctime(&curtime));
|
---|
216 | printf("%s\n", mstring);
|
---|
217 | }
|
---|
218 |
|
---|
219 | #endif
|
---|