Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

phoon - show the phase of the moon

by jima (Vicar)
on Jul 25, 2007 at 17:01 UTC ( #628729=sourcecode: print w/ replies, xml ) Need Help??

Category: Fun Stuff
Author/Contact Info
Description: A Perl translation of Jef Poskanzer's phoon program.
#!/usr/bin/perl
#
#   phoon - show the phase of the moon
#
#   Translated from Jef Poskanzer's phoon.c (http://www.acme.com/softw
+are/phoon/)
#   and John Walker's moontool.c astro libraries (http://www.fourmilab
+.ch/moontool/)
#   by James Allenspach <jima@legnog.com>. The copyright from the orig
+inal source:
#   
#   ** Copyright (C) 1986,1987,1988,1995 by Jef Poskanzer <jef@mail.ac
+me.com>.
#   ** All rights reserved.
#   **
#   ** Redistribution and use in source and binary forms, with or with
+out
#   ** modification, are permitted provided that the following conditi
+ons
#   ** are met:
#   ** 1. Redistributions of source code must retain the above copyrig
+ht
#   **    notice, this list of conditions and the following disclaimer
+.
#   ** 2. Redistributions in binary form must reproduce the above copy
+right
#   **    notice, this list of conditions and the following disclaimer
+ in the
#   **    documentation and/or other materials provided with the distr
+ibution.
#   ** 
#   ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS I
+S'' AND
#   ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED T
+O, THE
#   ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICU
+LAR PURPOSE
#   ** ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS B
+E LIABLE
#   ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CO
+NSEQUENTIAL
#   ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITU
+TE GOODS
#   ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRU
+PTION)
#   ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTR
+ACT, STRICT
#   ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+IN ANY WAY
#   ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
+LITY OF
#   ** SUCH DAMAGE.
#


use Date::Parse;
use POSIX;
use strict;

use constant {

    SECSPERMINUTE   => 60,
    SECSPERHOUR     => (60 * 60),
    SECSPERDAY      => (24 * 60 * 60),
    PI              => 3.1415926535897932384626433,
    DEFAULTNUMLINES => 23,
    ASPECTRATIO     => 0.5,         # If you change the aspect ratio, 
+the canned backgrounds won't work.


    epoch           => 2444238.5,   # 1980 January 0.0

# Constants defining the Sun's apparent orbit

    elonge          => 278.833540,  # Ecliptic longitude of the Sun at
+ epoch 1980.0
    elongp          => 282.596403,  # Ecliptic longitude of the Sun at
+ perigee
    eccent          => 0.016718,    # Eccentricity of Earth's orbit
    sunsmax         => 1.495985e8,  # Semi-major axis of Earth's orbit
+, km
    sunangsiz       => 0.533128,    # Sun's angular size, degrees, at 
+semi-major axis distance

# Elements of the Moon's orbit, epoch 1980.0

    mmlong          => 64.975464,   # Moon's mean lonigitude at the ep
+och 
    mmlongp         => 349.383063,  # Mean longitude of the perigee at
+ the epoch
    mlnode          => 151.950429,  # Mean longitude of the node at th
+e epoch
    minc            => 5.145396,    # Inclination of the Moon's orbit
    mecc            => 0.054900,    # Eccentricity of the Moon's orbit
+ 
    mangsiz         => 0.5181,      # Moon's angular size at distance 
+a from Earth 
    msmax           => 384401.0,    # Semi-major axis of Moon's orbit 
+in km 
    mparallax       => 0.9507,      # Parallax at distance a from Eart
+h 
    synmonth        => 29.53058868, # Synodic month (new Moon to new M
+oon) 
    lunatbase       => 2423436.0,   # Base date for E. W. Brown's numb
+ered series of lunations (1923 January 16) 

# Properties of the Earth

    earthrad        => 6378.16,     #  Radius of Earth in kilometres 

    EPSILON         =>  1E-6,

};

my $usage = "usage:  $0  [ -l <lines> ]  [ <date/time> ]\n";

sub putseconds {
    my($secs) = @_;
    my($days,$hours,$minutes);
    
    $days = int($secs / SECSPERDAY);
    $secs -= $days * SECSPERDAY;
    $hours = int($secs / SECSPERHOUR);
    $secs -= $hours * SECSPERHOUR;
    $minutes = int($secs / SECSPERMINUTE);
    $secs -= $minutes * SECSPERMINUTE;

    return sprintf( "%ld %2ld:%02ld:%02ld", $days, $hours, $minutes, $
+secs );
}

sub unix_to_julian {
    return $_[0] / 86400.0 + 2440587.4999996666666666666;
}


sub fixangle { return ($_[0] - 360.0 * (POSIX::floor($_[0] / 360.0)));
+ }
sub torad { return ($_[0] * (PI / 180.0)); }    # Deg->Rad
sub todeg { return ($_[0] * (180.0 / PI)); }    # Rad->Deg

sub dsin  { return sin(torad($_[0]));      }    # sin from Deg
sub dcos  { return cos(torad($_[0]));      }    # cos from Deg

sub kepler {    # solve the equation of Kepler
    my($m, $ecc) = @_;
    my($e,$delta);

    $e = $m = torad($m);
    do {
        $delta = $e - $ecc * sin($e) - $m;
        $e -= $delta / (1 - $ecc * cos($e));
    } while (abs ($delta) > EPSILON);
    return $e;
}


sub phase {
    my($pdate) = @_;

    # Calculation of the Sun's position 

    my($Day) = $pdate - epoch;  # Date within epoch 
    my($N) = fixangle((360 / 365.2422) * $Day); # Mean anomaly of the 
+Sun 
    my($M) = fixangle($N + elonge - elongp);    # Convert from perigee
+ co-ordinates to epoch 1980.0
    my($Ec) = kepler($M, eccent);   # Solve equation of Kepler */
    $Ec = sqrt((1 + eccent) / (1 - eccent)) * tan($Ec / 2);
    $Ec = 2 * todeg(atan($Ec)); # True anomaly
    my($Lambdasun) = fixangle($Ec + elongp);    # Sun's geocentric ecl
+iptic longitude
    
    # Orbital distance factor
    my($F) = ((1 + eccent * cos(torad($Ec))) / (1 - eccent * eccent));
    my($SunDist) = sunsmax / $F;    # Distance to Sun in km 
    my($SunAng) = $F * sunangsiz;   # Sun's angular size in degrees

    # Calculation of the Moon's position 

    # Moon's mean longitude
    my($ml) = fixangle(13.1763966 * $Day + mmlong);

    # Moon's mean anomaly 
    my($MM) = fixangle($ml - 0.1114041 * $Day - mmlongp);

    # Moon's ascending node mean longitude 
    my($MN) = fixangle(mlnode - 0.0529539 * $Day);

    # Evection
    my($Ev) = 1.2739 * sin(torad(2 * ($ml - $Lambdasun) - $MM));

    # Annual equation
    my($Ae) = 0.1858 * sin(torad($M));

    # Correction term 
    my($A3) = 0.37 * sin(torad($M));

    # Corrected anomaly 
    my($MmP) = $MM + $Ev - $Ae - $A3;

    # Correction for the equation of the centre 
    my($mEc) = 6.2886 * sin(torad($MmP));

    # Another correction term 
    my($A4) = 0.214 * sin(torad(2 * $MmP));

    # Corrected longitude 
    my($lP) = $ml + $Ev + $mEc - $Ae + $A4;

    # Variation 
    my($V) = 0.6583 * sin(torad(2 * ($lP - $Lambdasun)));

    # True longitude 
    my($lPP) = $lP + $V;

    # Corrected longitude of the node 
    my($NP) = $MN - 0.16 * sin(torad($M));

    # Y inclination coordinate 
    my($y) = sin(torad($lPP - $NP)) * cos(torad(minc));

    # X inclination coordinate 
    my($x) = cos(torad($lPP - $NP));

    # Ecliptic longitude 
    my($Lambdamoon) = todeg(atan2($y, $x));
    $Lambdamoon += $NP;

    # Ecliptic latitude 
    my($BetaM) = todeg(asin(sin(torad($lPP - $NP)) * sin(torad(minc)))
+);

    # Calculation of the phase of the Moon 

    # Age of the Moon in degrees 
    my($MoonAge) = $lPP - $Lambdasun;

    # Phase of the Moon 
    my($MoonPhase) = (1 - cos(torad($MoonAge))) / 2;

    # Calculate distance of moon from the centre of the Earth 

    my($MoonDist) = (msmax * (1 - mecc * mecc)) /
       (1 + mecc * cos(torad($MmP + $mEc)));

    # Calculate Moon's angular diameter 

    my($MoonDFrac) = $MoonDist / msmax;
    my($MoonAng) = mangsiz / $MoonDFrac;

    # Calculate Moon's parallax 

    my($MoonPar) = mparallax / $MoonDFrac;

    return (
        fixangle($MoonAge) / 360.0,                 # terminator phase
+ angle
        $MoonPhase,                                 # moon phase
        synmonth * (fixangle($MoonAge) / 360.0),    # age of moon in d
+ays
        $MoonDist,                                  # distance in km
        $MoonAng,                                   # angular diameter
+ in degrees
        $SunDist,                                   # distance to Sun
        $SunAng,                                    # Sun's angular di
+ameter
    );
}


# jyear - Convert Julian date to year, month, day.

sub jyear {
    my($td) = @_;
    my($j,$d,$y,$m);

    $td += 0.5;                #Astronomical to civil 
    $j = POSIX::floor($td);
    $j -= 1721119.0;
    $y = POSIX::floor(((4 * $j) - 1) / 146097.0);
    $j = ($j * 4.0) - (1.0 + (146097.0 * $y));
    $d = POSIX::floor($j / 4.0);
    $j = POSIX::floor(((4.0 * $d) + 3.0) / 1461.0);
    $d = ((4.0 * $d) + 3.0) - (1461.0 * $j);
    $d = POSIX::floor(($d + 4.0) / 4.0);
    $m = POSIX::floor(((5.0 * $d) - 3) / 153.0);
    $d = (5.0 * $d) - (3.0 + (153.0 * $m));
    $d = POSIX::floor(($d + 5.0) / 5.0);
    $y = (100.0 * $y) + $j;
    if ($m < 10.0) {
        $m += 3;
    } else {
        $m -= 9;
        ++$y;
    }
    return ($y,$m,$d);
}


# meanphase -  Calculates time of the mean new Moon for a given base d
+ate.  This argument K to this function is
# the precomputed synodic month index, given by:
#
#   K = (year - 1900) * 12.3685
#
# where year is expressed as a year and fractional year.

sub meanphase {
    my($sdate,$k) = @_;
    my($t,$t2,$t3,$nt1);

    # Time in Julian centuries from 1900 January 0.5
    $t = ($sdate - 2415020.0) / 36525;
    $t2 = $t * $t;          # Square for frequent use 
    $t3 = $t2 * $t;         # Cube for frequent use 

    $nt1 = 2415020.75933 + synmonth * $k
        + 0.0001178 * $t2
        - 0.000000155 * $t3
        + 0.00033 * dsin(166.56 + 132.87 * $t - 0.009173 * $t2);

    return $nt1;
}


# truephase -  Given a K value used to determine the mean phase of the
+ new moon, and a phase
# selector (0.0, 0.25, 0.5, 0.75), obtain the true, corrected phase ti
+me.

sub truephase {
    my($k, $phase) = @_;
    my($t,$t2,$t3, $pt, $m, $mprime, $f);
    my($apcor) = 0;

    $k += $phase;   # Add phase to new moon time 
    $t = $k / 1236.85;  # Time in Julian centuries from 1900 January 0
+.5 
    $t2 = $t * $t;      # Square for frequent use 
    $t3 = $t2 * $t;     # Cube for frequent use 
    $pt = 2415020.75933        # Mean time of phase 
         + synmonth * $k
         + 0.0001178 * $t2
         - 0.000000155 * $t3
         + 0.00033 * dsin(166.56 + 132.87 * $t - 0.009173 * $t2);

    $m = 359.2242               # Sun's mean anomaly 
        + 29.10535608 * $k
        - 0.0000333 * $t2
        - 0.00000347 * $t3;
    $mprime = 306.0253          # Moon's mean anomaly 
        + 385.81691806 * $k
        + 0.0107306 * $t2
        + 0.00001236 * $t3;
    $f = 21.2964                # Moon's argument of latitude 
        + 390.67050646 * $k
        - 0.0016528 * $t2
        - 0.00000239 * $t3;
    if (($phase < 0.01) || (abs($phase - 0.5) < 0.01)) {

       # Corrections for New and Full Moon 

       $pt +=     (0.1734 - 0.000393 * $t) * dsin($m)
            + 0.0021 * dsin(2 * $m)
            - 0.4068 * dsin($mprime)
            + 0.0161 * dsin(2 * $mprime)
            - 0.0004 * dsin(3 * $mprime)
            + 0.0104 * dsin(2 * $f)
            - 0.0051 * dsin($m + $mprime)
            - 0.0074 * dsin($m - $mprime)
            + 0.0004 * dsin(2 * $f + $m)
            - 0.0004 * dsin(2 * $f - $m)
            - 0.0006 * dsin(2 * $f + $mprime)
            + 0.0010 * dsin(2 * $f - $mprime)
            + 0.0005 * dsin($m + 2 * $mprime);
       $apcor = 1;
    } elsif ((abs($phase - 0.25) < 0.01 || (abs($phase - 0.75) < 0.01)
+)) {
       $pt +=     (0.1721 - 0.0004 * $t) * dsin($m)
            + 0.0021 * dsin(2 * $m)
            - 0.6280 * dsin($mprime)
            + 0.0089 * dsin(2 * $mprime)
            - 0.0004 * dsin(3 * $mprime)
            + 0.0079 * dsin(2 * $f)
            - 0.0119 * dsin($m + $mprime)
            - 0.0047 * dsin($m - $mprime)
            + 0.0003 * dsin(2 * $f + $m)
            - 0.0004 * dsin(2 * $f - $m)
            - 0.0006 * dsin(2 * $f + $mprime)
            + 0.0021 * dsin(2 * $f - $mprime)
            + 0.0003 * dsin($m + 2 * $mprime)
            + 0.0004 * dsin($m - 2 * $mprime)
            - 0.0003 * dsin(2 * $m + $mprime);
       if ($phase < 0.5) {
          # First quarter correction 
          $pt += 0.0028 - 0.0004 * dcos($m) + 0.0003 * dcos($mprime);
       } else {
          # Last quarter correction 
          $pt += -0.0028 + 0.0004 * dcos($m) - 0.0003 * dcos($mprime);
       }
       $apcor = 1;
    }
    if (!$apcor) {
       die "TRUEPHASE called with invalid phase selector.\n";
    }
    return $pt;
}


# phasehunt5 - Find time of phases of the moon which surround the curr
+ent date.  Five phases are found, starting
# and ending with the new moons which bound the current lunation.

sub phasehunt5 {
    my($sdate) = @_;
    my($adate, $k1, $k2, $nt1, $nt2, $yy, $mm, $dd);

    $adate = $sdate - 45;

    ($yy,$mm,$dd) = jyear($adate);
    $k1 = POSIX::floor(($yy + (($mm - 1) * (1.0 / 12.0)) - 1900) * 12.
+3685);

    $adate = $nt1 = meanphase($adate, $k1);
    while (1) {
        $adate += synmonth;
        $k2 = $k1 + 1;
        $nt2 = meanphase($adate, $k2);
        if ($nt1 <= $sdate && $nt2 > $sdate) {
            last;
        }
        $nt1 = $nt2;
        $k1 = $k2;
    }
    return [
        truephase ($k1, 0.0),
        truephase ($k1, 0.25),
        truephase ($k1, 0.5),
        truephase ($k1, 0.75),
        truephase ($k2, 0.0),
    ];
}

# phasehunt2 -  Find time of phases of the moon which surround the cur
+rent date.  Two phases are found.

sub phasehunt2 {
    my($sdate) = @_;
    
    my(@phases,@which,$phases5);

    $phases5 = phasehunt5( $sdate );
    $phases[0] = $phases5->[0];
    $which[0] = 0.0;
    $phases[1] = $phases5->[1];
    $which[1] = 0.25;
    if ( $phases[1] <= $sdate ) {
        $phases[0] = $phases[1];
        $which[0] = $which[1];
        $phases[1] = $phases5->[2];
        $which[1] = 0.5;
        if ( $phases[1] <= $sdate ) {
            $phases[0] = $phases[1];
            $which[0] = $which[1];
            $phases[1] = $phases5->[3];
            $which[1] = 0.75;
            if ( $phases[1] <= $sdate ) {
                $phases[0] = $phases[1];
                $which[0] = $which[1];
                $phases[1] = $phases5->[4];
                $which[1] = 0.0;
            }
        }
    }
    return \@which, \@phases;
}


sub putmoon {
    my($t, $numlines, $atfiller) = @_;
    my $secsynodic = 29*SECSPERDAY + 12*SECSPERHOUR + 44*SECSPERMINUTE
+ + 3;

    my(%background) = (
    
        '18' => [   "             .----------.            ",
                    "         .--'   o    .   `--.        ",
                    "       .'@  @@@@@@ O   .   . `.      ",
                    "     .'@@  @@@@@@@@   @@@@   . `.    ",
                    "   .'    . @@@@@@@@  @@@@@@    . `.  ",
                    "  / @@ o    @@@@@@.   @@@@    O   @\\ ",
                    "  |@@@@               @@@@@@     @@| ",
                    " / @@@@@   `.-.    . @@@@@@@@  .  @@\\",
                    " | @@@@   --`-'  .  o  @@@@@@@      |",
                    " |@ @@                 @@@@@@ @@@   |",
                    " \\      @@    @   . ()  @@   @@@@@  /",
                    "  |   @      @@@         @@@  @@@  | ",
                    "  \\  .   @@  @\\  .      .  @@    o / ",
                    "   `.   @@@@  _\\ /     .      o  .'  ",
                    "     `.  @@    ()---           .'    ",
                    "       `.     / |  .    o    .'      ",
                    "         `--./   .       .--'        ",
                    "             `----------'            "
        ],
        
        '19' => [   "              .----------.             ",
                    "          .--'   o    .   `--.         ",
                    "       .-'@  @@@@@@ O   .   . `-.      ",
                    "     .' @@  @@@@@@@@   @@@@   .  `.    ",
                    "    /     . @@@@@@@@  @@@@@@     . \\   ",
                    "   /@@  o    @@@@@@.   @@@@    O   @\\  ",
                    "  /@@@@                @@@@@@     @@@\\ ",
                    " . @@@@@   `.-./    . @@@@@@@@  .  @@ .",
                    " | @@@@   --`-'  .      @@@@@@@       |",
                    " |@ @@        `      o  @@@@@@ @@@@   |",
                    " |      @@        o      @@   @@@@@@  |",
                    " ` .  @       @@     ()   @@@  @@@@   '",
                    "  \\     @@   @@@@        . @@   .  o / ",
                    "   \\   @@@@  @@\\  .           o     /  ",
                    "    \\ . @@     _\\ /    .      .-.  /   ",
                    "     `.    .    ()---        `-' .'    ",
                    "       `-.    ./ |  .   o     .-'      ",
                    "          `--./   .       .--'         ",
                    "              `----------'             "
        ],
        'pumpkin19' => [        "              @@@@@@@@@@@@           
+  ",
                                "          @@@@@@@@@@@@@@@@@@@@       
+  ",
                                "       @@@@@@@@@@@@@@@@@@@@@@@@@@    
+  ",
                                "     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  
+  ",
                                "    @@@@        @@@@@@@@        @@@@ 
+  ",
                                "   @@@@@@      @@@@@@@@@@      @@@@@@
+  ",
                                "  @@@@@@@@    @@@@@@@@@@@@    @@@@@@@
+@ ",
                                " @@@@@@@@@@  @@@@@@  @@@@@@  @@@@@@@@
+@@",
                                " @@@@@@@@@@@@@@@@@    @@@@@@@@@@@@@@@
+@@",
                                " @@@@@@@@@@@@@@@@      @@@@@@@@@@@@@@
+@@",
                                " @@@@@@@@@@@@@@@        @@@@@@@@@@@@@
+@@",
                                " @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@@",
                                "  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ ",
                                "   @@@@@                @@      @@@@@
+  ",
                                "    @@@@@@                    @@@@@@ 
+  ",
                                "     @@@@@@@@              @@@@@@@@  
+  ",
                                "       @@@@@@@@@        @@@@@@@@@    
+  ",
                                "          @@@@@@@@@@@@@@@@@@@@       
+  ",
                                "              @@@@@@@@@@@@           
+  "
        ],

        '21' => [   "                .----------.               ",
                    "           .---'   O   . .  `---.          ",
                    "        .-'@ @@@@@@  .  @@@@@    `-.       ",
                    "      .'@@  @@@@@@@@@  @@@@@@@   .  `.     ",
                    "     /   o  @@@@@@@@@  @@@@@@@      . \\    ",
                    "    /@  o   @@@@@@@@@.  @@@@@@@   O    \\   ",
                    "   /@@@  .   @@@@@\@o   @@@@@@@@@@     @@\\  ",
                    "  /@@@@@            . @@@@@@@@@@@@@ o @@@\\ ",
                    " .@@@@@ O  `.-./ .     @@@@@@@@@@@@    @@ .",
                    " | @@@@   --`-'      o    @@@@@@@@ @@@@   |",
                    " |@ @@@       `   o     .  @@  . @@@@@@@  |",
                    " |      @@  @        .-.    @@@  @@@@@@@  |",
                    " `  . @       @@@    `-'  . @@@@  @@@@  o '",
                    "  \\     @@   @@@@@ .         @@  .       / ",
                    "   \\   @@@@  @\\@@    /  . O   .    o  . /  ",
                    "    \\o  @@     \\ \\  /       .   .      /   ",
                    "     \\    .    .\\.-.___  .     .  .-. /    ",
                    "      `.         `-'             `-'.'     ",
                    "        `-.  o  / |    o   O  .  .-'       ",
                    "           `---.    .    .  .---'          ",
                    "                `----------'               "
        ],
        '22' => [   "                .------------.               ",
                    "            .--'   o     . .  `--.           ",
                    "         .-'    .    O   .      . `-.        ",
                    "       .'@    @@@@@@@   .  @@@@@     `.      ",
                    "     .'@@@  @@@@@@@@@@@   @@@@@@@  .   `.    ",
                    "    /     o @@@@@@@@@@@   @@@@@@@      . \\   ",
                    "   /@@  o   @@@@@@@@@@@.   @@@@@@@   O    \\  ",
                    "  /@@@@   .   @@@@@@\@o    @@@@@@@@@@    @@@\\ ",
                    "  |@@@@@               . @@@@@@@@@@@@  @@@@| ",
                    " /@@@@@  O  `.-./  .      @@@@@@@@@@@   @@  \\",
                    " | @@@@    --`-'      o    . @@@@@@@ @@@@   |",
                    " |@ @@@  @@  @ `   o  .-.     @@  . @@@@@@  |",
                    " \\             @@@    `-'  .   @@@  @@@@@@  /",
                    "  | . @  @@   @@@@@ .          @@@@  @@@ o | ",
                    "  \\     @@@@  @\\@@    /  .  O   @@ .     . / ",
                    "   \\  o  @@     \\ \\  /          . . o     /  "
+,
                    "    \\      .    .\\.-.___   .  .  .  .-.  /   ",
                    "     `.           `-'              `-' .'    ",
                    "       `.    o   / |     o   O   .   .'      ",
                    "         `-.    /     .      .    .-'        ",
                    "            `--.        .     .--'           ",
                    "                `------------'               "
        ],

        
        '23' => [   "                 .------------.                ",
                    "             .--'  o     . .   `--.            ",
                    "          .-'   .    O   .       . `-.         ",
                    "       .-'@   @@@@@@@   .  @@@@@      `-.      ",
                    "      /@@@  @@@@@@@@@@@   @@@@@@@   .    \\     "
+,
                    "    ./    o @@@@@@@@@@@   @@@@@@@       . \\.   "
+,
                    "   /@@  o   @@@@@@@@@@@.   @@@@@@@   O      \\  "
+,
                    "  /@@@@   .   @@@@@@\@o    @@@@@@@@@@     @@@ \\ 
+",
                    "  |@@@@@               . @@@@@@@@@@@@@ o @@@@| ",
                    " /@@@@@  O  `.-./  .      @@@@@@@@@@@@    @@  \\"
+,
                    " | @@@@    --`-'       o     @@@@@@@@ @@@@    |",
                    " |@ @@@        `    o      .  @@   . @@@@@@@  |",
                    " |       @@  @         .-.     @@@   @@@@@@@  |",
                    " \\  . @        @@@     `-'   . @@@@   @@@@  o /"
+,
                    "  |      @@   @@@@@ .           @@   .       | ",
                    "  \\     @@@@  @\\@@    /  .  O    .     o   . / 
+",
                    "   \\  o  @@     \\ \\  /         .    .       / 
+ ",
                    "    `\\     .    .\\.-.___   .      .   .-. /'   
+",
                    "      \\           `-'                `-' /     "
+,
                    "       `-.   o   / |     o    O   .   .-'      ",
                    "          `-.   /     .       .    .-'         ",
                    "             `--.       .      .--'            ",
                    "                 `------------'                "
        ],
        
        '24' => [   "                  .------------.                 
+",
                    "             .---' o     .  .   `---.            
+",
                    "          .-'   .    O    .       .  `-.         
+",
                    "        .'@   @@@@@@@   .   @@@@@       `.       
+",
                    "      .'@@  @@@@@@@@@@@    @@@@@@@   .    `.     
+",
                    "     /    o @@@@@@@@@@@    @@@@@@@       .  \\   
+ ",
                    "    /@  o   @@@@@@@@@@@.    @@@@@@@   O      \\  
+ ",
                    "   /@@@   .   @@@@@@\@o     @@@@@@@@@@     @@@ \\
+  ",
                    "  /@@@@@               .  @@@@@@@@@@@@@ o @@@@ \\
+ ",
                    "  |@@@@  O  `.-./  .       @@@@@@@@@@@@    @@  | 
+",
                    " / @@@@    --`-'       o      @@@@@@@@ @@@@     \
+\",
                    " |@ @@@     @  `           .   @@     @@@@@@@   |
+",
                    " |      @           o          @      @@@@@@@   |
+",
                    " \\       @@            .-.      @@@    @@@@  o  
+/",
                    "  | . @        @@@     `-'    . @@@@           | 
+",
                    "  \\      @@   @@@@@ .            @@   .        /
+ ",
                    "   \\    @@@@  @\\@@    /  .   O    .     o   . /
+  ",
                    "    \\ o  @@     \\ \\  /          .    .       /
+   ",
                    "     \\     .    .\\.-.___    .      .   .-.  /  
+  ",
                    "      `.          `-'                 `-' .'     
+",
                    "        `.   o   / |      o    O   .    .'       
+",
                    "          `-.   /      .       .     .-'         
+",
                    "             `---.       .      .---'            
+",
                    "                  `------------'                 
+"
        ],
        
        '29' => [   "                      .--------------.           
+          ",
                    "                 .---'  o        .    `---.      
+          ",
                    "              .-'    .    O  .         .   `-.   
+          ",
                    "           .-'     @@@@@@       .             `-.
+          ",
                    "         .'@@   @@@@@@@@@@@       @@@@@@@   .    
+`.        ",
                    "       .'@@@  @@@@@@@@@@@@@@     @@@@@@@@@       
+  `.      ",
                    "      /@@@  o @@@@@@@@@@@@@@     @@@@@@@@@     O 
+    \\     ",
                    "     /        @@@@@@@@@@@@@@  @   @@@@@@@@@ @@   
+  .  \\    ",
                    "    /@  o      @@@@@@@@@@@   .  @@  @@@@@@@@@@@  
+   @@ \\   ",
                    "   /@@@      .   @@@@@@ o       @  @@@@@@@@@@@@@ 
+o @@@@ \\  ",
                    "  /@@@@@                  @ .      @@@@@@@@@@@@@@
+  @@@@@ \\ ",
                    "  |@@@@@    O    `.-./  .        .  @@@@@@@@@@@@@
+   @@@  | ",
                    " / @@@@@        --`-'       o        @@@@@@@@@@@ 
+@@@    . \\",
                    " |@ @@@@ .  @  @    `    @            @@      . @
+@@@@@    |",
                    " |   @@                         o    @@   .     @
+@@@@@    |",
                    " |  .     @   @ @       o              @@   o   @
+@@@@@.   |",
                    " \\     @    @       @       .-.       @@@@      
+ @@@      /",
                    "  |  @    @  @              `-'     . @@@@     . 
+   .    | ",
                    "  \\ .  o       @  @@@@  .              @@  .    
+       . / ",
                    "   \\      @@@    @@@@@@       .                 
+  o     /  ",
                    "    \\    @@@@@   @@\\@@    /        O          .
+        /   ",
                    "     \\ o  @@@       \\ \\  /  __        .   .   
+  .--.  /    ",
                    "      \\      .     . \\.-.---                   
+`--'  /     ",
                    "       `.             `-'      .                 
+  .'      ",
                    "         `.    o     / | `           O     .     
+.'        ",
                    "           `-.      /  |        o             .-'
+          ",
                    "              `-.          .         .     .-'   
+          ",
                    "                 `---.        .       .---'      
+          ",
                    "                      `--------------'           
+          "
        ],
        'hubert29' => [ "                      .--------------.       
+              ",
                        "                 .---'  o        .    `---.  
+              ",
                        "              .-'    .    O  .         .   `-
+.             ",
                        "           .-'     @@@@@@       .            
+ `-.          ",
                        "         .'@@   @@@@@@@@@@@       @@@@@@@   .
+    `.        ",
                        "       .'@@@  @@@@@ ___====-_  _-====___ @   
+      `.      ",
                        "      /@@@  o _--~~~#####//      \\\\#####~~~
+--_ O     \\     ",
                        "     /     _-~##########// (    ) \\\\#######
+###~-_  .  \\    ",
                        "    /@  o -############//  :\\^^/:  \\\\#####
+#######-  @@ \\   ",
                        "   /@@@ _~############//   (\@::@)   \\\\####
+########~_ @@ \\  ",
                        "  /@@@ ~#############((     \\\\//     ))####
+#########~ @@ \\ ",
                        "  |@@ -###############\\\\    (oo)    //#####
+##########- @ | ",
                        " / @ -#################\\\\  / \"\" \\  //###
+##############- . \\",
                        " |@ -###################\\\\/      \\//######
+#############-  |",
                        " | _#/:##########/\\######(   /\\   )######/\
+\##########:\\#_ |",
                        " | :/ :#/\\#/\\#/\\/  \\#/\\##\\  :  :  /##/\
+\#/  \\/\\#/\\#/\\#: \\: |",
                        " \\ \"  :/  V  V  \"   V  \\#\\: :  : :/#/  V
+   \"  V  V  \\:  \" /",
                        "  | @ \"   \"  \"      \"   / : :  : : \\   \
+"      \"  \"   \"   | ",
                        "  \\ .  o       @  @@@@ (  : :  : :  )  @@  .
+           . / ",
                        "   \\      @@@    @@@@ __\\ : :  : : /__     
+       o     /  ",
                        "    \\    @@@@@   @@\\@(vvv(VVV)(VVV)vvv)    
+   .        /   ",
                        "     \\ o  @@@       \\ \\  /  __        .   
+.     .--.  /    ",
                        "      \\      .     . \\.-.---               
+    `--'  /     ",
                        "       `.             `-'      .             
+      .'      ",
                        "         `.    o     / | `           O     . 
+    .'        ",
                        "           `-.      /  |        o            
+ .-'          ",
                        "              `-.          .         .     .-
+'             ",
                        "                 `---.        .       .---'  
+              ",
                        "                      `--------------'       
+              "
        ],
        '32' => [       "                         .--------------.    
+                    ",
                        "                   .----'  o        .    `---
+-.                  ",
                        "                .-'     .    O  .          . 
+  `-.               ",
                        "             .-'      @@@@@@       .         
+     `-.            ",
                        "           .'@     @@@@@@@@@@@       @@@@@@@@
+    .   `.          ",
                        "         .'@@    @@@@@@@@@@@@@@     @@@@@@@@@
+@         `.        ",
                        "       .'@@@ o   @@@@@@@@@@@@@@     @@@@@@@@@
+@      o    `.      ",
                        "      /@@@       @@@@@@@@@@@@@@  @   @@@@@@@@
+@@  @@     .  \\     ",
                        "     /            @@@@@@@@@@@   .  @@   @@@@@
+@@@@@@@     @@ \\    ",
                        "    /@  o     .     @@@@@@ o       @   @@@@@@
+@@@@@@@@ o @@@@ \\   ",
                        "   /@@@                        .       @@@@@@
+@@@@@@@@@  @@@@@ \\  ",
                        "  /@@@@@                     @      .   @@@@@
+@@@@@@@@@   @@@   \\ ",
                        "  |@@@@@     o      `.-./  .             @@@@
+@@@@@@@@ @@@    . | ",
                        " / @@@@@           __`-'       o          @@ 
+      . @@@@@@     \\",
                        " |@ @@@@ .        @    `    @            @@  
+  .     @@@@@@     |",
                        " |   @@       @                    o       @@
+@   o   @@@@@@.    |",
                        " |          @                             @@@
+@@       @@@       |",
                        " |  . .  @      @  @       o              @@@
+@@     .    .      |",
                        " \\            @                .-.      .  @
+@@  .           .   /",
                        "  |    @   @   @      @        `-'           
+          .       / ",
                        "  \\   .      @   @                   .      
+      o            / ",
                        "   \\     o          @@@@   .                
+.                 /  ",
                        "    \\       @@@    @@@@@@        .          
+          o      /   ",
                        "     \\     @@@@@   @@\\@@    /         o    
+       .         /    ",
                        "      \\  o  @@@       \\ \\  /  ___         
+.   .     .--.   /     ",
                        "       `.      .       \\.-.---              
+       `--'  .'      ",
                        "         `.             `-'       .          
+          .'        ",
                        "           `.    o     / |              O    
+  .     .'          ",
                        "             `-.      /  |         o         
+     .-'            ",
                        "                `-.           .         .    
+  .-'               ",
                        "                   `----.        .       .---
+-'                  ",
                        "                         `--------------'    
+                    "
        ],


    );

    my(@qlits) = (
    "New Moon +     ",
    "First Quarter +",
    "Full Moon +    ",
    "Last Quarter + ",
    );
    my(@nqlits) = (
    "New Moon -     ",
    "First Quarter -",
    "Full Moon -    ",
    "Last Quarter - ",
    );

    # Find the length of the atfiller string.
    my($atflrlen) = length( $atfiller );

    # Figure out the phase.
    my($jd) = unix_to_julian( $t );
    
    my($pctphase,$cphase,$aom,$cdist,$cangdia, $csund, $csuang) = phas
+e($jd);
    my($angphase) = $pctphase * 2.0 * PI;
    my($mcap) = -cos( $angphase );

    my($clocknow) = time;
    # Randomly cheat and generate Hubert.
    if ( time % 13 == 3 && $cphase > 0.8 ) {
        $numlines = 29;
        $clocknow = 3;
    }

    # Figure out how big the moon is. 
    my($yrad) = $numlines / 2.0;
    my($xrad) = $yrad / ASPECTRATIO;
    my($numcols) = $xrad * 2;

    # Figure out some other random stuff.
    my($midlin) = int($numlines / 2);
    my($which,$phases) = phasehunt2($jd);

    # Now output the moon, a slice at a time.
    my($atflridx) = 0;
    for ( my $lin = 0; $lin < $numlines; ++$lin ) {
    
        # Compute the edges of this slice.
        my($y) = $lin + 0.5 - $yrad;
        my($xright) = $xrad * sqrt( 1.0 - ( $y * $y ) / ( $yrad * $yra
+d ) );
        my($xleft) = -$xright;
        if ( $angphase >= 0.0 && $angphase < PI ) {
            $xleft = $mcap * $xleft;
        } else {
            $xright = $mcap * $xright;
        }

        my($colleft)  = int($xrad + 0.5) + int($xleft + 0.5);
        my($colright) = int($xrad + 0.5) + int($xright + 0.5);
    
        # Now output the slice.
        my($col) = 0;
        for ( $col = 0; $col < $colleft; ++$col ) { print " "; }
        for ( ; $col <= $colright; ++$col ) {
        my($c) = '@';
        if (exists($background{$numlines})) {
            $c = substr($background{$numlines}->[$lin], $col, 1);

            if ($numlines == 19 && (localtime(time))[4] == 9 && $clock
+now % (33 - (localtime(time))[3]) == 1) {
                $c = substr($background{pumpkin19}->[$lin], $col, 1);
            } elsif ($numlines == 29 && $clocknow % 23 == 3) {
                $c = substr($background{hubert29}->[$lin], $col, 1);
            }
        }
        
        if ($c ne '@') {
            print $c;
        } else {
            print substr($atfiller,$atflridx++,1);
            $atflridx %= $atflrlen;
        }
    }
    
        if ( $numlines <= 27 ) {
            # Output the end-of-line information, if any.
            if ( $lin == $midlin - 2 ) {
                print "\t" . $qlits[int($which->[0] * 4.0 + 0.001)];
            } elsif ( $lin == $midlin - 1) {
                print "\t" . putseconds(int(($jd - $phases->[0]) * SEC
+SPERDAY));
            } elsif ( $lin == $midlin ) {
                print "\t" . $nqlits[int($which->[1] * 4.0 + 0.001)];
            } elsif ( $lin == $midlin + 1 ) {
                print "\t" . putseconds(int(($phases->[1] - $jd) * SEC
+SPERDAY));
            }
        }
    
        print "\n";
    }
}



#
# main
#

my($numlines) = DEFAULTNUMLINES;

if ($ARGV[0] eq '-l') {
    shift @ARGV;
    if ($ARGV[0] == 0) { print $usage; exit 1; }  # just in case the u
+ser types in "-l not_a_number"
    $numlines = int(shift @ARGV) || DEFAULTNUMLINES;
}

my($t) = 0;

if (@ARGV >= 1 && @ARGV <= 3) {  # date provided ?
    $t = str2time(join(' ', @ARGV));
    if (!defined($t)) { print $usage; exit 1; }
} elsif (@ARGV == 0) {
    $t = time;
} else {
    print $usage; exit 1;
}

# Pseudo-randomly decide what the moon is made of, and print it.
if (time % 17 == 3) {
    putmoon($t, $numlines, 'GREENCHEESE');
} else {
    putmoon($t, $numlines, '@');
}

exit 0;

__END__

=head1 NAME

phoon - show the PHase of the mOON

=head1 SYNOPSIS

phoon [-l lines] [date]

=head1 DESCRIPTION

I<Phoon> displays the phase of the moon, either currently
or at a specified date / time.
Unlike other such programs, which just tell you how long since first q
+uarter
or something like that, phoon I<shows> you the phase with a cute littl
+e picture.
You can vary the size of the picture with the -l flag, but only some
sizes have pictures defined - other sizes use @'s.

The perl version is a direct translation of the original C version, an
+d 
includes all of the features, moon images and Easter eggs of the origi
+nal
program.

=head1 SEE ALSO

perl(1).

=head1 AUTHOR

Translated from Jef Poskanzer's original phoon.c and John Walker's
moontool.c by James Allenspach E<lt>jima@legnog.comE<gt>. See the sour
+ce of
the program for copyright information.

=cut

Comment on phoon - show the phase of the moon
Download Code
Re: phoon - show the phase of the moon
by Scott7477 (Chaplain) on Jul 26, 2007 at 14:01 UTC
    Nice++...a clarification in the usage line of the date/time format and that the date wanted should be Julian might be helpful...

Back to Code Catacombs

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://628729]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (15)
As of 2014-10-02 17:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    What is your favourite meta-syntactic variable name?














    Results (67 votes), past polls