Play with http://connettiva.eu/newton/
How to compute the distance between us and a planet?
https://packages.debian.org/source/sid/astronomical-almanac
C program written between 1987 and 2011
From http://www.moshier.net/
C program computes ephemerides of Sun, Moon, planets, comets, and stars using rigorous reduction methods from the _Astronomical Almanac_ and related sources. Includes PLAN404 series (see below) for positions of the planets, and a long-term extension of modern Lunar theory for the Moon's position. Reads ASCII file catalogues of stars and orbital elements. Displays all adjustments as it finds local azimuth and elevation, rise and set times, etc. Windows or MSDOS (Microsoft and Borland), Unix, VAX make files. Archive includes MSDOS executable program.
Quite complex. Better not to rewrite it.
Debian and derivatives
sudo apt-get install aa
Poll a server?
No thanks!
We convert the C program to JavaScript using emscripten (emcc)
gcc
assembler
machine code
linker
exe
clang
LLVM bytecode
machine code
linker
exe
emcc
LLVM bytecode
linker
asm.js
$ emcc -h
ERROR root: no input files
note that input files without a known suffix are
ignored, make sure your input files end with one of:
('.c', '.C', '.i', '.cpp', '.cxx', '.cc', '.c++',
'.CPP', '.CXX', '.CC', '.C++', '.ii', '.m', '.mi',
'.mm', '.mii', '.bc', '.o', '.obj', '.dylib', '.so',
'.a', '.ll', '.h', '.hxx', '.hpp', '.hh', '.H',
'.HXX', '.HPP', '.HH')
Surprisingly few changes
Basically I extracted the distance calculation algorithm
and made a standalone program of it.
It uses most of the .c files in the program.
Entry point: main in planet.c
This is the function to call from the browser
#include <stdio.h>
#include "consts.h"
int main(int argc, char* argv[]) {
double distance;
double julian_day;
int planet;
sscanf(argv[1], "%lf", &julian_day);
sscanf(argv[2], "%d", &planet);
distance = km_to_planet(julian_day, planet);
printf("%f\n", distance);
}
CC= emcc
NODE_CFLAGS= -O2 --closure 1 --emit-symbol-map
BROWSER_CFLAGS = -O2 --closure 1 --emit-symbol-map -s MODULARIZE=1 \
-s EXPORTED_FUNCTIONS="['_km_to_planet']"
...
PLANET_OBJS = planet.o planet_distance.o distance.o consts.o \
...
INCS = kep.h plantbl.h
all: aa conjunct moonrise planet
...
planet: $(PLANET_OBJS) $(INCS)
$(CC) $(NODE_CFLAGS) -o planet-node.js $(PLANET_OBJS) -lm
$(CC) $(BROWSER_CFLAGS) -o planet.js $(PLANET_OBJS) -lm
%.o: %c
$(CC) $(INCS) $<
The files are big but they contain all the libc functions needed by the algorithm, rewritten in asm.js
--closure 1 removed all the unused C functions
$ make -j
$ ll *js
-rw-rw-r-- 1 montra montra 234494 Jul 3 22:13 aa.js
-rw-rw-r-- 1 montra montra 210749 Jul 3 22:13 conjunct.js
-rw-rw-r-- 1 montra montra 811 Jun 24 16:41 julian_day.js
-rw-rw-r-- 1 montra montra 208694 Jul 3 22:13 moonrise.js
-rw-rw-r-- 1 montra montra 129124 Jul 3 22:13 planet.js
-rw-rw-r-- 1 montra montra 187395 Jul 3 22:13 planet-node.js
Command line. Inputs: julian date and the number of the planet
Browser module with Module declaration because of -s MODULARIZE=1
$ node planet-node.js $(node julian_day.js) 4 # Mars
386760399.250331
$ less planet-node.js # minified because of -O2
var f;f||(f=eval("(function() { try { return Module ||
{} } catch(e) { return {} } })()"));var ...
$ less planet.js
var Module = function(Module) {
Module = Module || {};
var e;e||(e=eval("(function() { try { return Module || {} } ...
Lists of the functions used by the modules
$ ll *symbols
-rw-rw-r-- 1 montra montra 2855 Jul 3 22:13 aa.js.symbols
-rw-rw-r-- 1 montra montra 2602 Jul 3 22:13 conjunct.js.symbols
-rw-rw-r-- 1 montra montra 2470 Jul 3 22:13 moonrise.js.symbols
-rw-rw-r-- 1 montra montra 1694 Jul 3 22:13 planet.js.symbols
-rw-rw-r-- 1 montra montra 2266 Jul 3 22:13 planet-node.js.symbols
$ less planet.js.symbols
da:_fabs
Db:_strlen
fa:_exp
ib:_g2plan
hb:_g3plan
...
The heap of the modules. It's either an array in the .js file or the .mem binary file. Tradeoffs:
Generated with -O2 and ontrolled by --memory-init-file
$ ll *mem
-rw-rw-r-- 1 montra montra 167792 Jul 3 22:13 aa.js.mem
-rw-rw-r-- 1 montra montra 50576 Jul 3 22:13 conjunct.js.mem
-rw-rw-r-- 1 montra montra 51088 Jul 3 22:13 moonrise.js.mem
-rw-rw-r-- 1 montra montra 152776 Jul 3 22:13 planet.js.mem
-rw-rw-r-- 1 montra montra 153344 Jul 3 22:13 planet-node.js.mem
$ cp planet.js planet.js.mem planet.js.symbols ../newton
$ cd !$
$ less index.html
...
<script src="planet.js"></script>
<script src="newton-client.bundle.js"></script>
...
$ less newton-client.js
// this makes the asm.js module available to JavaScript
var kmToPlanet = Module().cwrap("km_to_planet", "number",
["number", "number"]);
...
// computes the Julian date, with decimals
var now = new Date().getTime() / 86400000 + 2440587.5;
var distanceKm = Big(kmToPlanet(now, selectedPlanet.id));
// Big: https://github.com/MikeMcl/big.js
// arbitrary-precision decimal arithmetic
Repositories
web app https://github.com/pmontrasio/newton-says
asm.js module https://github.com/pmontrasio/astronomical-almanac-js
PS: If you like to know more about the planets of the
Solar System you'll love
https://bubbl.in/book/the-solar-system-by-marvin-danig
$ beefy newton-client.js:newton-client.bundle.js \
--url http://192.168.1.131:9966