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):**
|
||||
- Airport code -> location mapping: [Openflights](https://github.com/jpatokal/openflights)
|
||||
- Ip address -> location mapping: [GeoLite2 City Database](https://github.com/maxmind/libmaxminddb)
|
||||
- Moon phase calculations (vendored): [Phoon](https://acme.com/software/phoon/)
|
||||
|
||||
## Performance Targets
|
||||
|
||||
|
|
|
|||
|
|
@ -20,15 +20,14 @@ Features not yet implemented in the Zig version:
|
|||
- lang query parameter support
|
||||
- Translation of weather conditions and text (54 languages)
|
||||
|
||||
## 5. Moon Phase Calculation
|
||||
- Real moon phase computation based on date
|
||||
- Moon phase emoji display
|
||||
- Moonday calculation
|
||||
|
||||
## 6. Astronomical Times
|
||||
## 5. Astronomical Times
|
||||
- Calculate dawn, sunrise, zenith, sunset, dusk times
|
||||
- Based on location coordinates and timezone
|
||||
- Display in custom format output
|
||||
|
||||
## 7. Json output
|
||||
## 6. Json output
|
||||
- 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", .{});
|
||||
|
||||
// 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
|
||||
const maxminddb = b.addLibrary(.{
|
||||
.name = "maxminddb",
|
||||
|
|
@ -74,8 +97,10 @@ pub fn build(b: *std.Build) void {
|
|||
});
|
||||
exe.root_module.addOptions("build_options", build_options);
|
||||
exe.root_module.addIncludePath(maxminddb_upstream.path("include"));
|
||||
exe.root_module.addIncludePath(b.path("libs/phoon_14Aug2014"));
|
||||
exe.root_module.addConfigHeader(maxminddb_config);
|
||||
exe.linkLibrary(maxminddb);
|
||||
exe.linkLibrary(phoon);
|
||||
exe.linkLibC();
|
||||
|
||||
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.addIncludePath(maxminddb_upstream.path("include"));
|
||||
tests.root_module.addIncludePath(b.path("libs/phoon_14Aug2014"));
|
||||
tests.root_module.addConfigHeader(maxminddb_config);
|
||||
tests.linkLibrary(maxminddb);
|
||||
tests.linkLibrary(phoon);
|
||||
tests.linkLibC();
|
||||
|
||||
const run_tests = b.addRunArtifact(tests);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
.url = "git+https://github.com/rockorager/zeit?ref=zig-0.15#7ac64d72dbfb1a4ad549102e7d4e232a687d32d8",
|
||||
.hash = "zeit-0.6.0-5I6bk36tAgATpSl9wjFmRPMqYN2Mn0JQHgIcRNcqDpJA",
|
||||
},
|
||||
.phoon = .{ .path = "libs/phoon_14Aug2014" },
|
||||
},
|
||||
.fingerprint = 0x710c2b57e81aa678,
|
||||
.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)
|
||||
\\ %w # wind
|
||||
\\ %l # location
|
||||
\\ %m # * moon phase emoji
|
||||
\\ %M # * moon day
|
||||
\\ %m # moon phase emoji
|
||||
\\ %M # moon day
|
||||
\\ %p # precipitation (mm)
|
||||
\\ %o # probability of precipitation
|
||||
\\ %P # pressure (hPa)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ const std = @import("std");
|
|||
const types = @import("../weather/types.zig");
|
||||
const emoji = @import("emoji.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 {
|
||||
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";
|
||||
try writer.print("{d:.2} {s}", .{ pressure, unit });
|
||||
},
|
||||
'm' => try writer.print("🌕", .{}), // Moon phase placeholder
|
||||
'M' => try writer.print("15", .{}), // Moon day placeholder
|
||||
'm' => {
|
||||
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
|
||||
'D' => try writer.print("06:00", .{}), // Dawn placeholder
|
||||
'S' => try writer.print("07:30", .{}), // Sunrise placeholder
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue