home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume39 / remind / patch09d < prev    next >
Encoding:
Text File  |  1993-10-04  |  24.3 KB  |  686 lines

  1. Newsgroups: comp.sources.misc
  2. From: dfs@doe.carleton.ca (David F. Skoll)
  3. Subject: v39i118:  remind - A replacement for calendar, Patch09d/4
  4. Message-ID: <1993Oct4.204013.8220@sparky.sterling.com>
  5. X-Md4-Signature: bc2071672c4bbe2241298bea3dc0f5c3
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Dept. of Electronics, Carleton University
  8. Date: Mon, 4 Oct 1993 20:40:13 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: dfs@doe.carleton.ca (David F. Skoll)
  12. Posting-number: Volume 39, Issue 118
  13. Archive-name: remind/patch09d
  14. Environment: UNIX, MS-DOS, OS/2
  15. Patch-To: remind: Volume 33, Issue 58-69
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # Contents:  moon.c
  22. # Wrapped by kent@sparky on Mon Oct  4 15:03:31 1993
  23. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 4 (of 4)."'
  26. if test -f 'moon.c' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'moon.c'\"
  28. else
  29.   echo shar: Extracting \"'moon.c'\" \(22461 characters\)
  30.   sed "s/^X//" >'moon.c' <<'END_OF_FILE'
  31. X/***************************************************************/
  32. X/*                                                             */
  33. X/*  MOON.C                                                     */
  34. X/*                                                             */
  35. X/*  Calculations for figuring out moon phases.                 */
  36. X/*                                                             */
  37. X/*  This file is part of REMIND.                               */
  38. X/*  Copyright (C) 1992, 1993 by David F. Skoll.                */
  39. X/*                                                             */
  40. X/***************************************************************/
  41. X
  42. X/* All of these routines were adapted from the program "moontool"
  43. X   by John Walker, February 1988.  Here's the blurb from moontool:
  44. X
  45. X   ... The information is generally accurate to within ten
  46. X   minutes.
  47. X
  48. X   The algorithms used in this program to calculate the positions Sun and
  49. X   Moon as seen from the Earth are given in the book "Practical Astronomy
  50. X   With Your Calculator" by Peter Duffett-Smith, Second Edition,
  51. X   Cambridge University Press, 1981. Ignore the word "Calculator" in the
  52. X   title; this is an essential reference if you're interested in
  53. X   developing software which calculates planetary positions, orbits,
  54. X   eclipses, and the like. If you're interested in pursuing such
  55. X   programming, you should also obtain:
  56. X
  57. X   "Astronomical Formulae for Calculators" by Jean Meeus, Third Edition,
  58. X   Willmann-Bell, 1985. A must-have.
  59. X
  60. X   "Planetary Programs and Tables from -4000 to +2800" by Pierre
  61. X   Bretagnon and Jean-Louis Simon, Willmann-Bell, 1986. If you want the
  62. X   utmost (outside of JPL) accuracy for the planets, it's here.
  63. X
  64. X   "Celestial BASIC" by Eric Burgess, Revised Edition, Sybex, 1985. Very
  65. X   cookbook oriented, and many of the algorithms are hard to dig out of
  66. X   the turgid BASIC code, but you'll probably want it anyway.
  67. X
  68. X   Many of these references can be obtained from Willmann-Bell, P.O. Box
  69. X   35025, Richmond, VA 23235, USA. Phone: (804) 320-7016. In addition
  70. X   to their own publications, they stock most of the standard references
  71. X   for mathematical and positional astronomy.
  72. X
  73. X   This program was written by:
  74. X
  75. X      John Walker
  76. X      Autodesk, Inc.
  77. X      2320 Marinship Way
  78. X      Sausalito, CA 94965
  79. X      (415) 332-2344 Ext. 829
  80. X
  81. X      Usenet: {sun!well}!acad!kelvin
  82. X
  83. X   This program is in the public domain: "Do what thou wilt shall be the
  84. X   whole of the law". I'd appreciate receiving any bug fixes and/or
  85. X   enhancements, which I'll incorporate in future versions of the
  86. X   program. Please leave the original attribution information intact so
  87. X   that credit and blame may be properly apportioned.
  88. X
  89. X*/
  90. X#include "config.h"
  91. X#ifdef HAVE_STDLIB_H
  92. X#include <stdlib.h>
  93. X#endif
  94. X#include <stdio.h>
  95. X#include <math.h>
  96. X#include <time.h>
  97. X#include "types.h"
  98. X#include "protos.h"
  99. X#include "expr.h"
  100. X#include "globals.h"
  101. X#include "err.h"
  102. X
  103. X/* Function prototypes */
  104. XPRIVATE long jdate ARGS((int y, int mon, int day));
  105. XPRIVATE double jtime ARGS((int y, int mon, int day, int hour, int min, int sec));
  106. XPRIVATE void jyear ARGS((double td, int *yy, int *mm, int *dd));
  107. XPRIVATE void jhms ARGS((double j, int *h, int *m, int *s));
  108. XPRIVATE double meanphase ARGS((double sdate, double phase, double *usek));
  109. XPRIVATE double truephase ARGS((double k, double phase));
  110. XPRIVATE double kepler ARGS((double m, double ecc));
  111. XPRIVATE double phase ARGS((double, double *, double *, double *, double *, double *, double *));
  112. X
  113. X
  114. X/*  Astronomical constants  */
  115. X
  116. X#define epoch        2444238.5       /* 1980 January 0.0 */
  117. X
  118. X/*  Constants defining the Sun's apparent orbit  */
  119. X
  120. X#define elonge        278.833540       /* Ecliptic longitude of the Sun
  121. X                      at epoch 1980.0 */
  122. X#define elongp        282.596403       /* Ecliptic longitude of the Sun at
  123. X                      perigee */
  124. X#define eccent      0.016718       /* Eccentricity of Earth's orbit */
  125. X#define sunsmax     1.495985e8     /* Semi-major axis of Earth's orbit, km */
  126. X#define sunangsiz   0.533128       /* Sun's angular size, degrees, at
  127. X                      semi-major axis distance */
  128. X
  129. X/*  Elements of the Moon's orbit, epoch 1980.0  */
  130. X
  131. X#define mmlong      64.975464      /* Moon's mean lonigitude at the epoch */
  132. X#define mmlongp     349.383063       /* Mean longitude of the perigee at the
  133. X                      epoch */
  134. X#define mlnode        151.950429       /* Mean longitude of the node at the
  135. X                      epoch */
  136. X#define minc        5.145396       /* Inclination of the Moon's orbit */
  137. X#define mecc        0.054900       /* Eccentricity of the Moon's orbit */
  138. X#define mangsiz     0.5181         /* Moon's angular size at distance a
  139. X                      from Earth */
  140. X#define msmax       384401.0       /* Semi-major axis of Moon's orbit in km */
  141. X#define mparallax   0.9507       /* Parallax at distance a from Earth */
  142. X#define synmonth    29.53058868    /* Synodic month (new Moon to new Moon) */
  143. X#define lunatbase   2423436.0      /* Base date for E. W. Brown's numbered
  144. X                      series of lunations (1923 January 16) */
  145. X
  146. X/*  Properties of the Earth  */
  147. X
  148. X#define earthrad    6378.16       /* Radius of Earth in kilometres */
  149. X
  150. X#define PI 3.14159265358979323846
  151. X
  152. X/*  Handy mathematical functions  */
  153. X
  154. X#ifdef sgn
  155. X#undef sgn
  156. X#endif
  157. X#define sgn(x) (((x) < 0) ? -1 : ((x) > 0 ? 1 : 0))      /* Extract sign */
  158. X
  159. X#ifdef abs
  160. X#undef abs
  161. X#endif
  162. X#define abs(x) ((x) < 0 ? (-(x)) : (x))           /* Absolute val */
  163. X
  164. X#define fixangle(a) ((a) - 360.0 * (floor((a) / 360.0)))  /* Fix angle      */
  165. X#define torad(d) ((d) * (PI / 180.0))              /* Deg->Rad      */
  166. X#define todeg(d) ((d) * (180.0 / PI))              /* Rad->Deg      */
  167. X#define dsin(x) (sin(torad((x))))              /* Sin from deg */
  168. X#define dcos(x) (cos(torad((x))))              /* Cos from deg */
  169. X
  170. X/***************************************************************/
  171. X/*                                                             */
  172. X/*  jdate                                                      */
  173. X/*                                                             */
  174. X/*  Convert a date and time to Julian day and fraction.        */
  175. X/*                                                             */
  176. X/***************************************************************/
  177. X#ifdef HAVE_PROTOS
  178. XPRIVATE long jdate(int y, int mon, int day)
  179. X#else
  180. Xstatic long jdate(y, mon, day)
  181. Xint y, mon, day;
  182. X#endif
  183. X{
  184. X   long c, m;
  185. X
  186. X   m = mon+1;
  187. X   if (m>2) {
  188. X      m -= 3;
  189. X   } else {
  190. X      m += 9;
  191. X      y--;
  192. X   }
  193. X   c = y/100L;   /* Century */
  194. X   y -= 100L * c;
  195. X   return day + (c*146097L)/4 + (y*1461L)/4 + (m*153L+2)/5 + 1721119L;
  196. X}
  197. X
  198. X/***************************************************************/
  199. X/*                                                             */
  200. X/*  jtime                                                      */
  201. X/*                                                             */
  202. X/*  Convert a GMT date and time to astronomical Julian time,   */
  203. X/*  i.e. Julian date plus day fraction, expressed as a double  */
  204. X/*                                                             */
  205. X/***************************************************************/
  206. X#ifdef HAVE_PROTOS
  207. XPRIVATE double jtime(int y, int mon, int day, int hour, int min, int sec)
  208. X#else
  209. Xstatic double jtime(y, mon, day, hour, min, sec)
  210. Xint y, mon, day, hour, min, sec;
  211. X#endif
  212. X{
  213. X   return (jdate(y, mon, day)-0.5) +
  214. X             (sec + 60L * (long) min + 3600L * (long) hour) / 86400.0;
  215. X}
  216. X
  217. X/***************************************************************/
  218. X/*                                                             */
  219. X/*  jyear                                                      */
  220. X/*                                                             */
  221. X/*  Convert a Julian date to year, month, day.                 */
  222. X/*                                                             */
  223. X/***************************************************************/
  224. X#ifdef HAVE_PROTOS
  225. XPRIVATE void jyear(double td, int *yy, int *mm, int *dd)
  226. X#else
  227. Xstatic void jyear(td, yy, mm, dd)
  228. Xdouble td;
  229. Xint *yy, *mm, *dd;
  230. X#endif
  231. X{
  232. X   double j, d, y, m;
  233. X
  234. X   td += 0.5;         /* Astronomical to civil */
  235. X   j = floor(td);
  236. X   j = j - 1721119.0;
  237. X   y = floor(((4 * j) - 1) / 146097.0);
  238. X   j = (j * 4.0) - (1.0 + (146097.0 * y));
  239. X   d = floor(j / 4.0);
  240. X   j = floor(((4.0 * d) + 3.0) / 1461.0);
  241. X   d = ((4.0 * d) + 3.0) - (1461.0 * j);
  242. X   d = floor((d + 4.0) / 4.0);
  243. X   m = floor(((5.0 * d) - 3) / 153.0);
  244. X   d = (5.0 * d) - (3.0 + (153.0 * m));
  245. X   d = floor((d + 5.0) / 5.0);
  246. X   y = (100.0 * y) + j;
  247. X   if (m < 10.0)
  248. X      m = m + 2;
  249. X   else {
  250. X      m = m - 10;
  251. X      y = y + 1;
  252. X   }
  253. X   *yy = y;
  254. X   *mm = m;
  255. X   *dd = d;
  256. X}
  257. X
  258. X/***************************************************************/
  259. X/*                                                             */
  260. X/*  jhms                                                       */
  261. X/*                                                             */
  262. X/*  Convert a Julian time to hour, minutes and seconds.        */
  263. X/*                                                             */
  264. X/***************************************************************/
  265. X#ifdef HAVE_PROTOS
  266. XPRIVATE void jhms(double j, int *h, int *m, int *s)
  267. X#else
  268. Xstatic void jhms(j, h, m, s)
  269. Xdouble j;
  270. Xint *h, *m, *s;
  271. X#endif
  272. X{
  273. X   long ij;
  274. X
  275. X   j += 0.5;         /* Astronomical to civil */
  276. X   ij = (j - floor(j)) * 86400.0;
  277. X   *h = ij / 3600L;
  278. X   *m = (ij / 60L) % 60L;
  279. X   *s = ij % 60L;
  280. X}
  281. X
  282. X/***************************************************************/
  283. X/*                                                             */
  284. X/*  meanphase                                                  */
  285. X/*                                                             */
  286. X/*  Calculates mean phase of the Moon for a                    */
  287. X/*  given base date and desired phase:                   */
  288. X/*     0.0   New Moon                           */
  289. X/*     0.25  First quarter                       */
  290. X/*     0.5   Full moon                           */
  291. X/*     0.75  Last quarter                       */
  292. X/*  Beware!!!  This routine returns meaningless               */
  293. X/*  results for any other phase arguments.  Don't           */
  294. X/*  attempt to generalise it without understanding           */
  295. X/*  that the motion of the moon is far more complicated           */
  296. X/*  than this calculation reveals.                   */
  297. X/*                                                             */
  298. X/***************************************************************/
  299. X#ifdef HAVE_PROTOS
  300. XPRIVATE double meanphase(double sdate, double phase, double *usek)
  301. X#else
  302. Xstatic double meanphase(sdate, phase, usek)
  303. Xdouble sdate, phase;
  304. Xdouble *usek;
  305. X#endif
  306. X{
  307. X   int yy, mm, dd;
  308. X   double k, t, t2, t3, nt1;
  309. X
  310. X   jyear(sdate, &yy, &mm, &dd);
  311. X
  312. X   k = (yy + ((mm - 1) * (1.0 / 12.0)) - 1900) * 12.3685;
  313. X
  314. X   /* Time in Julian centuries from 1900 January 0.5 */
  315. X   t = (sdate - 2415020.0) / 36525;
  316. X   t2 = t * t;           /* Square for frequent use */
  317. X   t3 = t2 * t;           /* Cube for frequent use */
  318. X
  319. X   *usek = k = floor(k) + phase;
  320. X   nt1 = 2415020.75933 + synmonth * k
  321. X         + 0.0001178 * t2
  322. X         - 0.000000155 * t3
  323. X         + 0.00033 * dsin(166.56 + 132.87 * t - 0.009173 * t2);
  324. X
  325. X   return nt1;
  326. X}
  327. X
  328. X/***************************************************************/
  329. X/*                                                             */
  330. X/*  truephase                                                  */
  331. X/*                                                             */
  332. X/*  Given a K value used to determine the                      */
  333. X/*  mean phase of the new moon, and a phase                    */
  334. X/*  selector (0.0, 0.25, 0.5, 0.75), obtain                    */
  335. X/*  the true, corrected phase time.                            */
  336. X/*                                                             */
  337. X/***************************************************************/
  338. X#ifdef HAVE_PROTOS
  339. XPRIVATE double truephase(double k, double phase)
  340. X#else
  341. Xstatic double truephase(k, phase)
  342. Xdouble k, phase;
  343. X#endif
  344. X{
  345. X   double t, t2, t3, pt, m, mprime, f;
  346. X   int apcor = 0;
  347. X
  348. X   k += phase;           /* Add phase to new moon time */
  349. X   t = k / 1236.85;       /* Time in Julian centuries from
  350. X                     1900 January 0.5 */
  351. X   t2 = t * t;           /* Square for frequent use */
  352. X   t3 = t2 * t;           /* Cube for frequent use */
  353. X   pt = 2415020.75933       /* Mean time of phase */
  354. X        + synmonth * k
  355. X        + 0.0001178 * t2
  356. X        - 0.000000155 * t3
  357. X        + 0.00033 * dsin(166.56 + 132.87 * t - 0.009173 * t2);
  358. X
  359. X        m = 359.2242               /* Sun's mean anomaly */
  360. X       + 29.10535608 * k
  361. X       - 0.0000333 * t2
  362. X       - 0.00000347 * t3;
  363. X        mprime = 306.0253          /* Moon's mean anomaly */
  364. X       + 385.81691806 * k
  365. X       + 0.0107306 * t2
  366. X       + 0.00001236 * t3;
  367. X        f = 21.2964                /* Moon's argument of latitude */
  368. X       + 390.67050646 * k
  369. X       - 0.0016528 * t2
  370. X       - 0.00000239 * t3;
  371. X   if ((phase < 0.01) || (abs(phase - 0.5) < 0.01)) {
  372. X
  373. X      /* Corrections for New and Full Moon */
  374. X
  375. X      pt +=     (0.1734 - 0.000393 * t) * dsin(m)
  376. X           + 0.0021 * dsin(2 * m)
  377. X           - 0.4068 * dsin(mprime)
  378. X           + 0.0161 * dsin(2 * mprime)
  379. X           - 0.0004 * dsin(3 * mprime)
  380. X           + 0.0104 * dsin(2 * f)
  381. X           - 0.0051 * dsin(m + mprime)
  382. X           - 0.0074 * dsin(m - mprime)
  383. X           + 0.0004 * dsin(2 * f + m)
  384. X           - 0.0004 * dsin(2 * f - m)
  385. X           - 0.0006 * dsin(2 * f + mprime)
  386. X           + 0.0010 * dsin(2 * f - mprime)
  387. X           + 0.0005 * dsin(m + 2 * mprime);
  388. X      apcor = 1;
  389. X   } else if ((abs(phase - 0.25) < 0.01 || (abs(phase - 0.75) < 0.01))) {
  390. X      pt +=     (0.1721 - 0.0004 * t) * dsin(m)
  391. X           + 0.0021 * dsin(2 * m)
  392. X           - 0.6280 * dsin(mprime)
  393. X           + 0.0089 * dsin(2 * mprime)
  394. X           - 0.0004 * dsin(3 * mprime)
  395. X           + 0.0079 * dsin(2 * f)
  396. X           - 0.0119 * dsin(m + mprime)
  397. X           - 0.0047 * dsin(m - mprime)
  398. X           + 0.0003 * dsin(2 * f + m)
  399. X           - 0.0004 * dsin(2 * f - m)
  400. X           - 0.0006 * dsin(2 * f + mprime)
  401. X           + 0.0021 * dsin(2 * f - mprime)
  402. X           + 0.0003 * dsin(m + 2 * mprime)
  403. X           + 0.0004 * dsin(m - 2 * mprime)
  404. X           - 0.0003 * dsin(2 * m + mprime);
  405. X      if (phase < 0.5)
  406. X         /* First quarter correction */
  407. X         pt += 0.0028 - 0.0004 * dcos(m) + 0.0003 * dcos(mprime);
  408. X      else
  409. X         /* Last quarter correction */
  410. X         pt += -0.0028 + 0.0004 * dcos(m) - 0.0003 * dcos(mprime);
  411. X      apcor = 1;
  412. X   }
  413. X   if (!apcor) return 0.0;
  414. X   return pt;
  415. X}
  416. X
  417. X/***************************************************************/
  418. X/*                                                             */
  419. X/*  kepler                                                     */
  420. X/*                                                             */
  421. X/*  Solve the equation of Kepler.                              */
  422. X/*                                                             */
  423. X/***************************************************************/
  424. X#ifdef HAVE_PROTOS
  425. XPRIVATE double kepler(double m, double ecc)
  426. X#else
  427. Xstatic double kepler(m, ecc)
  428. Xdouble m, ecc;
  429. X#endif
  430. X{
  431. X   double e, delta;
  432. X#define EPSILON 1E-6
  433. X
  434. X   e = m = torad(m);
  435. X   do {
  436. X      delta = e - ecc * sin(e) - m;
  437. X      e -= delta / (1 - ecc * cos(e));
  438. X   } while (abs(delta) > EPSILON);
  439. X   return e;
  440. X}
  441. X/***************************************************************/
  442. X/*                                                             */
  443. X/*  PHASE  --  Calculate phase of moon as a fraction:          */
  444. X/*                                                             */
  445. X/*   The argument is the time for which the phase is              */
  446. X/*   Requested, expressed as a Julian date and               */
  447. X/*   fraction.  Returns the terminator phase angle as a           */
  448. X/*   percentage of a full circle (i.e., 0 to 1), and           */
  449. X/*   stores into pointer arguments the illuminated           */
  450. X/*   fraction of the Moon's disc, the Moon's age in           */
  451. X/*   days and fraction, the distance of the Moon from           */
  452. X/*   the centre of the Earth, and the angular diameter           */
  453. X/*   subtended by the Moon as seen by an observer at           */
  454. X/*   the centre of the Earth.                       */
  455. X/*                                                             */
  456. X/***************************************************************/
  457. X#ifdef HAVE_PROTOS
  458. XPRIVATE double phase(double pdate,
  459. X                 double *pphase,
  460. X             double *mage,
  461. X             double *dist,
  462. X             double *angdia,
  463. X             double *sudist,
  464. X             double *suangdia)
  465. X#else
  466. Xstatic double phase(pdate, pphase, mage, dist, angdia, sudist, suangdia)
  467. Xdouble pdate;
  468. Xdouble *pphase;            /* Illuminated fraction */
  469. Xdouble *mage;               /* Age of moon in days */
  470. Xdouble *dist;               /* Distance in kilometres */
  471. Xdouble *angdia;            /* Angular diameter in degrees */
  472. Xdouble *sudist;            /* Distance to Sun */
  473. Xdouble *suangdia;                  /* Sun's angular diameter */
  474. X#endif
  475. X{
  476. X
  477. X   double Day, N, M, Ec, Lambdasun, ml, MM, MN, Ev, Ae, A3, MmP,
  478. X          mEc, A4, lP, V, lPP, NP, y, x, Lambdamoon,
  479. X          MoonAge, MoonPhase,
  480. X          MoonDist, MoonDFrac, MoonAng,
  481. X          F, SunDist, SunAng;
  482. X
  483. X        /* Calculation of the Sun's position */
  484. X
  485. X   Day = pdate - epoch;        /* Date within epoch */
  486. X   N = fixangle((360 / 365.2422) * Day); /* Mean anomaly of the Sun */
  487. X   M = fixangle(N + elonge - elongp);    /* Convert from perigee
  488. X                      co-ordinates to epoch 1980.0 */
  489. X   Ec = kepler(M, eccent);     /* Solve equation of Kepler */
  490. X   Ec = sqrt((1 + eccent) / (1 - eccent)) * tan(Ec / 2);
  491. X   Ec = 2 * todeg(atan(Ec));   /* 1 anomaly */
  492. X   Lambdasun = fixangle(Ec + elongp);  /* Sun's geocentric ecliptic
  493. X                          longitude */
  494. X   /* Orbital distance factor */
  495. X   F = ((1 + eccent * cos(torad(Ec))) / (1 - eccent * eccent));
  496. X   SunDist = sunsmax / F;        /* Distance to Sun in km */
  497. X        SunAng = F * sunangsiz;     /* Sun's angular size in degrees */
  498. X
  499. X
  500. X        /* Calculation of the Moon's position */
  501. X
  502. X        /* Moon's mean longitude */
  503. X   ml = fixangle(13.1763966 * Day + mmlong);
  504. X
  505. X        /* Moon's mean anomaly */
  506. X   MM = fixangle(ml - 0.1114041 * Day - mmlongp);
  507. X
  508. X        /* Moon's ascending node mean longitude */
  509. X   MN = fixangle(mlnode - 0.0529539 * Day);
  510. X
  511. X   /* Evection */
  512. X   Ev = 1.2739 * sin(torad(2 * (ml - Lambdasun) - MM));
  513. X
  514. X   /* Annual equation */
  515. X   Ae = 0.1858 * sin(torad(M));
  516. X
  517. X   /* Correction term */
  518. X   A3 = 0.37 * sin(torad(M));
  519. X
  520. X   /* Corrected anomaly */
  521. X   MmP = MM + Ev - Ae - A3;
  522. X
  523. X   /* Correction for the equation of the centre */
  524. X   mEc = 6.2886 * sin(torad(MmP));
  525. X
  526. X   /* Another correction term */
  527. X   A4 = 0.214 * sin(torad(2 * MmP));
  528. X
  529. X   /* Corrected longitude */
  530. X   lP = ml + Ev + mEc - Ae + A4;
  531. X
  532. X   /* Variation */
  533. X   V = 0.6583 * sin(torad(2 * (lP - Lambdasun)));
  534. X
  535. X   /* 1 longitude */
  536. X   lPP = lP + V;
  537. X
  538. X   /* Corrected longitude of the node */
  539. X   NP = MN - 0.16 * sin(torad(M));
  540. X
  541. X   /* Y inclination coordinate */
  542. X   y = sin(torad(lPP - NP)) * cos(torad(minc));
  543. X
  544. X   /* X inclination coordinate */
  545. X   x = cos(torad(lPP - NP));
  546. X
  547. X   /* Ecliptic longitude */
  548. X   Lambdamoon = todeg(atan2(y, x));
  549. X   Lambdamoon += NP;
  550. X
  551. X   /* Calculation of the phase of the Moon */
  552. X
  553. X   /* Age of the Moon in degrees */
  554. X   MoonAge = lPP - Lambdasun;
  555. X
  556. X   /* Phase of the Moon */
  557. X   MoonPhase = (1 - cos(torad(MoonAge))) / 2;
  558. X
  559. X   /* Calculate distance of moon from the centre of the Earth */
  560. X
  561. X   MoonDist = (msmax * (1 - mecc * mecc)) /
  562. X      (1 + mecc * cos(torad(MmP + mEc)));
  563. X
  564. X        /* Calculate Moon's angular diameter */
  565. X
  566. X   MoonDFrac = MoonDist / msmax;
  567. X   MoonAng = mangsiz / MoonDFrac;
  568. X
  569. X   if(pphase)   *pphase = MoonPhase;
  570. X   if(mage)     *mage = synmonth * (fixangle(MoonAge) / 360.0);
  571. X   if(dist)     *dist = MoonDist;
  572. X   if(angdia)   *angdia = MoonAng;
  573. X   if(sudist)   *sudist = SunDist;
  574. X   if(suangdia) *suangdia = SunAng;
  575. X   return fixangle(MoonAge) / 360.0;
  576. X}
  577. X
  578. X/***************************************************************/
  579. X/*                                                             */
  580. X/*  MoonPhase                                                  */
  581. X/*                                                             */
  582. X/*  Interface routine dealing in Remind representations.       */
  583. X/*  Given a local date and time, returns the moon phase at     */
  584. X/*  that date and time as a number from 0 to 360.              */
  585. X/*                                                             */
  586. X/***************************************************************/
  587. X#ifdef HAVE_PROTOS
  588. XPUBLIC int MoonPhase(int date, int time)
  589. X#else
  590. Xint MoonPhase(date, time)
  591. Xint date, time;
  592. X#endif
  593. X{
  594. X   int utcd, utct;
  595. X   int y, m, d;
  596. X   double jd, mp;
  597. X
  598. X   /* Convert from local to UTC */
  599. X   LocalToUTC(date, time, &utcd, &utct);
  600. X
  601. X   /* Convert from Remind representation to year/mon/day */
  602. X   FromJulian(utcd, &y, &m, &d);
  603. X
  604. X   /* Convert to a true Julian date -- sorry for the name clashes! */
  605. X   jd = jtime(y, m, d, (utct / 60), (utct % 60), 0);   
  606. X
  607. X   /* Calculate moon phase */
  608. X   mp = 360.0 * phase(jd, NULL, NULL, NULL, NULL, NULL, NULL);
  609. X   return (int) mp;
  610. X}
  611. X
  612. X/***************************************************************/
  613. X/*                                                             */
  614. X/*  HuntPhase                                                  */
  615. X/*                                                             */
  616. X/*  Given a starting date and time and a target phase, find    */
  617. X/*  the first date on or after the starting date and time when */
  618. X/*  the moon hits the specified phase.  Phase must be from     */
  619. X/*  0 to 3 for new, 1stq, full, 3rdq                           */
  620. X/*                                                             */
  621. X/***************************************************************/
  622. X#ifdef HAVE_PROTOS
  623. XPUBLIC void HuntPhase(int startdate, int starttim, int phas, int *date, int *time)
  624. X#else
  625. Xvoid HuntPhase(startdate, starttim, phas, date, time)
  626. Xint startdate, starttim, phas, *date, *time;
  627. X#endif
  628. X{
  629. X   int utcd, utct;
  630. X   int y, m, d;
  631. X   int h, min, s;
  632. X   int d1, t1;
  633. X   double k1, k2, jd, jdorig;
  634. X   double nt1, nt2;
  635. X   /* Convert from local to UTC */
  636. X   LocalToUTC(startdate, starttim, &utcd, &utct);
  637. X
  638. X   /* Convert from Remind representation to year/mon/day */
  639. X   FromJulian(utcd, &y, &m, &d);
  640. X
  641. X   /* Convert to a true Julian date -- sorry for the name clashes! */
  642. X   jdorig = jtime(y, m, d, (utct / 60), (utct % 60), 0);   
  643. X   jd = jdorig - 45;
  644. X   nt1 = meanphase(jd, 0.0, &k1);
  645. X   while(1) {
  646. X      jd += synmonth;
  647. X      nt2 = meanphase(jd, 0.0, &k2);
  648. X      if (nt1 <= jdorig && nt2 > jdorig) break;
  649. X      nt1 = nt2;
  650. X      k1 = k2;
  651. X   }
  652. X   jd = truephase(k1, phas/4.0);
  653. X   if (jd < jdorig) jd = truephase(k2, phas/4.0);
  654. X
  655. X   /* Convert back to Remind format */
  656. X   jyear(jd, &y, &m, &d);
  657. X   jhms(jd, &h, &min, &s);
  658. X
  659. X   d1 = Julian(y, m, d);
  660. X   t1 = h*60 + min;
  661. X   UTCToLocal(d1, t1, date, time);
  662. X}
  663. END_OF_FILE
  664.   if test 22461 -ne `wc -c <'moon.c'`; then
  665.     echo shar: \"'moon.c'\" unpacked with wrong size!
  666.   fi
  667.   # end of 'moon.c'
  668. fi
  669. echo shar: End of archive 4 \(of 4\).
  670. cp /dev/null ark4isdone
  671. MISSING=""
  672. for I in 1 2 3 4 ; do
  673.     if test ! -f ark${I}isdone ; then
  674.     MISSING="${MISSING} ${I}"
  675.     fi
  676. done
  677. if test "${MISSING}" = "" ; then
  678.     echo You have unpacked all 4 archives.
  679.     rm -f ark[1-9]isdone
  680. else
  681.     echo You still must unpack the following archives:
  682.     echo "        " ${MISSING}
  683. fi
  684. exit 0
  685. exit 0 # Just in case...
  686.