[net.sources] phase of the moon

rs@mirror.UUCP (05/17/85)

The recent posting by Robert Bond with the sunrise/sunset
programs led me to dig out this old chestnut that had been
floating around MIT for a while.  It /seems/ correct to
me, but I ain't no "loup-garou" :-)

--------
Rich $alz	{ mit-eddie, ihnp4!inmet, wjh12, cca, datacube } ! mirror!rs
Mirror Systems
2067 Massachusetts Ave.			"I've seen this happen
Cambridge, MA, 02140			 in other people's lives
617-661-0777				 and now it's happening in mine."

# -----------------CUT HERE---------------------
#!/bin/sh
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by mirror!rs on Fri May 17 14:38:21 EDT 1985
# Contents:  pom.c
 
echo x - pom.c
sed 's/^XX//' > "pom.c" <<'@//E*O*F pom.c//'
XX/*$The phase of the moon, for your safety and convenience.
XX**
XX**  Stolen from ArchMach & converted from PL/I by Brian Hess.
XX**  Extensively cleaned up by Rich $alz.
XX**
XX**  If you can figure out how this program works, then YOU deserve
XX**  to be working on it, sucker!  Here's a hint:  The epoch is 13:23,
XX**  10/1/78.
XX*/


XX#include <math.h>
XX#include <sys/types.h>
XX#include <time.h>


XX/* Globals. */
XXlong		 Day;
XXlong		 Hour;
XXlong		 Minute;
XXdouble		 Fraction;
XXchar		*Moon[] =
XX{
XX    "new",
XX    "first quarter of the",
XX    "full moon",
XX    "last quarter of the"
XX};


XX/* Linked in later. */
XXchar		*rindex();
XXtime_t		 time();
XXstruct tm	*localtime();


XX#define LINES		24
XX#define WIDTH		80
XX#define CENTER		((WIDTH - 2 * LINES) / 2)
XX#define BRIGHT		'@'
XX#define LEDGE		'('
XX#define REDGE		')'
XX#define FULL		0.5
XX#define TwoPi		(2 * 3.14159)
XX#define ZERO		0.03

XX#define Plural(X)	if (X != 1) printf("s");
XX/*!*/
XXlong
XXCalculate()
XX{
XX    register struct tm	*tm;
XX    register long	 Length;
XX    register long	 Phase;
XX    register long	 DeltaH;
XX    register long	 Delta;
XX    register long	 offset;
XX    time_t		 tick;
XX    long		 julian;
XX    long		 year;
XX    long		 hour;
XX    long		 minute;

XX    tick	= time((time_t *)0);
XX    tm		= localtime(&tick);
XX    julian	= tm->tm_yday + 1;
XX    year	= tm->tm_year - 78;
XX    hour	= tm->tm_hour;
XX    minute	= tm->tm_min;

XX    Length	= (double)2551 / 60 * 1000 + (double)443 / 60;
XX    offset	= ((year * 365L + julian) * 24L + hour) * 60L + minute;
XX    Delta	= offset - (273L * 24L + 13L) * 60L + 23L;
XX    Phase	= Delta - (Delta / Length) * Length;

XX    Fraction	= Phase / Length;

XX    Length	= Length / 4;
XX    Phase	= Phase / Length;
XX    Delta	= Delta - (Delta / Length) * Length;
XX    DeltaH	= Delta / 60;
XX    Minute	= Delta - DeltaH * 60;
XX    Day		= DeltaH / 24;
XX    Hour	= DeltaH - Day * 24;
XX    return(Phase);
XX}
XX/*!*/
XXint
XXCharPos(x)
XX    double		x;
XX{
XX    register int	i;

XX    i = x * LINES + 0.5;
XX    if ((i += LINES + CENTER) < 1)
XX	i = 1;
XX    return(i);
XX}


XXvoid
XXDraw()
XX{
XX    register char	*p;
XX    register int	 i;
XX    register int	 end;
XX    register double	 y;
XX    register double	 cht;
XX    register double	 squisher;
XX    register double	 horizon;
XX    register double	 terminator;
XX    char		 Buffer[256];

XX    /* Clear screen? */

XX    if (Fraction < FULL)
XX	squisher = cos(TwoPi * Fraction);
XX    else
XX	squisher = cos(TwoPi * (Fraction - FULL));

XX    cht = (double)2.0 / (LINES - 6.0);
XX    for (y = 0.93; y > -1.0; y -= cht)
XX    {
XX	for (i = sizeof Buffer, p = Buffer; --i >= 0; )
XX	    *p++ = ' ';
XX	horizon = sqrt(1.0 - y * y);
XX	Buffer[    CharPos(-horizon)]	= LEDGE;
XX	Buffer[i = CharPos( horizon)]	= REDGE;
XX	Buffer[++i]			= '\0';
XX	terminator = horizon * squisher;
XX	if (Fraction > ZERO && Fraction < (1.0 - ZERO))
XX	{
XX	    if (Fraction < FULL)
XX	    {
XX		i   = CharPos( terminator);
XX		end = CharPos( horizon);
XX	    }
XX	    else
XX	    {
XX		i   = CharPos(-horizon);
XX		end = CharPos( terminator);
XX	    }
XX	    while (i <= end)
XX		Buffer[i++] = BRIGHT;
XX	}
XX	printf(" %s\n", Buffer);
XX    }
XX}
XX/*!*/
XXmain(ac)
XX    int			 ac;
XX{
XX    register long	 Phase;

XX    Phase = Calculate();
XX    if (ac == 1)
XX	Draw();

XX    printf("\nIt is ");
XX    if (Day == 0 && Hour == 0 && Minute == 0)
XX	printf("exactly");
XX    else
XX    {
XX	if (Day)
XX	{
XX	    printf("%ld day", Day);
XX	    Plural(Day);
XX	    if (Hour | Day)
XX		printf(", ");
XX	}
XX	if (Hour)
XX	{
XX	    printf("%ld hour", Hour);
XX	    Plural(Hour);
XX	    if (Minute)
XX		printf(", ");
XX	}
XX	if (Minute)
XX	{
XX	    printf("%ld minute", Minute);
XX	    Plural(Minute);
XX	}
XX	printf(" since");
XX    }
XX    printf(" the %s moon.\n", Moon[Phase]);

XX    exit(0);
XX}
@//E*O*F pom.c//
chmod u=rw,g=rw,o=r pom.c
 
echo Inspecting for damage in transit...
temp=/tmp/shar$$; dtemp=/tmp/.shar$$
trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
cat > $temp <<\!!!
     188     565    3569 pom.c
!!!
wc  pom.c | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
if [ -s $dtemp ]
then echo "Ouch [diff of wc output]:" ; cat $dtemp
else echo "No problems found."
fi
exit 0