moon phase calculation based on phoon
This commit is contained in:
parent
9ccb0b2cb2
commit
e95c13b1c6
15 changed files with 2394 additions and 11 deletions
|
|
@ -343,6 +343,7 @@ The application makes network calls to the following services:
|
||||||
**External (other):**
|
**External (other):**
|
||||||
- Airport code -> location mapping: [Openflights](https://github.com/jpatokal/openflights)
|
- Airport code -> location mapping: [Openflights](https://github.com/jpatokal/openflights)
|
||||||
- Ip address -> location mapping: [GeoLite2 City Database](https://github.com/maxmind/libmaxminddb)
|
- Ip address -> location mapping: [GeoLite2 City Database](https://github.com/maxmind/libmaxminddb)
|
||||||
|
- Moon phase calculations (vendored): [Phoon](https://acme.com/software/phoon/)
|
||||||
|
|
||||||
## Performance Targets
|
## Performance Targets
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,15 +20,14 @@ Features not yet implemented in the Zig version:
|
||||||
- lang query parameter support
|
- lang query parameter support
|
||||||
- Translation of weather conditions and text (54 languages)
|
- Translation of weather conditions and text (54 languages)
|
||||||
|
|
||||||
## 5. Moon Phase Calculation
|
## 5. Astronomical Times
|
||||||
- Real moon phase computation based on date
|
|
||||||
- Moon phase emoji display
|
|
||||||
- Moonday calculation
|
|
||||||
|
|
||||||
## 6. Astronomical Times
|
|
||||||
- Calculate dawn, sunrise, zenith, sunset, dusk times
|
- Calculate dawn, sunrise, zenith, sunset, dusk times
|
||||||
- Based on location coordinates and timezone
|
- Based on location coordinates and timezone
|
||||||
- Display in custom format output
|
- Display in custom format output
|
||||||
|
|
||||||
## 7. Json output
|
## 6. Json output
|
||||||
- Does not match wttr.in format
|
- Does not match wttr.in format
|
||||||
|
|
||||||
|
## 7. Moon endpoint
|
||||||
|
- `/Moon` and `/Moon@YYYY-MM-DD` endpoints not yet implemented
|
||||||
|
- Moon phase calculation is implemented and available in custom format (%m, %M)
|
||||||
|
|
|
||||||
27
build.zig
27
build.zig
|
|
@ -19,6 +19,29 @@ pub fn build(b: *std.Build) void {
|
||||||
|
|
||||||
const maxminddb_upstream = b.dependency("maxminddb", .{});
|
const maxminddb_upstream = b.dependency("maxminddb", .{});
|
||||||
|
|
||||||
|
// Build phoon as a static library
|
||||||
|
const phoon = b.addLibrary(.{
|
||||||
|
.name = "phoon",
|
||||||
|
.linkage = .static,
|
||||||
|
.root_module = b.createModule(.{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.link_libc = true,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
phoon.addIncludePath(b.path("libs/phoon_14Aug2014"));
|
||||||
|
phoon.addCSourceFiles(.{
|
||||||
|
.root = b.path("libs/phoon_14Aug2014"),
|
||||||
|
.files = &.{
|
||||||
|
"astro.c",
|
||||||
|
"date_parse.c",
|
||||||
|
},
|
||||||
|
.flags = &.{ "-std=c99", "-D_DEFAULT_SOURCE" },
|
||||||
|
});
|
||||||
|
phoon.linkLibC();
|
||||||
|
phoon.linkSystemLibrary("m");
|
||||||
|
|
||||||
// Build libmaxminddb as a static library
|
// Build libmaxminddb as a static library
|
||||||
const maxminddb = b.addLibrary(.{
|
const maxminddb = b.addLibrary(.{
|
||||||
.name = "maxminddb",
|
.name = "maxminddb",
|
||||||
|
|
@ -74,8 +97,10 @@ pub fn build(b: *std.Build) void {
|
||||||
});
|
});
|
||||||
exe.root_module.addOptions("build_options", build_options);
|
exe.root_module.addOptions("build_options", build_options);
|
||||||
exe.root_module.addIncludePath(maxminddb_upstream.path("include"));
|
exe.root_module.addIncludePath(maxminddb_upstream.path("include"));
|
||||||
|
exe.root_module.addIncludePath(b.path("libs/phoon_14Aug2014"));
|
||||||
exe.root_module.addConfigHeader(maxminddb_config);
|
exe.root_module.addConfigHeader(maxminddb_config);
|
||||||
exe.linkLibrary(maxminddb);
|
exe.linkLibrary(maxminddb);
|
||||||
|
exe.linkLibrary(phoon);
|
||||||
exe.linkLibC();
|
exe.linkLibC();
|
||||||
|
|
||||||
b.installArtifact(exe);
|
b.installArtifact(exe);
|
||||||
|
|
@ -109,8 +134,10 @@ pub fn build(b: *std.Build) void {
|
||||||
});
|
});
|
||||||
tests.root_module.addOptions("build_options", test_options);
|
tests.root_module.addOptions("build_options", test_options);
|
||||||
tests.root_module.addIncludePath(maxminddb_upstream.path("include"));
|
tests.root_module.addIncludePath(maxminddb_upstream.path("include"));
|
||||||
|
tests.root_module.addIncludePath(b.path("libs/phoon_14Aug2014"));
|
||||||
tests.root_module.addConfigHeader(maxminddb_config);
|
tests.root_module.addConfigHeader(maxminddb_config);
|
||||||
tests.linkLibrary(maxminddb);
|
tests.linkLibrary(maxminddb);
|
||||||
|
tests.linkLibrary(phoon);
|
||||||
tests.linkLibC();
|
tests.linkLibC();
|
||||||
|
|
||||||
const run_tests = b.addRunArtifact(tests);
|
const run_tests = b.addRunArtifact(tests);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
.url = "git+https://github.com/rockorager/zeit?ref=zig-0.15#7ac64d72dbfb1a4ad549102e7d4e232a687d32d8",
|
.url = "git+https://github.com/rockorager/zeit?ref=zig-0.15#7ac64d72dbfb1a4ad549102e7d4e232a687d32d8",
|
||||||
.hash = "zeit-0.6.0-5I6bk36tAgATpSl9wjFmRPMqYN2Mn0JQHgIcRNcqDpJA",
|
.hash = "zeit-0.6.0-5I6bk36tAgATpSl9wjFmRPMqYN2Mn0JQHgIcRNcqDpJA",
|
||||||
},
|
},
|
||||||
|
.phoon = .{ .path = "libs/phoon_14Aug2014" },
|
||||||
},
|
},
|
||||||
.fingerprint = 0x710c2b57e81aa678,
|
.fingerprint = 0x710c2b57e81aa678,
|
||||||
.minimum_zig_version = "0.15.2",
|
.minimum_zig_version = "0.15.2",
|
||||||
|
|
|
||||||
33
libs/phoon_14Aug2014/Makefile
Normal file
33
libs/phoon_14Aug2014/Makefile
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Makefile for phoon
|
||||||
|
|
||||||
|
BINDIR = /usr/local/bin
|
||||||
|
MANDIR = /usr/local/man/man1
|
||||||
|
|
||||||
|
DEFINES = -DOS_BSD
|
||||||
|
#DEFINES = -DOS_SYSV
|
||||||
|
|
||||||
|
CC = cc
|
||||||
|
CFLAGS = -O $(DEFINES) -ansi -pedantic -U__STRICT_ANSI__ -Wall -Wpointer-arith -Wshadow -Wcast-qual -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wno-long-long
|
||||||
|
|
||||||
|
LDFLAGS = -s
|
||||||
|
|
||||||
|
|
||||||
|
all: phoon
|
||||||
|
|
||||||
|
phoon: phoon.o date_parse.o astro.o
|
||||||
|
$(CC) $(LDFLAGS) -o phoon phoon.o date_parse.o astro.o -lm
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
date_parse.o: date_parse.h
|
||||||
|
astro.o: astro.h
|
||||||
|
|
||||||
|
install: all
|
||||||
|
rm -f $(BINDIR)/phoon
|
||||||
|
cp phoon $(BINDIR)
|
||||||
|
rm -f $(MANDIR)/phoon.1
|
||||||
|
cp phoon.1 $(MANDIR)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f phoon *.o a.out core
|
||||||
50
libs/phoon_14Aug2014/README
Normal file
50
libs/phoon_14Aug2014/README
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
phoon - display current moon phase
|
||||||
|
|
||||||
|
|
||||||
|
phoon - program to display the PHase of the mOON. Unlike other
|
||||||
|
such programs, which just tell you how long since first quarter
|
||||||
|
or something like that, phoon *shows* you the phase with a little
|
||||||
|
picture. I've put an example at the end of this file. I first
|
||||||
|
wrote this program in Pascal / TOPS-20 at CMU in 1979; I translated
|
||||||
|
it to Ratfor / Software Tools in 1981; and now it's in C / Unix.
|
||||||
|
|
||||||
|
Files in this distribution:
|
||||||
|
|
||||||
|
README this
|
||||||
|
Makefile guess
|
||||||
|
phoon.c phase of moon display
|
||||||
|
astro.c phase of moon calculations
|
||||||
|
astro.h header file
|
||||||
|
phoon.1 manual for phase of moon program
|
||||||
|
date_parse.c date-parsing routine
|
||||||
|
date_parse.h header file
|
||||||
|
|
||||||
|
Unpack the files, edit Makefile and change the options to suit, make,
|
||||||
|
and enjoy! Feedback is welcome - send bug reports, enhancements,
|
||||||
|
checks, money orders, etc. to the addresses below.
|
||||||
|
|
||||||
|
Jef Poskanzer jef@mail.acme.com http://www.acme.com/jef/
|
||||||
|
|
||||||
|
.--
|
||||||
|
.--
|
||||||
|
.-'
|
||||||
|
.-'@
|
||||||
|
/@@@
|
||||||
|
./
|
||||||
|
/@@ o
|
||||||
|
/@@@@
|
||||||
|
|@@@@@
|
||||||
|
/@@@@@ Last Quarter +
|
||||||
|
| @@@@ 4 1:36:10
|
||||||
|
|@ @@@ New Moon -
|
||||||
|
| 3 7:34:53
|
||||||
|
\ . @
|
||||||
|
|
|
||||||
|
\ @
|
||||||
|
\ o
|
||||||
|
`\
|
||||||
|
\
|
||||||
|
`-.
|
||||||
|
`-.
|
||||||
|
`--
|
||||||
|
`--
|
||||||
467
libs/phoon_14Aug2014/astro.c
Normal file
467
libs/phoon_14Aug2014/astro.c
Normal file
|
|
@ -0,0 +1,467 @@
|
||||||
|
/* Adapted from "moontool.c" by John Walker, Release 2.5
|
||||||
|
**
|
||||||
|
** Quoting from the original:
|
||||||
|
**
|
||||||
|
** The algorithms used in this program to calculate the positions Sun and
|
||||||
|
** Moon as seen from the Earth are given in the book "Practical Astronomy
|
||||||
|
** With Your Calculator" by Peter Duffett-Smith, Second Edition,
|
||||||
|
** Cambridge University Press, 1981. Ignore the word "Calculator" in the
|
||||||
|
** title; this is an essential reference if you're interested in
|
||||||
|
** developing software which calculates planetary positions, orbits,
|
||||||
|
** eclipses, and the like. If you're interested in pursuing such
|
||||||
|
** programming, you should also obtain:
|
||||||
|
**
|
||||||
|
** "Astronomical Formulae for Calculators" by Jean Meeus, Third Edition,
|
||||||
|
** Willmann-Bell, 1985. A must-have.
|
||||||
|
**
|
||||||
|
** "Planetary Programs and Tables from -4000 to +2800" by Pierre
|
||||||
|
** Bretagnon and Jean-Louis Simon, Willmann-Bell, 1986. If you want the
|
||||||
|
** utmost (outside of JPL) accuracy for the planets, it's here.
|
||||||
|
**
|
||||||
|
** "Celestial BASIC" by Eric Burgess, Revised Edition, Sybex, 1985. Very
|
||||||
|
** cookbook oriented, and many of the algorithms are hard to dig out of
|
||||||
|
** the turgid BASIC code, but you'll probably want it anyway.
|
||||||
|
**
|
||||||
|
** See http://www.fourmilab.ch/moontool/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "astro.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define FALSE 0
|
||||||
|
#define TRUE 1
|
||||||
|
|
||||||
|
/* Astronomical constants */
|
||||||
|
|
||||||
|
#define epoch 2444238.5 /* 1980 January 0.0 */
|
||||||
|
|
||||||
|
/* Constants defining the Sun's apparent orbit */
|
||||||
|
|
||||||
|
#define elonge 278.833540 /* Ecliptic longitude of the Sun
|
||||||
|
at epoch 1980.0 */
|
||||||
|
#define elongp 282.596403 /* Ecliptic longitude of the Sun at
|
||||||
|
perigee */
|
||||||
|
#define eccent 0.016718 /* Eccentricity of Earth's orbit */
|
||||||
|
#define sunsmax 1.495985e8 /* Semi-major axis of Earth's orbit, km */
|
||||||
|
#define sunangsiz 0.533128 /* Sun's angular size, degrees, at
|
||||||
|
semi-major axis distance */
|
||||||
|
|
||||||
|
/* Elements of the Moon's orbit, epoch 1980.0 */
|
||||||
|
|
||||||
|
#define mmlong 64.975464 /* Moon's mean lonigitude at the epoch */
|
||||||
|
#define mmlongp 349.383063 /* Mean longitude of the perigee at the
|
||||||
|
epoch */
|
||||||
|
#define mlnode 151.950429 /* Mean longitude of the node at the
|
||||||
|
epoch */
|
||||||
|
#define minc 5.145396 /* Inclination of the Moon's orbit */
|
||||||
|
#define mecc 0.054900 /* Eccentricity of the Moon's orbit */
|
||||||
|
#define mangsiz 0.5181 /* Moon's angular size at distance a
|
||||||
|
from Earth */
|
||||||
|
#define msmax 384401.0 /* Semi-major axis of Moon's orbit in km */
|
||||||
|
#define mparallax 0.9507 /* Parallax at distance a from Earth */
|
||||||
|
#define synmonth 29.53058868 /* Synodic month (new Moon to new Moon) */
|
||||||
|
#define lunatbase 2423436.0 /* Base date for E. W. Brown's numbered
|
||||||
|
series of lunations (1923 January 16) */
|
||||||
|
|
||||||
|
/* Properties of the Earth */
|
||||||
|
|
||||||
|
#define earthrad 6378.16 /* Radius of Earth in kilometres */
|
||||||
|
|
||||||
|
|
||||||
|
#define PI 3.14159265358979323846 /* Assume not near black hole nor in
|
||||||
|
Tennessee */
|
||||||
|
|
||||||
|
/* Handy mathematical functions */
|
||||||
|
|
||||||
|
#define sgn(x) (((x) < 0) ? -1 : ((x) > 0 ? 1 : 0)) /* Extract sign */
|
||||||
|
#define abs(x) ((x) < 0 ? (-(x)) : (x)) /* Absolute val */
|
||||||
|
#define fixangle(a) ((a) - 360.0 * (floor((a) / 360.0))) /* Fix angle */
|
||||||
|
#define torad(d) ((d) * (PI / 180.0)) /* Deg->Rad */
|
||||||
|
#define todeg(d) ((d) * (180.0 / PI)) /* Rad->Deg */
|
||||||
|
#define dsin(x) (sin(torad((x)))) /* Sin from deg */
|
||||||
|
#define dcos(x) (cos(torad((x)))) /* Cos from deg */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UNIX_TO_JULIAN -- Convert internal Unix date/time to astronomical
|
||||||
|
* Julian time (i.e. Julian date plus day fraction, expressed as
|
||||||
|
* a double).
|
||||||
|
*/
|
||||||
|
double
|
||||||
|
unix_to_julian( time_t t )
|
||||||
|
{
|
||||||
|
return (double) t / 86400.0 + 2440587.4999996666666666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* JYEAR -- Convert Julian date to year, month, day, which are
|
||||||
|
* returned via integer pointers to integers.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
jyear( double td, int* yy, int* mm, int* dd )
|
||||||
|
{
|
||||||
|
double j, d, y, m;
|
||||||
|
|
||||||
|
td += 0.5; /* Astronomical to civil */
|
||||||
|
j = floor(td);
|
||||||
|
j = j - 1721119.0;
|
||||||
|
y = floor(((4 * j) - 1) / 146097.0);
|
||||||
|
j = (j * 4.0) - (1.0 + (146097.0 * y));
|
||||||
|
d = floor(j / 4.0);
|
||||||
|
j = floor(((4.0 * d) + 3.0) / 1461.0);
|
||||||
|
d = ((4.0 * d) + 3.0) - (1461.0 * j);
|
||||||
|
d = floor((d + 4.0) / 4.0);
|
||||||
|
m = floor(((5.0 * d) - 3) / 153.0);
|
||||||
|
d = (5.0 * d) - (3.0 + (153.0 * m));
|
||||||
|
d = floor((d + 5.0) / 5.0);
|
||||||
|
y = (100.0 * y) + j;
|
||||||
|
if (m < 10.0)
|
||||||
|
m = m + 3;
|
||||||
|
else {
|
||||||
|
m = m - 9;
|
||||||
|
y = y + 1;
|
||||||
|
}
|
||||||
|
*yy = y;
|
||||||
|
*mm = m;
|
||||||
|
*dd = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MEANPHASE -- Calculates time of the mean new Moon for a given
|
||||||
|
* base date. 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.
|
||||||
|
*/
|
||||||
|
static double
|
||||||
|
meanphase( double sdate, double k )
|
||||||
|
{
|
||||||
|
double 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 time.
|
||||||
|
*/
|
||||||
|
static double
|
||||||
|
truephase( double k, double pha )
|
||||||
|
{
|
||||||
|
double t, t2, t3, pt, m, mprime, f;
|
||||||
|
int apcor = FALSE;
|
||||||
|
|
||||||
|
k += pha; /* 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 ((pha < 0.01) || (abs(pha - 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 = TRUE;
|
||||||
|
} else if ((abs(pha - 0.25) < 0.01 || (abs(pha - 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 (pha < 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 = TRUE;
|
||||||
|
}
|
||||||
|
if (!apcor) {
|
||||||
|
(void)fprintf (stderr,
|
||||||
|
"TRUEPHASE called with invalid phase selector.\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PHASEHUNT5 -- Find time of phases of the moon which surround
|
||||||
|
* the current date. Five phases are found, starting
|
||||||
|
* and ending with the new moons which bound the
|
||||||
|
* current lunation.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
phasehunt5( double sdate, double phases[5] )
|
||||||
|
{
|
||||||
|
double adate, k1, k2, nt1, nt2;
|
||||||
|
int yy, mm, dd;
|
||||||
|
|
||||||
|
adate = sdate - 45;
|
||||||
|
|
||||||
|
jyear(adate, &yy, &mm, &dd);
|
||||||
|
k1 = floor((yy + ((mm - 1) * (1.0 / 12.0)) - 1900) * 12.3685);
|
||||||
|
|
||||||
|
adate = nt1 = meanphase(adate, k1);
|
||||||
|
while (TRUE) {
|
||||||
|
adate += synmonth;
|
||||||
|
k2 = k1 + 1;
|
||||||
|
nt2 = meanphase(adate, k2);
|
||||||
|
if (nt1 <= sdate && nt2 > sdate)
|
||||||
|
break;
|
||||||
|
nt1 = nt2;
|
||||||
|
k1 = k2;
|
||||||
|
}
|
||||||
|
phases [0] = truephase (k1, 0.0);
|
||||||
|
phases [1] = truephase (k1, 0.25);
|
||||||
|
phases [2] = truephase (k1, 0.5);
|
||||||
|
phases [3] = truephase (k1, 0.75);
|
||||||
|
phases [4] = truephase (k2, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PHASEHUNT2 -- Find time of phases of the moon which surround
|
||||||
|
* the current date. Two phases are found.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
phasehunt2( double sdate, double phases[2], double which[2] )
|
||||||
|
{
|
||||||
|
double phases5[5];
|
||||||
|
|
||||||
|
phasehunt5( sdate, phases5 );
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* KEPLER -- Solve the equation of Kepler.
|
||||||
|
*/
|
||||||
|
static double
|
||||||
|
kepler( double m, double ecc )
|
||||||
|
{
|
||||||
|
double e, delta;
|
||||||
|
#define EPSILON 1E-6
|
||||||
|
|
||||||
|
e = m = torad(m);
|
||||||
|
do {
|
||||||
|
delta = e - ecc * sin(e) - m;
|
||||||
|
e -= delta / (1 - ecc * cos(e));
|
||||||
|
} while (abs (delta) > EPSILON);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PHASE -- Calculate phase of moon as a fraction:
|
||||||
|
*
|
||||||
|
* The argument is the time for which the phase is requested,
|
||||||
|
* expressed as a Julian date and fraction. Returns the terminator
|
||||||
|
* phase angle as a percentage of a full circle (i.e., 0 to 1),
|
||||||
|
* and stores into pointer arguments the illuminated fraction of
|
||||||
|
* the Moon's disc, the Moon's age in days and fraction, the
|
||||||
|
* distance of the Moon from the centre of the Earth, and the
|
||||||
|
* angular diameter subtended by the Moon as seen by an observer
|
||||||
|
* at the centre of the Earth.
|
||||||
|
*
|
||||||
|
* pphase: Illuminated fraction
|
||||||
|
* mage: Age of moon in days
|
||||||
|
* dist: Distance in kilometres
|
||||||
|
* angdia: Angular diameter in degrees
|
||||||
|
* sudist: Distance to Sun
|
||||||
|
* suangdia: Sun's angular diameter
|
||||||
|
*/
|
||||||
|
double
|
||||||
|
phase( double pdate, double* pphase, double* mage, double* dist, double* angdia, double* sudist, double* suangdia )
|
||||||
|
{
|
||||||
|
|
||||||
|
double Day, N, M, Ec, Lambdasun, ml, MM, MN, Ev, Ae, A3, MmP,
|
||||||
|
mEc, A4, lP, V, lPP, NP, y, x, Lambdamoon, BetaM,
|
||||||
|
MoonAge, MoonPhase,
|
||||||
|
MoonDist, MoonDFrac, MoonAng, MoonPar,
|
||||||
|
F, SunDist, SunAng;
|
||||||
|
|
||||||
|
/* Calculation of the Sun's position */
|
||||||
|
|
||||||
|
Day = pdate - epoch; /* Date within epoch */
|
||||||
|
N = fixangle((360 / 365.2422) * Day); /* Mean anomaly of the Sun */
|
||||||
|
M = fixangle(N + elonge - elongp); /* Convert from perigee
|
||||||
|
co-ordinates to epoch 1980.0 */
|
||||||
|
Ec = kepler(M, eccent); /* Solve equation of Kepler */
|
||||||
|
Ec = sqrt((1 + eccent) / (1 - eccent)) * tan(Ec / 2);
|
||||||
|
Ec = 2 * todeg(atan(Ec)); /* True anomaly */
|
||||||
|
Lambdasun = fixangle(Ec + elongp); /* Sun's geocentric ecliptic
|
||||||
|
longitude */
|
||||||
|
/* Orbital distance factor */
|
||||||
|
F = ((1 + eccent * cos(torad(Ec))) / (1 - eccent * eccent));
|
||||||
|
SunDist = sunsmax / F; /* Distance to Sun in km */
|
||||||
|
SunAng = F * sunangsiz; /* Sun's angular size in degrees */
|
||||||
|
|
||||||
|
|
||||||
|
/* Calculation of the Moon's position */
|
||||||
|
|
||||||
|
/* Moon's mean longitude */
|
||||||
|
ml = fixangle(13.1763966 * Day + mmlong);
|
||||||
|
|
||||||
|
/* Moon's mean anomaly */
|
||||||
|
MM = fixangle(ml - 0.1114041 * Day - mmlongp);
|
||||||
|
|
||||||
|
/* Moon's ascending node mean longitude */
|
||||||
|
MN = fixangle(mlnode - 0.0529539 * Day);
|
||||||
|
|
||||||
|
/* Evection */
|
||||||
|
Ev = 1.2739 * sin(torad(2 * (ml - Lambdasun) - MM));
|
||||||
|
|
||||||
|
/* Annual equation */
|
||||||
|
Ae = 0.1858 * sin(torad(M));
|
||||||
|
|
||||||
|
/* Correction term */
|
||||||
|
A3 = 0.37 * sin(torad(M));
|
||||||
|
|
||||||
|
/* Corrected anomaly */
|
||||||
|
MmP = MM + Ev - Ae - A3;
|
||||||
|
|
||||||
|
/* Correction for the equation of the centre */
|
||||||
|
mEc = 6.2886 * sin(torad(MmP));
|
||||||
|
|
||||||
|
/* Another correction term */
|
||||||
|
A4 = 0.214 * sin(torad(2 * MmP));
|
||||||
|
|
||||||
|
/* Corrected longitude */
|
||||||
|
lP = ml + Ev + mEc - Ae + A4;
|
||||||
|
|
||||||
|
/* Variation */
|
||||||
|
V = 0.6583 * sin(torad(2 * (lP - Lambdasun)));
|
||||||
|
|
||||||
|
/* True longitude */
|
||||||
|
lPP = lP + V;
|
||||||
|
|
||||||
|
/* Corrected longitude of the node */
|
||||||
|
NP = MN - 0.16 * sin(torad(M));
|
||||||
|
|
||||||
|
/* Y inclination coordinate */
|
||||||
|
y = sin(torad(lPP - NP)) * cos(torad(minc));
|
||||||
|
|
||||||
|
/* X inclination coordinate */
|
||||||
|
x = cos(torad(lPP - NP));
|
||||||
|
|
||||||
|
/* Ecliptic longitude */
|
||||||
|
Lambdamoon = todeg(atan2(y, x));
|
||||||
|
Lambdamoon += NP;
|
||||||
|
|
||||||
|
/* Ecliptic latitude */
|
||||||
|
BetaM = todeg(asin(sin(torad(lPP - NP)) * sin(torad(minc))));
|
||||||
|
|
||||||
|
/* Calculation of the phase of the Moon */
|
||||||
|
|
||||||
|
/* Age of the Moon in degrees */
|
||||||
|
MoonAge = lPP - Lambdasun;
|
||||||
|
|
||||||
|
/* Phase of the Moon */
|
||||||
|
MoonPhase = (1 - cos(torad(MoonAge))) / 2;
|
||||||
|
|
||||||
|
/* Calculate distance of moon from the centre of the Earth */
|
||||||
|
|
||||||
|
MoonDist = (msmax * (1 - mecc * mecc)) /
|
||||||
|
(1 + mecc * cos(torad(MmP + mEc)));
|
||||||
|
|
||||||
|
/* Calculate Moon's angular diameter */
|
||||||
|
|
||||||
|
MoonDFrac = MoonDist / msmax;
|
||||||
|
MoonAng = mangsiz / MoonDFrac;
|
||||||
|
|
||||||
|
/* Calculate Moon's parallax */
|
||||||
|
|
||||||
|
MoonPar = mparallax / MoonDFrac;
|
||||||
|
|
||||||
|
*pphase = MoonPhase;
|
||||||
|
*mage = synmonth * (fixangle(MoonAge) / 360.0);
|
||||||
|
*dist = MoonDist;
|
||||||
|
*angdia = MoonAng;
|
||||||
|
*sudist = SunDist;
|
||||||
|
*suangdia = SunAng;
|
||||||
|
return fixangle(MoonAge) / 360.0;
|
||||||
|
}
|
||||||
46
libs/phoon_14Aug2014/astro.h
Normal file
46
libs/phoon_14Aug2014/astro.h
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef _ASTRO_H_
|
||||||
|
#define _ASTRO_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UNIX_TO_JULIAN -- Convert internal Unix date/time to astronomical
|
||||||
|
* Julian time (i.e. Julian date plus day fraction, expressed as
|
||||||
|
* a double).
|
||||||
|
*/
|
||||||
|
double unix_to_julian( time_t t );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PHASEHUNT5 -- Find time of phases of the moon which surround
|
||||||
|
* the current date. Five phases are found, starting
|
||||||
|
* and ending with the new moons which bound the
|
||||||
|
* current lunation.
|
||||||
|
*/
|
||||||
|
void phasehunt5( double sdate, double phases[5] );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PHASEHUNT2 -- Find time of phases of the moon which surround
|
||||||
|
* the current date. Two phases are found.
|
||||||
|
*/
|
||||||
|
void phasehunt2( double sdate, double phases[2], double which[2] );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PHASE -- Calculate phase of moon as a fraction:
|
||||||
|
*
|
||||||
|
* The argument is the time for which the phase is requested,
|
||||||
|
* expressed as a Julian date and fraction. Returns the terminator
|
||||||
|
* phase angle as a percentage of a full circle (i.e., 0 to 1),
|
||||||
|
* and stores into pointer arguments the illuminated fraction of
|
||||||
|
* the Moon's disc, the Moon's age in days and fraction, the
|
||||||
|
* distance of the Moon from the centre of the Earth, and the
|
||||||
|
* angular diameter subtended by the Moon as seen by an observer
|
||||||
|
* at the centre of the Earth.
|
||||||
|
*
|
||||||
|
* pphase: Illuminated fraction
|
||||||
|
* mage: Age of moon in days
|
||||||
|
* dist: Distance in kilometres
|
||||||
|
* angdia: Angular diameter in degrees
|
||||||
|
* sudist: Distance to Sun
|
||||||
|
* suangdia: Sun's angular diameter
|
||||||
|
*/
|
||||||
|
double phase( double pdate, double* pphase, double* mage, double* dist, double* angdia, double* sudist, double* suangdia );
|
||||||
|
|
||||||
|
#endif /* _ASTRO_H_ */
|
||||||
1048
libs/phoon_14Aug2014/date_parse.c
Normal file
1048
libs/phoon_14Aug2014/date_parse.c
Normal file
File diff suppressed because it is too large
Load diff
33
libs/phoon_14Aug2014/date_parse.h
Normal file
33
libs/phoon_14Aug2014/date_parse.h
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
/* date_parse.h - parse string dates into internal form
|
||||||
|
**
|
||||||
|
** Copyright © 1995 by Jef Poskanzer <jef@mail.acme.com>.
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
** SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DATE_PARSE_H_
|
||||||
|
#define _DATE_PARSE_H_
|
||||||
|
|
||||||
|
time_t date_parse( char* str );
|
||||||
|
|
||||||
|
#endif /* _DATE_PARSE_H_ */
|
||||||
23
libs/phoon_14Aug2014/phoon.1
Normal file
23
libs/phoon_14Aug2014/phoon.1
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
.TH phoon 1 "07 June 1988"
|
||||||
|
.SH NAME
|
||||||
|
phoon - show the PHase of the mOON
|
||||||
|
.SH SYNOPSIS
|
||||||
|
phoon
|
||||||
|
.RB -l
|
||||||
|
.IR lines ]
|
||||||
|
.RI [ date ]
|
||||||
|
.SH 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 quarter
|
||||||
|
or something like that, phoon
|
||||||
|
.I shows
|
||||||
|
you the phase with a cute little picture.
|
||||||
|
You can vary the size of the picture with the -l flag, but only some
|
||||||
|
sizes have pictures defined - other sizes use @'s.
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
date_parse(3)
|
||||||
|
.SH AUTHOR
|
||||||
|
Jef Poskanzer.
|
||||||
|
The moon-phase computation is from "moontool.c", by John Walker.
|
||||||
575
libs/phoon_14Aug2014/phoon.c
Normal file
575
libs/phoon_14Aug2014/phoon.c
Normal file
|
|
@ -0,0 +1,575 @@
|
||||||
|
/* phoon - show the phase of the moon
|
||||||
|
**
|
||||||
|
** ver date who remarks
|
||||||
|
** --- ------- --- -------------------------------------------------------------
|
||||||
|
** 03A 01apr95 JP Updated to use date_parse.
|
||||||
|
** 02A 07jun88 JP Changed the phase calculation to use code from John Walker's
|
||||||
|
** "moontool", increasing accuracy tremendously.
|
||||||
|
** Got rid of SINFORCOS, since Apple has probably fixed A/UX
|
||||||
|
** by now.
|
||||||
|
** 01I 03feb88 JP Added 32 lines.
|
||||||
|
** 01H 14jan88 JP Added 22 lines.
|
||||||
|
** 01G 05dec87 JP Added random sabotage to generate Hubert.
|
||||||
|
** Defeated text stuff for moons 28 or larger.
|
||||||
|
** 01F 13oct87 JP Added pumpkin19 in October. Added hubert29.
|
||||||
|
** 01E 14may87 JP Added #ifdef SINFORCOS to handle broken A/UX library.
|
||||||
|
** 01D 02apr87 JP Added 21 lines.
|
||||||
|
** 01C 26jan87 JP Added backgrounds for 29 and 18 lines.
|
||||||
|
** 01B 28dec86 JP Added -l flag, and backgrounds for 19 and 24 lines.
|
||||||
|
** 01A 08nov86 JP Translated from the ratfor version of 12nov85, which itself
|
||||||
|
** was translated from the Pascal version of 05apr79.
|
||||||
|
**
|
||||||
|
** Copyright (C) 1986,1987,1988,1995 by Jef Poskanzer <jef@mail.acme.com>.
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
** SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "date_parse.h"
|
||||||
|
#include "astro.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Global defines and declarations. */
|
||||||
|
|
||||||
|
#define SECSPERMINUTE 60
|
||||||
|
#define SECSPERHOUR (60 * SECSPERMINUTE)
|
||||||
|
#define SECSPERDAY (24 * SECSPERHOUR)
|
||||||
|
|
||||||
|
#define PI 3.1415926535897932384626433
|
||||||
|
|
||||||
|
#define DEFAULTNUMLINES 23
|
||||||
|
|
||||||
|
#define QUARTERLITLEN 16
|
||||||
|
#define QUARTERLITLENPLUSONE 17
|
||||||
|
|
||||||
|
/* If you change the aspect ratio, the canned backgrounds won't work. */
|
||||||
|
#define ASPECTRATIO 0.5
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
putseconds( long secs )
|
||||||
|
{
|
||||||
|
long days, hours, minutes;
|
||||||
|
|
||||||
|
days = secs / SECSPERDAY;
|
||||||
|
secs = secs - days * SECSPERDAY;
|
||||||
|
hours = secs / SECSPERHOUR;
|
||||||
|
secs = secs - hours * SECSPERHOUR;
|
||||||
|
minutes = secs / SECSPERMINUTE;
|
||||||
|
secs = secs - minutes * SECSPERMINUTE;
|
||||||
|
|
||||||
|
printf( "%ld %2ld:%02ld:%02ld", days, hours, minutes, secs );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
putmoon( time_t t, int numlines, char* atfiller )
|
||||||
|
{
|
||||||
|
static char background18[18][37] = {
|
||||||
|
" .----------. ",
|
||||||
|
" .--' o . `--. ",
|
||||||
|
" .'@ @@@@@@ O . . `. ",
|
||||||
|
" .'@@ @@@@@@@@ @@@@ . `. ",
|
||||||
|
" .' . @@@@@@@@ @@@@@@ . `. ",
|
||||||
|
" / @@ o @@@@@@. @@@@ O @\\ ",
|
||||||
|
" |@@@@ @@@@@@ @@| ",
|
||||||
|
" / @@@@@ `.-. . @@@@@@@@ . @@\\",
|
||||||
|
" | @@@@ --`-' . o @@@@@@@ |",
|
||||||
|
" |@ @@ @@@@@@ @@@ |",
|
||||||
|
" \\ @@ @ . () @@ @@@@@ /",
|
||||||
|
" | @ @@@ @@@ @@@ | ",
|
||||||
|
" \\ . @@ @\\ . . @@ o / ",
|
||||||
|
" `. @@@@ _\\ / . o .' ",
|
||||||
|
" `. @@ ()--- .' ",
|
||||||
|
" `. / | . o .' ",
|
||||||
|
" `--./ . .--' ",
|
||||||
|
" `----------' "};
|
||||||
|
static char background19[19][39] = {
|
||||||
|
" .----------. ",
|
||||||
|
" .--' o . `--. ",
|
||||||
|
" .-'@ @@@@@@ O . . `-. ",
|
||||||
|
" .' @@ @@@@@@@@ @@@@ . `. ",
|
||||||
|
" / . @@@@@@@@ @@@@@@ . \\ ",
|
||||||
|
" /@@ o @@@@@@. @@@@ O @\\ ",
|
||||||
|
" /@@@@ @@@@@@ @@@\\ ",
|
||||||
|
" . @@@@@ `.-./ . @@@@@@@@ . @@ .",
|
||||||
|
" | @@@@ --`-' . @@@@@@@ |",
|
||||||
|
" |@ @@ ` o @@@@@@ @@@@ |",
|
||||||
|
" | @@ o @@ @@@@@@ |",
|
||||||
|
" ` . @ @@ () @@@ @@@@ '",
|
||||||
|
" \\ @@ @@@@ . @@ . o / ",
|
||||||
|
" \\ @@@@ @@\\ . o / ",
|
||||||
|
" \\ . @@ _\\ / . .-. / ",
|
||||||
|
" `. . ()--- `-' .' ",
|
||||||
|
" `-. ./ | . o .-' ",
|
||||||
|
" `--./ . .--' ",
|
||||||
|
" `----------' "};
|
||||||
|
static char pumpkin19[19][39] = {
|
||||||
|
" @@@@@@@@@@@@ ",
|
||||||
|
" @@@@@@@@@@@@@@@@@@@@ ",
|
||||||
|
" @@@@@@@@@@@@@@@@@@@@@@@@@@ ",
|
||||||
|
" @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ",
|
||||||
|
" @@@@ @@@@@@@@ @@@@ ",
|
||||||
|
" @@@@@@ @@@@@@@@@@ @@@@@@ ",
|
||||||
|
" @@@@@@@@ @@@@@@@@@@@@ @@@@@@@@ ",
|
||||||
|
" @@@@@@@@@@ @@@@@@ @@@@@@ @@@@@@@@@@",
|
||||||
|
" @@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@",
|
||||||
|
" @@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@",
|
||||||
|
" @@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@",
|
||||||
|
" @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
|
||||||
|
" @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ",
|
||||||
|
" @@@@@ @@ @@@@@ ",
|
||||||
|
" @@@@@@ @@@@@@ ",
|
||||||
|
" @@@@@@@@ @@@@@@@@ ",
|
||||||
|
" @@@@@@@@@ @@@@@@@@@ ",
|
||||||
|
" @@@@@@@@@@@@@@@@@@@@ ",
|
||||||
|
" @@@@@@@@@@@@ "};
|
||||||
|
static char background21[21][43] = {
|
||||||
|
" .----------. ",
|
||||||
|
" .---' O . . `---. ",
|
||||||
|
" .-'@ @@@@@@ . @@@@@ `-. ",
|
||||||
|
" .'@@ @@@@@@@@@ @@@@@@@ . `. ",
|
||||||
|
" / o @@@@@@@@@ @@@@@@@ . \\ ",
|
||||||
|
" /@ o @@@@@@@@@. @@@@@@@ O \\ ",
|
||||||
|
" /@@@ . @@@@@@o @@@@@@@@@@ @@\\ ",
|
||||||
|
" /@@@@@ . @@@@@@@@@@@@@ o @@@\\ ",
|
||||||
|
" .@@@@@ O `.-./ . @@@@@@@@@@@@ @@ .",
|
||||||
|
" | @@@@ --`-' o @@@@@@@@ @@@@ |",
|
||||||
|
" |@ @@@ ` o . @@ . @@@@@@@ |",
|
||||||
|
" | @@ @ .-. @@@ @@@@@@@ |",
|
||||||
|
" ` . @ @@@ `-' . @@@@ @@@@ o '",
|
||||||
|
" \\ @@ @@@@@ . @@ . / ",
|
||||||
|
" \\ @@@@ @\\@@ / . O . o . / ",
|
||||||
|
" \\o @@ \\ \\ / . . / ",
|
||||||
|
" \\ . .\\.-.___ . . .-. / ",
|
||||||
|
" `. `-' `-'.' ",
|
||||||
|
" `-. o / | o O . .-' ",
|
||||||
|
" `---. . . .---' ",
|
||||||
|
" `----------' "};
|
||||||
|
static char background22[22][45] = {
|
||||||
|
" .------------. ",
|
||||||
|
" .--' o . . `--. ",
|
||||||
|
" .-' . O . . `-. ",
|
||||||
|
" .'@ @@@@@@@ . @@@@@ `. ",
|
||||||
|
" .'@@@ @@@@@@@@@@@ @@@@@@@ . `. ",
|
||||||
|
" / o @@@@@@@@@@@ @@@@@@@ . \\ ",
|
||||||
|
" /@@ o @@@@@@@@@@@. @@@@@@@ O \\ ",
|
||||||
|
" /@@@@ . @@@@@@@o @@@@@@@@@@ @@@\\ ",
|
||||||
|
" |@@@@@ . @@@@@@@@@@@@ @@@@| ",
|
||||||
|
" /@@@@@ O `.-./ . @@@@@@@@@@@ @@ \\",
|
||||||
|
" | @@@@ --`-' o . @@@@@@@ @@@@ |",
|
||||||
|
" |@ @@@ @@ @ ` o .-. @@ . @@@@@@ |",
|
||||||
|
" \\ @@@ `-' . @@@ @@@@@@ /",
|
||||||
|
" | . @ @@ @@@@@ . @@@@ @@@ o | ",
|
||||||
|
" \\ @@@@ @\\@@ / . O @@ . . / ",
|
||||||
|
" \\ o @@ \\ \\ / . . o / ",
|
||||||
|
" \\ . .\\.-.___ . . . .-. / ",
|
||||||
|
" `. `-' `-' .' ",
|
||||||
|
" `. o / | o O . .' ",
|
||||||
|
" `-. / . . .-' ",
|
||||||
|
" `--. . .--' ",
|
||||||
|
" `------------' "};
|
||||||
|
static char background23[23][47] = {
|
||||||
|
" .------------. ",
|
||||||
|
" .--' o . . `--. ",
|
||||||
|
" .-' . O . . `-. ",
|
||||||
|
" .-'@ @@@@@@@ . @@@@@ `-. ",
|
||||||
|
" /@@@ @@@@@@@@@@@ @@@@@@@ . \\ ",
|
||||||
|
" ./ o @@@@@@@@@@@ @@@@@@@ . \\. ",
|
||||||
|
" /@@ o @@@@@@@@@@@. @@@@@@@ O \\ ",
|
||||||
|
" /@@@@ . @@@@@@@o @@@@@@@@@@ @@@ \\ ",
|
||||||
|
" |@@@@@ . @@@@@@@@@@@@@ o @@@@| ",
|
||||||
|
" /@@@@@ O `.-./ . @@@@@@@@@@@@ @@ \\",
|
||||||
|
" | @@@@ --`-' o @@@@@@@@ @@@@ |",
|
||||||
|
" |@ @@@ ` o . @@ . @@@@@@@ |",
|
||||||
|
" | @@ @ .-. @@@ @@@@@@@ |",
|
||||||
|
" \\ . @ @@@ `-' . @@@@ @@@@ o /",
|
||||||
|
" | @@ @@@@@ . @@ . | ",
|
||||||
|
" \\ @@@@ @\\@@ / . O . o . / ",
|
||||||
|
" \\ o @@ \\ \\ / . . / ",
|
||||||
|
" `\\ . .\\.-.___ . . .-. /' ",
|
||||||
|
" \\ `-' `-' / ",
|
||||||
|
" `-. o / | o O . .-' ",
|
||||||
|
" `-. / . . .-' ",
|
||||||
|
" `--. . .--' ",
|
||||||
|
" `------------' "};
|
||||||
|
|
||||||
|
static char background24[24][49] = {
|
||||||
|
" .------------. ",
|
||||||
|
" .---' o . . `---. ",
|
||||||
|
" .-' . O . . `-. ",
|
||||||
|
" .'@ @@@@@@@ . @@@@@ `. ",
|
||||||
|
" .'@@ @@@@@@@@@@@ @@@@@@@ . `. ",
|
||||||
|
" / o @@@@@@@@@@@ @@@@@@@ . \\ ",
|
||||||
|
" /@ o @@@@@@@@@@@. @@@@@@@ O \\ ",
|
||||||
|
" /@@@ . @@@@@@@o @@@@@@@@@@ @@@ \\ ",
|
||||||
|
" /@@@@@ . @@@@@@@@@@@@@ o @@@@ \\ ",
|
||||||
|
" |@@@@ O `.-./ . @@@@@@@@@@@@ @@ | ",
|
||||||
|
" / @@@@ --`-' o @@@@@@@@ @@@@ \\",
|
||||||
|
" |@ @@@ @ ` . @@ @@@@@@@ |",
|
||||||
|
" | @ o @ @@@@@@@ |",
|
||||||
|
" \\ @@ .-. @@@ @@@@ o /",
|
||||||
|
" | . @ @@@ `-' . @@@@ | ",
|
||||||
|
" \\ @@ @@@@@ . @@ . / ",
|
||||||
|
" \\ @@@@ @\\@@ / . O . o . / ",
|
||||||
|
" \\ o @@ \\ \\ / . . / ",
|
||||||
|
" \\ . .\\.-.___ . . .-. / ",
|
||||||
|
" `. `-' `-' .' ",
|
||||||
|
" `. o / | o O . .' ",
|
||||||
|
" `-. / . . .-' ",
|
||||||
|
" `---. . .---' ",
|
||||||
|
" `------------' "};
|
||||||
|
static char background29[29][59] = {
|
||||||
|
" .--------------. ",
|
||||||
|
" .---' o . `---. ",
|
||||||
|
" .-' . O . . `-. ",
|
||||||
|
" .-' @@@@@@ . `-. ",
|
||||||
|
" .'@@ @@@@@@@@@@@ @@@@@@@ . `. ",
|
||||||
|
" .'@@@ @@@@@@@@@@@@@@ @@@@@@@@@ `. ",
|
||||||
|
" /@@@ o @@@@@@@@@@@@@@ @@@@@@@@@ O \\ ",
|
||||||
|
" / @@@@@@@@@@@@@@ @ @@@@@@@@@ @@ . \\ ",
|
||||||
|
" /@ o @@@@@@@@@@@ . @@ @@@@@@@@@@@ @@ \\ ",
|
||||||
|
" /@@@ . @@@@@@ o @ @@@@@@@@@@@@@ o @@@@ \\ ",
|
||||||
|
" /@@@@@ @ . @@@@@@@@@@@@@@ @@@@@ \\ ",
|
||||||
|
" |@@@@@ O `.-./ . . @@@@@@@@@@@@@ @@@ | ",
|
||||||
|
" / @@@@@ --`-' o @@@@@@@@@@@ @@@ . \\",
|
||||||
|
" |@ @@@@ . @ @ ` @ @@ . @@@@@@ |",
|
||||||
|
" | @@ o @@ . @@@@@@ |",
|
||||||
|
" | . @ @ @ o @@ o @@@@@@. |",
|
||||||
|
" \\ @ @ @ .-. @@@@ @@@ /",
|
||||||
|
" | @ @ @ `-' . @@@@ . . | ",
|
||||||
|
" \\ . o @ @@@@ . @@ . . / ",
|
||||||
|
" \\ @@@ @@@@@@ . o / ",
|
||||||
|
" \\ @@@@@ @@\\@@ / O . / ",
|
||||||
|
" \\ o @@@ \\ \\ / __ . . .--. / ",
|
||||||
|
" \\ . . \\.-.--- `--' / ",
|
||||||
|
" `. `-' . .' ",
|
||||||
|
" `. o / | ` O . .' ",
|
||||||
|
" `-. / | o .-' ",
|
||||||
|
" `-. . . .-' ",
|
||||||
|
" `---. . .---' ",
|
||||||
|
" `--------------' "};
|
||||||
|
static char hubert29[29][59] = {
|
||||||
|
" .--------------. ",
|
||||||
|
" .---' o . `---. ",
|
||||||
|
" .-' . O . . `-. ",
|
||||||
|
" .-' @@@@@@ . `-. ",
|
||||||
|
" .'@@ @@@@@@@@@@@ @@@@@@@ . `. ",
|
||||||
|
" .'@@@ @@@@@ ___====-_ _-====___ @ `. ",
|
||||||
|
" /@@@ o _--~~~#####// \\\\#####~~~--_ O \\ ",
|
||||||
|
" / _-~##########// ( ) \\\\##########~-_ . \\ ",
|
||||||
|
" /@ o -############// :\\^^/: \\\\############- @@ \\ ",
|
||||||
|
" /@@@ _~############// (@::@) \\\\############~_ @@ \\ ",
|
||||||
|
" /@@@ ~#############(( \\\\// ))#############~ @@ \\ ",
|
||||||
|
" |@@ -###############\\\\ (oo) //###############- @ | ",
|
||||||
|
" / @ -#################\\\\ / \"\" \\ //#################- . \\",
|
||||||
|
" |@ -###################\\\\/ \\//###################- |",
|
||||||
|
" | _#/:##########/\\######( /\\ )######/\\##########:\\#_ |",
|
||||||
|
" | :/ :#/\\#/\\#/\\/ \\#/\\##\\ : : /##/\\#/ \\/\\#/\\#/\\#: \\: |",
|
||||||
|
" \\ \" :/ V V \" V \\#\\: : : :/#/ V \" V V \\: \" /",
|
||||||
|
" | @ \" \" \" \" / : : : : \\ \" \" \" \" | ",
|
||||||
|
" \\ . o @ @@@@ ( : : : : ) @@ . . / ",
|
||||||
|
" \\ @@@ @@@@ __\\ : : : : /__ o / ",
|
||||||
|
" \\ @@@@@ @@\\@(vvv(VVV)(VVV)vvv) . / ",
|
||||||
|
" \\ o @@@ \\ \\ / __ . . .--. / ",
|
||||||
|
" \\ . . \\.-.--- `--' / ",
|
||||||
|
" `. `-' . .' ",
|
||||||
|
" `. o / | ` O . .' ",
|
||||||
|
" `-. / | o .-' ",
|
||||||
|
" `-. . . .-' ",
|
||||||
|
" `---. . .---' ",
|
||||||
|
" `--------------' "};
|
||||||
|
static char background32[32][65] = {
|
||||||
|
" .--------------. ",
|
||||||
|
" .----' o . `----. ",
|
||||||
|
" .-' . O . . `-. ",
|
||||||
|
" .-' @@@@@@ . `-. ",
|
||||||
|
" .'@ @@@@@@@@@@@ @@@@@@@@ . `. ",
|
||||||
|
" .'@@ @@@@@@@@@@@@@@ @@@@@@@@@@ `. ",
|
||||||
|
" .'@@@ o @@@@@@@@@@@@@@ @@@@@@@@@@ o `. ",
|
||||||
|
" /@@@ @@@@@@@@@@@@@@ @ @@@@@@@@@@ @@ . \\ ",
|
||||||
|
" / @@@@@@@@@@@ . @@ @@@@@@@@@@@@ @@ \\ ",
|
||||||
|
" /@ o . @@@@@@ o @ @@@@@@@@@@@@@@ o @@@@ \\ ",
|
||||||
|
" /@@@ . @@@@@@@@@@@@@@@ @@@@@ \\ ",
|
||||||
|
" /@@@@@ @ . @@@@@@@@@@@@@@ @@@ \\ ",
|
||||||
|
" |@@@@@ o `.-./ . @@@@@@@@@@@@ @@@ . | ",
|
||||||
|
" / @@@@@ __`-' o @@ . @@@@@@ \\",
|
||||||
|
" |@ @@@@ . @ ` @ @@ . @@@@@@ |",
|
||||||
|
" | @@ @ o @@@ o @@@@@@. |",
|
||||||
|
" | @ @@@@@ @@@ |",
|
||||||
|
" | . . @ @ @ o @@@@@ . . |",
|
||||||
|
" \\ @ .-. . @@@ . . /",
|
||||||
|
" | @ @ @ @ `-' . / ",
|
||||||
|
" \\ . @ @ . o / ",
|
||||||
|
" \\ o @@@@ . . / ",
|
||||||
|
" \\ @@@ @@@@@@ . o / ",
|
||||||
|
" \\ @@@@@ @@\\@@ / o . / ",
|
||||||
|
" \\ o @@@ \\ \\ / ___ . . .--. / ",
|
||||||
|
" `. . \\.-.--- `--' .' ",
|
||||||
|
" `. `-' . .' ",
|
||||||
|
" `. o / | O . .' ",
|
||||||
|
" `-. / | o .-' ",
|
||||||
|
" `-. . . .-' ",
|
||||||
|
" `----. . .----' ",
|
||||||
|
" `--------------' "};
|
||||||
|
|
||||||
|
static char qlits[4][16] = {
|
||||||
|
"New Moon + ",
|
||||||
|
"First Quarter +",
|
||||||
|
"Full Moon + ",
|
||||||
|
"Last Quarter + ",
|
||||||
|
};
|
||||||
|
static char nqlits[4][16] = {
|
||||||
|
"New Moon - ",
|
||||||
|
"First Quarter -",
|
||||||
|
"Full Moon - ",
|
||||||
|
"Last Quarter - ",
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tm* tmP;
|
||||||
|
double jd, pctphase, angphase, cphase, aom, cdist, cangdia, csund, csuang;
|
||||||
|
double phases[2], which[2];
|
||||||
|
long clocknow;
|
||||||
|
int atflrlen, atflridx, numcols, lin, col, midlin;
|
||||||
|
double mcap, yrad, xrad, y, xright, xleft;
|
||||||
|
int colright, colleft;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
/* Find the length of the atfiller string. */
|
||||||
|
atflrlen = strlen( atfiller );
|
||||||
|
|
||||||
|
/* Figure out the phase. */
|
||||||
|
jd = unix_to_julian( t );
|
||||||
|
pctphase = phase( jd, &cphase, &aom, &cdist, &cangdia, &csund, &csuang );
|
||||||
|
angphase = pctphase * 2.0 * PI;
|
||||||
|
mcap = -cos( angphase );
|
||||||
|
|
||||||
|
/* Get now for use as a random number. */
|
||||||
|
(void) time( &clocknow );
|
||||||
|
|
||||||
|
/* Randomly cheat and generate Hubert. */
|
||||||
|
if ( clocknow % 13 == 3 && cphase > 0.8 )
|
||||||
|
{
|
||||||
|
numlines = 29;
|
||||||
|
clocknow = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Figure out how big the moon is. */
|
||||||
|
yrad = numlines / 2.0;
|
||||||
|
xrad = yrad / ASPECTRATIO;
|
||||||
|
numcols = xrad * 2;
|
||||||
|
|
||||||
|
/* Figure out some other random stuff. */
|
||||||
|
midlin = numlines / 2;
|
||||||
|
phasehunt2( jd, phases, which );
|
||||||
|
|
||||||
|
/* Now output the moon, a slice at a time. */
|
||||||
|
atflridx = 0;
|
||||||
|
for ( lin = 0; lin < numlines; lin = lin + 1 )
|
||||||
|
{
|
||||||
|
/* Compute the edges of this slice. */
|
||||||
|
y = lin + 0.5 - yrad;
|
||||||
|
xright = xrad * sqrt( 1.0 - ( y * y ) / ( yrad * yrad ) );
|
||||||
|
xleft = -xright;
|
||||||
|
if ( angphase >= 0.0 && angphase < PI )
|
||||||
|
xleft = mcap * xleft;
|
||||||
|
else
|
||||||
|
xright = mcap * xright;
|
||||||
|
colleft = (int) (xrad + 0.5) + (int) (xleft + 0.5);
|
||||||
|
colright = (int) (xrad + 0.5) + (int) (xright + 0.5);
|
||||||
|
|
||||||
|
/* Now output the slice. */
|
||||||
|
for ( col = 0; col < colleft; ++col )
|
||||||
|
putchar( ' ' );
|
||||||
|
for ( ; col <= colright; ++col )
|
||||||
|
{
|
||||||
|
switch ( numlines )
|
||||||
|
{
|
||||||
|
case 18:
|
||||||
|
c = background18[lin][col];
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
tmP = localtime( &t );
|
||||||
|
if ( tmP->tm_mon == 9 &&
|
||||||
|
clocknow % ( 33 - tmP->tm_mday ) == 1 )
|
||||||
|
c = pumpkin19[lin][col];
|
||||||
|
else
|
||||||
|
c = background19[lin][col];
|
||||||
|
break;
|
||||||
|
case 21:
|
||||||
|
c = background21[lin][col];
|
||||||
|
break;
|
||||||
|
case 22:
|
||||||
|
c = background22[lin][col];
|
||||||
|
break;
|
||||||
|
case 23:
|
||||||
|
c = background23[lin][col];
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
c = background24[lin][col];
|
||||||
|
break;
|
||||||
|
case 29:
|
||||||
|
if ( clocknow % 23 == 3 )
|
||||||
|
c = hubert29[lin][col];
|
||||||
|
else
|
||||||
|
c = background29[lin][col];
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
c = background32[lin][col];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
c = '@';
|
||||||
|
}
|
||||||
|
if ( c != '@' )
|
||||||
|
putchar( c );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
putchar( atfiller[atflridx] );
|
||||||
|
atflridx = ( atflridx + 1 ) % atflrlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef notdef
|
||||||
|
for ( ; col <= numcols; ++col )
|
||||||
|
putchar( ' ' );
|
||||||
|
#endif /* notdef */
|
||||||
|
|
||||||
|
if ( numlines <= 27 )
|
||||||
|
{
|
||||||
|
/* Output the end-of-line information, if any. */
|
||||||
|
if ( lin == midlin - 2 )
|
||||||
|
{
|
||||||
|
fputs( "\t ", stdout );
|
||||||
|
fputs( qlits[(int) (which[0] * 4.0 + 0.001)], stdout );
|
||||||
|
}
|
||||||
|
else if ( lin == midlin - 1)
|
||||||
|
{
|
||||||
|
fputs( "\t ", stdout );
|
||||||
|
putseconds( (int) ( ( jd - phases[0] ) * SECSPERDAY ) );
|
||||||
|
}
|
||||||
|
else if ( lin == midlin )
|
||||||
|
{
|
||||||
|
fputs( "\t ", stdout );
|
||||||
|
fputs( nqlits[(int) (which[1] * 4.0 + 0.001)], stdout );
|
||||||
|
}
|
||||||
|
else if ( lin == midlin + 1 )
|
||||||
|
{
|
||||||
|
fputs( "\t ", stdout );
|
||||||
|
putseconds( (int) ( ( phases[1] - jd ) * SECSPERDAY ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
putchar( '\n' );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Main program. */
|
||||||
|
|
||||||
|
int
|
||||||
|
main( int argc, char** argv )
|
||||||
|
{
|
||||||
|
time_t t;
|
||||||
|
char buf[100];
|
||||||
|
int numlines, argn;
|
||||||
|
char* usage = "usage: %s [-l <lines>] [<date/time>]\n";
|
||||||
|
|
||||||
|
/* Parge args. */
|
||||||
|
argn = 1;
|
||||||
|
/* Check for -l flag. */
|
||||||
|
numlines = DEFAULTNUMLINES;
|
||||||
|
if ( argc - argn >= 1 )
|
||||||
|
{
|
||||||
|
if ( argv[argn][0] == '-' )
|
||||||
|
{
|
||||||
|
if ( argv[argn][1] != 'l' || argv[argn][2] != '\0' )
|
||||||
|
{
|
||||||
|
fprintf( stderr, usage, argv[0] );
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( argc - argn < 2 )
|
||||||
|
{
|
||||||
|
fprintf( stderr, usage, argv[0] );
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
|
if ( sscanf( argv[argn + 1], "%d", &numlines ) != 1 )
|
||||||
|
{
|
||||||
|
fprintf( stderr, usage, argv[0] );
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
|
argn += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Figure out what date and time to use. */
|
||||||
|
if ( argc - argn == 0 )
|
||||||
|
{
|
||||||
|
/* No arguments present - use the current date and time. */
|
||||||
|
t = time( (time_t) 0 );
|
||||||
|
}
|
||||||
|
else if ( argc - argn == 1 || argc - argn == 2 || argc - argn == 3 )
|
||||||
|
{
|
||||||
|
/* One, two, or three args - use them. */
|
||||||
|
strcpy( buf, argv[argn] );
|
||||||
|
if ( argc - argn > 1 )
|
||||||
|
{
|
||||||
|
strcat( buf, " " );
|
||||||
|
strcat( buf, argv[argn + 1] );
|
||||||
|
if ( argc - argn > 2 )
|
||||||
|
{
|
||||||
|
strcat( buf, " " );
|
||||||
|
strcat( buf, argv[argn + 2] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t = date_parse( buf );
|
||||||
|
if ( t <= 0 )
|
||||||
|
{
|
||||||
|
fprintf( stderr, "illegal date/time: %s\n", buf );
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Too many args! */
|
||||||
|
fprintf( stderr, usage, argv[0] );
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pseudo-randomly decide what the moon is made of, and print it. */
|
||||||
|
if ( t % 17 == 3 )
|
||||||
|
putmoon( t, numlines, "GREENCHEESE" );
|
||||||
|
else
|
||||||
|
putmoon( t, numlines, "@" );
|
||||||
|
|
||||||
|
/* All done. */
|
||||||
|
exit( 0 );
|
||||||
|
}
|
||||||
71
src/Moon.zig
Normal file
71
src/Moon.zig
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const c = @cImport({
|
||||||
|
@cInclude("time.h");
|
||||||
|
@cInclude("astro.h");
|
||||||
|
});
|
||||||
|
|
||||||
|
pub const Phase = struct {
|
||||||
|
phase: f64, // 0.0 to 1.0 (0=new, 0.25=first quarter, 0.5=full, 0.75=last quarter)
|
||||||
|
illuminated: f64, // 0.0 to 1.0
|
||||||
|
age_days: f64, // Age in days
|
||||||
|
distance_km: f64,
|
||||||
|
angular_diameter: f64,
|
||||||
|
|
||||||
|
pub fn emoji(self: Phase) []const u8 {
|
||||||
|
const p = self.phase;
|
||||||
|
if (p < 0.0625) return "🌑"; // New moon
|
||||||
|
if (p < 0.1875) return "🌒"; // Waxing crescent
|
||||||
|
if (p < 0.3125) return "🌓"; // First quarter
|
||||||
|
if (p < 0.4375) return "🌔"; // Waxing gibbous
|
||||||
|
if (p < 0.5625) return "🌕"; // Full moon
|
||||||
|
if (p < 0.6875) return "🌖"; // Waning gibbous
|
||||||
|
if (p < 0.8125) return "🌗"; // Last quarter
|
||||||
|
if (p < 0.9375) return "🌘"; // Waning crescent
|
||||||
|
return "🌑"; // New moon
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn day(self: Phase) u8 {
|
||||||
|
return @intFromFloat(@round(self.age_days));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn getPhase(timestamp: i64) Phase {
|
||||||
|
const julian = c.unix_to_julian(@intCast(timestamp));
|
||||||
|
|
||||||
|
var illuminated: f64 = 0;
|
||||||
|
var age_days: f64 = 0;
|
||||||
|
var distance: f64 = 0;
|
||||||
|
var angular_diameter: f64 = 0;
|
||||||
|
var sun_distance: f64 = 0;
|
||||||
|
var sun_angular_diameter: f64 = 0;
|
||||||
|
|
||||||
|
const phase_angle = c.phase(
|
||||||
|
julian,
|
||||||
|
&illuminated,
|
||||||
|
&age_days,
|
||||||
|
&distance,
|
||||||
|
&angular_diameter,
|
||||||
|
&sun_distance,
|
||||||
|
&sun_angular_diameter,
|
||||||
|
);
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.phase = phase_angle,
|
||||||
|
.illuminated = illuminated,
|
||||||
|
.age_days = age_days,
|
||||||
|
.distance_km = distance,
|
||||||
|
.angular_diameter = angular_diameter,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
test "moon phase calculation" {
|
||||||
|
// Test a known date: 2024-01-01 00:00:00 UTC
|
||||||
|
const timestamp: i64 = 1704067200;
|
||||||
|
const moon = getPhase(timestamp);
|
||||||
|
|
||||||
|
try std.testing.expect(moon.phase >= 0.0 and moon.phase <= 1.0);
|
||||||
|
try std.testing.expect(moon.illuminated >= 0.0 and moon.illuminated <= 1.0);
|
||||||
|
try std.testing.expect(moon.age_days >= 0.0 and moon.age_days <= 29.53);
|
||||||
|
try std.testing.expect(moon.distance_km > 0);
|
||||||
|
}
|
||||||
|
|
@ -64,8 +64,8 @@ pub const help_page =
|
||||||
\\ %f # temperature (feels like)
|
\\ %f # temperature (feels like)
|
||||||
\\ %w # wind
|
\\ %w # wind
|
||||||
\\ %l # location
|
\\ %l # location
|
||||||
\\ %m # * moon phase emoji
|
\\ %m # moon phase emoji
|
||||||
\\ %M # * moon day
|
\\ %M # moon day
|
||||||
\\ %p # precipitation (mm)
|
\\ %p # precipitation (mm)
|
||||||
\\ %o # probability of precipitation
|
\\ %o # probability of precipitation
|
||||||
\\ %P # pressure (hPa)
|
\\ %P # pressure (hPa)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ const std = @import("std");
|
||||||
const types = @import("../weather/types.zig");
|
const types = @import("../weather/types.zig");
|
||||||
const emoji = @import("emoji.zig");
|
const emoji = @import("emoji.zig");
|
||||||
const utils = @import("utils.zig");
|
const utils = @import("utils.zig");
|
||||||
|
const Moon = @import("../Moon.zig");
|
||||||
|
|
||||||
pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData, format: []const u8, use_imperial: bool) ![]const u8 {
|
pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData, format: []const u8, use_imperial: bool) ![]const u8 {
|
||||||
var output: std.ArrayList(u8) = .empty;
|
var output: std.ArrayList(u8) = .empty;
|
||||||
|
|
@ -52,8 +53,16 @@ pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData, format:
|
||||||
const unit = if (use_imperial) "inHg" else "hPa";
|
const unit = if (use_imperial) "inHg" else "hPa";
|
||||||
try writer.print("{d:.2} {s}", .{ pressure, unit });
|
try writer.print("{d:.2} {s}", .{ pressure, unit });
|
||||||
},
|
},
|
||||||
'm' => try writer.print("🌕", .{}), // Moon phase placeholder
|
'm' => {
|
||||||
'M' => try writer.print("15", .{}), // Moon day placeholder
|
const now = std.time.timestamp();
|
||||||
|
const moon = Moon.getPhase(now);
|
||||||
|
try writer.print("{s}", .{moon.emoji()});
|
||||||
|
},
|
||||||
|
'M' => {
|
||||||
|
const now = std.time.timestamp();
|
||||||
|
const moon = Moon.getPhase(now);
|
||||||
|
try writer.print("{d}", .{moon.day()});
|
||||||
|
},
|
||||||
'o' => try writer.print("0%", .{}), // Probability of precipitation placeholder
|
'o' => try writer.print("0%", .{}), // Probability of precipitation placeholder
|
||||||
'D' => try writer.print("06:00", .{}), // Dawn placeholder
|
'D' => try writer.print("06:00", .{}), // Dawn placeholder
|
||||||
'S' => try writer.print("07:30", .{}), // Sunrise placeholder
|
'S' => try writer.print("07:30", .{}), // Sunrise placeholder
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue