[net.astro] Phase of the Moon from Unix time

slb@drutx.UUCP (Sue Brezden) (02/28/86)

>> I am looking for a routine that will return the phase of
>> the moon (in floating, a 0-28 integer, or  whatever) ...

>I'd like to have this code too.

Add me to the list.

-- 

                                     Sue Brezden
                                     ihnp4!drutx!slb

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      Nirvana?  That's a place where the powers that be and
      their friends hang out. 
                                       --Zonker Harris
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

paul@zoom.UUCP (20 Proprietor) (03/05/86)

koyaanisqatsi...koyaanisqatsi...koyaanisqatsi...koyaanisqatsi...koyaanisqatsi...

OK everybody (Doug Escher, Martin Minow, Chris Beekhuis, der Mouse, etc.)...
I feel that there has been sufficient interest in the Moon programs that I'm
posting them to this news group.  I hope everyone has fun with them.  I got
them orginally from the 'net some time ago - what group I don't remember --
probably `net.sources.games'.  At any rate, there are two programs here that
will give you information about our pal, the Moon.  `pom.c' actually draws a
little picture of the Moon on your screen.  `potm.c' just issues the English
version of the ("...first quarter", etc).  I had only a little trouble getting
them to run here on a 3b2/300 due to a small typecast (fixed) plus the need
for the `-f' flag in compiling.  The accuracy of these routines should, for
obvious reasons, not be used if you plan to go to the Moon, but it's close
enough for some purposes.  I have much more accurate routines (as mentioned
in an earlier posting) for ephemeride determination.  I'm currently trying
to negotiate a reasonable means for the distribution of these routines.  If
an interested party would be willing to trade my code for a long-term USENET
feed, I'd love to hear from you.  I'm really quite serious.
								Paul Ruel
A `shar' follows...
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	Makefile
#	moontx.c
#	moontx.h
#	pom.c
#	potm.c
echo shar: extracting Makefile
sed 's/^X//' << 'SHAR_EOF' > Makefile
X#
X#	Set `MATH' to `-f' if you need to force floating point emulation.
X#
XMATH =
Xall:	pom potm
Xpom:	pom.o
X	cc $(MATH) pom.o -lm -o pom;
Xpotm:	potm.o moontx.o
X	cc $(MATH) potm.o moontx.o -lm -o potm;
SHAR_EOF
echo shar: extracting moontx.c
sed 's/^X//' << 'SHAR_EOF' > moontx.c
X/****************************************************************************
X moon.c
X
X     Phase of the Moon. Calculates the current phase of the moon.
X     Based on routines from `Practical Astronomy with Your Calculator',
X        by Duffett-Smith.
X     Comments give the section from the book that particular piece
X        of code was adapted from.
X
X     -- Keith E. Brandt  VIII 1984
X
X ****************************************************************************/
X
X# include	"moontx.h"
X
Xmoontxt(buf)
Xchar	buf[];
X{
X    char *cp=buf;
X
Xdouble dtor();
Xdouble adj360();
Xdouble potm();
X
Xlong *lo = (long *) calloc (1, sizeof(long)); /* used by time calls */
Xstruct tm *pt; /* ptr to time structure */
X
Xdouble days;   /* days since EPOCH */
Xdouble phase;  /* percent of lunar surface illuminated */
Xdouble phase2; /* percent of lunar surface illuminated one day later */
Xint i = EPOCH;
X
Xtime (lo);  /* get system time */
Xpt = gmtime(lo);  /* get ptr to gmt time struct */
Xcfree(lo);
X
X/* calculate days since EPOCH */
Xdays = (pt->tm_yday +1) + ((pt->tm_hour + (pt->tm_min / 60.0)
X       + (pt->tm_sec / 3600.0)) / 24.0);
Xwhile (i < pt->tm_year + 1900)
X   days = days + 365 + ly(i++);
X
Xphase = potm(days);
Xsprintf(cp,"The Moon is ");
Xcp += strlen(buf);
Xif ((int)(phase + .5) == 100) {
X   sprintf(cp,"Full");
X   }
Xelse if ((int)(phase + 0.5) == 0) 
X   sprintf(cp,"New");
Xelse if ((int)(phase + 0.5) == 50)  {
X   phase2 = potm(++days);
X   if (phase2 > phase)
X      sprintf(cp,"at the First Quarter");
X   else 
X      sprintf(cp,"at the Last Quarter");
X   }
Xelse if ((int)(phase + 0.5) > 50) {
X   phase2 = potm(++days);
X   if (phase2 > phase)
X      sprintf(cp,"Waxing ");
X   else 
X      sprintf(cp,"Waning ");
X   cp = buf + strlen(buf);
X   sprintf(cp,"Gibbous (%1.0f%% of Full)", phase);
X   }
Xelse if ((int)(phase + 0.5) < 50) {
X   phase2 = potm(++days);
X   if (phase2 > phase)
X      sprintf(cp,"Waxing ");
X   else
X      sprintf(cp,"Waning ");
X   cp = buf + strlen(buf);
X   sprintf(cp,"Crescent (%1.0f%% of Full)", phase);
X   }
X}
X
Xdouble potm(days)
Xdouble days;
X{
Xdouble N;
Xdouble Msol;
Xdouble Ec;
Xdouble LambdaSol;
Xdouble l;
Xdouble Mm;
Xdouble Ev;
Xdouble Ac;
Xdouble A3;
Xdouble Mmprime;
Xdouble A4;
Xdouble lprime;
Xdouble V;
Xdouble ldprime;
Xdouble D;
Xdouble Nm;
X
XN = 360 * days / 365.2422;  /* sec 42 #3 */
Xadj360(&N);
X
XMsol = N + EPSILONg - RHOg; /* sec 42 #4 */
Xadj360(&Msol);
X
XEc = 360 / PI * e * sin(dtor(Msol)); /* sec 42 #5 */
X
XLambdaSol = N + Ec + EPSILONg;       /* sec 42 #6 */
Xadj360(&LambdaSol);
X
Xl = 13.1763966 * days + lzero;       /* sec 61 #4 */
Xadj360(&l);
X
XMm = l - (0.1114041 * days) - Pzero; /* sec 61 #5 */
Xadj360(&Mm);
X
XNm = Nzero - (0.0529539 * days);     /* sec 61 #6 */
Xadj360(&Nm);
X
XEv = 1.2739 * sin(dtor(2*(l - LambdaSol) - Mm)); /* sec 61 #7 */
X
XAc = 0.1858 * sin(dtor(Msol));       /* sec 61 #8 */
XA3 = 0.37 * sin(dtor(Msol));
X
XMmprime = Mm + Ev - Ac - A3;         /* sec 61 #9 */
X
XEc = 6.2886 * sin(dtor(Mmprime));    /* sec 61 #10 */
X
XA4 = 0.214 * sin(dtor(2 * Mmprime)); /* sec 61 #11 */
X
Xlprime = l + Ev + Ec - Ac + A4;      /* sec 61 #12 */
X
XV = 0.6583 * sin(dtor(2 * (lprime - LambdaSol))); /* sec 61 #13 */
X
Xldprime = lprime + V;                /* sec 61 #14 */
X
XD = ldprime - LambdaSol;             /* sec 63 #2 */
X
Xreturn (50 * (1 - cos(dtor(D))));    /* sec 63 #3 */
X}
X
Xly(yr)
Xint yr;
X{
X/* returns 1 if leapyear, 0 otherwise */
Xreturn (yr % 4 == 0 && yr % 100 != 0 || yr % 400 == 0);
X}
X
Xdouble dtor(deg)
Xdouble deg;
X{
X/* convert degrees to radians */
Xreturn (deg * PI / 180);
X}
X
Xdouble adj360(deg)
Xdouble *deg;
X{
X/* adjust value so 0 <= deg <= 360 */
Xdo if (*deg < 0)
X   *deg += 360;
Xelse if (*deg > 360)
X   *deg -= 360;
Xwhile (*deg < 0 || *deg > 360);
X}
SHAR_EOF
echo shar: extracting moontx.h
sed 's/^X//' << 'SHAR_EOF' > moontx.h
X# include	<stdio.h>
X#ifdef	VAX
X# include	<sys/time.h>
X#else	VAX
X# include	<time.h>
X#endif	VAX
X# include	<math.h>
X
X#define EPOCH   1985
X#define EPSILONg 279.611371     /* solar ecliptic long at EPOCH */
X#define RHOg     282.680403     /* solar ecliptic long of perigee at EPOCH */
X#define e          0.01671542   /* solar orbit eccentricity */
X#define lzero     18.251907     /* lunar mean long at EPOCH */
X#define Pzero    192.917585     /* lunar mean long of perigee at EPOCH */
X#define Nzero     55.204723     /* lunar mean long of node at EPOCH */
X
X# define	PI         3.141592654
SHAR_EOF
echo shar: extracting pom.c
sed 's/^X//' << 'SHAR_EOF' > pom.c
X/*$The phase of the moon, for your safety and convenience.
X**
X**  Stolen from ArchMach & converted from PL/I by Brian Hess.
X**  Extensively cleaned up by Rich $alz.
X**
X**  If you can figure out how this program works, then YOU deserve
X**  to be working on it, sucker!  Here's a hint:  The epoch is 13:23,
X**  10/1/78.
X*/
X
X
X#include <math.h>
X#include <sys/types.h>
X#include <time.h>
X
X
X/* Globals. */
Xlong		 Day;
Xlong		 Hour;
Xlong		 Minute;
Xdouble		 Fraction;
Xchar		*Moon[] =
X{
X    "new",
X    "first quarter of the",
X    "full moon",
X    "last quarter of the"
X};
X
X
X/* Linked in later. */
Xchar		*rindex();
Xtime_t		 time();
Xstruct tm	*localtime();
X
X
X#define LINES		24
X#define WIDTH		80
X#define CENTER		((WIDTH - 2 * LINES) / 2)
X#define BRIGHT		'@'
X#define LEDGE		'('
X#define REDGE		')'
X#define FULL		0.5
X#define TwoPi		(2 * 3.14159)
X#define ZERO		0.03
X
X#define Plural(X)	if (X != 1) printf("s");
X/*!*/
Xlong
XCalculate()
X{
X    register struct tm	*tm;
X    register long	 Length;
X    register long	 Phase;
X    register long	 DeltaH;
X    register long	 Delta;
X    register long	 offset;
X    time_t		 tick;
X    long		 julian;
X    long		 year;
X    long		 hour;
X    long		 minute;
X
X    tick	= time((time_t *)0);
X    tm		= localtime(&tick);
X    julian	= tm->tm_yday + 1;
X    year	= tm->tm_year - 78;
X    hour	= tm->tm_hour;
X    minute	= tm->tm_min;
X
X    Length	= (double)2551 / 60 * 1000 + (double)443 / 60;
X    offset	= ((year * 365L + julian) * 24L + hour) * 60L + minute;
X    Delta	= offset - (273L * 24L + 13L) * 60L + 23L;
X    Phase	= Delta - (Delta / Length) * Length;
X
X    Fraction	= (double)Phase / Length;
X
X    Length	= Length / 4;
X    Phase	= Phase / Length;
X    Delta	= Delta - (Delta / Length) * Length;
X    DeltaH	= Delta / 60;
X    Minute	= Delta - DeltaH * 60;
X    Day		= DeltaH / 24;
X    Hour	= DeltaH - Day * 24;
X    return(Phase);
X}
X/*!*/
Xint
XCharPos(x)
X    double		x;
X{
X    register int	i;
X
X    i = x * LINES + 0.5;
X    if ((i += LINES + CENTER) < 1)
X	i = 1;
X    return(i);
X}
X
X
Xvoid
XDraw()
X{
X    register char	*p;
X    register int	 i;
X    register int	 end;
X    register double	 y;
X    register double	 cht;
X    register double	 squisher;
X    register double	 horizon;
X    register double	 terminator;
X    char		 Buffer[256];
X
X    /* Clear screen? */
X
X    if (Fraction < FULL)
X	squisher = cos(TwoPi * Fraction);
X    else
X	squisher = cos(TwoPi * (Fraction - FULL));
X
X    cht = (double)2.0 / (LINES - 6.0);
X    for (y = 0.93; y > -1.0; y -= cht)
X    {
X	for (i = sizeof Buffer, p = Buffer; --i >= 0; )
X	    *p++ = ' ';
X	horizon = sqrt(1.0 - y * y);
X	Buffer[    CharPos(-horizon)]	= LEDGE;
X	Buffer[i = CharPos( horizon)]	= REDGE;
X	Buffer[++i]			= '\0';
X	terminator = horizon * squisher;
X	if (Fraction > ZERO && Fraction < (1.0 - ZERO))
X	{
X	    if (Fraction < FULL)
X	    {
X		i   = CharPos( terminator);
X		end = CharPos( horizon);
X	    }
X	    else
X	    {
X		i   = CharPos(-horizon);
X		end = CharPos( terminator);
X	    }
X	    while (i <= end)
X		Buffer[i++] = BRIGHT;
X	}
X	printf(" %s\n", Buffer);
X    }
X}
X/*!*/
Xmain(ac)
X    int			 ac;
X{
X    register long	 Phase;
X
X    Phase = Calculate();
X    if (ac == 1)
X	Draw();
X
X    printf("\nIt is ");
X    if (Day == 0 && Hour == 0 && Minute == 0)
X	printf("exactly");
X    else
X    {
X	if (Day)
X	{
X	    printf("%ld day", Day);
X	    Plural(Day);
X	    if (Hour | Day)
X		printf(", ");
X	}
X	if (Hour)
X	{
X	    printf("%ld hour", Hour);
X	    Plural(Hour);
X	    if (Minute)
X		printf(", ");
X	}
X	if (Minute)
X	{
X	    printf("%ld minute", Minute);
X	    Plural(Minute);
X	}
X	printf(" since");
X    }
X    printf(" the %s moon.\n", Moon[Phase]);
X
X    exit(0);
X}
SHAR_EOF
echo shar: extracting potm.c
sed 's/^X//' << 'SHAR_EOF' > potm.c
X/*
X**	<potm.c> --	Print out the phase of the moon ...
X**
X**	programmer:	John Dilley	(mordred:jad)
X**
X**	creation date:	Sat Feb  9 14:27
X**
X**
X**	modification history
X**
X*/
X
Xstatic	char	potm[64];
X
Xmain()
X{
X    moontxt(potm);
X    printf("Phase-of-the-Moon:%s\n", potm+11);
X}
SHAR_EOF
exit