mirror of https://github.com/espruino/BangleApps
Add files via upload
parent
140b1458d8
commit
389f566dde
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwgIifh/wAod//wECgP//+AAoMHAoPgCwQFBDAUfw///AFBjkD//8AoMYgPnEgUQgPB/4qCgeB/YFDwHxGAeA+AFEvHAAocdAoQCBh4CBgJFBh4CBAoNwg4FBhHA+AIBgkcgJSBAoMIg5SBAoIpB/E58EGAoP8n4FD/8f8EDAoQvBgfANYOfAYPwAoP/4AtBAoWAgP4SARfBAoZYB/0/Aod/AgKJCBQSVCj4FBUIStFXIrFFaIrdGADYA=="))
|
|
@ -0,0 +1,296 @@
|
|||
//Icons from https://icons8.com
|
||||
//Sun and Moon calculations from https://github.com/mourner/suncalc and https://gist.github.com/endel/dfe6bb2fbe679781948c
|
||||
|
||||
//pictures
|
||||
function getImg(i) {
|
||||
var data = {
|
||||
"NewMoon": "AD8AAH/4AHwPgDwA8BwADg4AAcMAADHAAA5gAAGYAABsAAAPAAADwAAA8AAAPAAADwAAA2AAAZgAAGcAADjAAAw4AAcHAAOA8APAHwPgAf/gAA/AAA==",
|
||||
"WaxingCrescentNorth" : "AD8AAH/4AHw/gDwH8BwA/g4AH8MAB/HAAf5gAD+YAA/sAAP/AAD/wAA/8AAP/AAD/wAA/2AAP5gAD+cAB/jAAfw4AH8HAD+A8B/AHw/gAf/gAA/AAA==",
|
||||
"WaningCrescentSouth" : "AD8AAH/4AHw/gDwH8BwA/g4AH8MAB/HAAf5gAD+YAA/sAAP/AAD/wAA/8AAP/AAD/wAA/2AAP5gAD+cAB/jAAfw4AH8HAD+A8B/AHw/gAf/gAA/AAA==",
|
||||
"FirstQuarterNorth" : "AD8AAH/4AHx/gDwf8BwH/g4B/8MAf/HAH/5gB/+YAf/sAH//AB//wAf/8AH//AB//wAf/2AH/5gB/+cAf/jAH/w4B/8HAf+A8H/AHx/gAf/gAA/AAA==",
|
||||
"FirstQuarterSouth" : "AD8AAH/4AH+PgD/g8B/4Dg/+AcP/gDH/4A5/+AGf/gBv/4AP/+AD//gA//4AP/+AD//gA3/4AZ/+AGf/gDj/4Aw/+AcH/gOA/4PAH+PgAf/gAA/AAA==",
|
||||
"WaxingGibbousNorth" : "AD8AAH/4AH3/gDz/8Bw//g4f/8MH//HB//5g//+YP//sD///A///wP//8D///A///wP//2D//5g//+cH//jB//w4f/8HD/+A8//AH3/gAf/gAA/AAA==",
|
||||
"WaxingGibbousSouth" : "AD8AAH/4AH/vgD/88B//Dg//4cP/+DH//g5//8Gf//Bv//wP//8D///A///wP//8D///A3//wZ//8Gf/+Dj//gw//4cH/8OA//PAH/vgAf/gAA/AAA==",
|
||||
"FullMoon" : "AD8AAH/4AH//gD//8B///g///8P///H///5///+f///v/////////////////////////3///5///+f///j///w///8H//+A///AH//gAf/gAA/AAA==",
|
||||
"WaningGibbousNorth" : "AD8AAH/4AH/vgD/88B//Dg//4cP/+DH//g5//8Gf//Bv//wP//8D///A///wP//8D///A3//wZ//8Gf/+Dj//gw//4cH/8OA//PAH/vgAf/gAA/AAA==",
|
||||
"WaningGibbousSouth" : "AD8AAH/4AH3/gDz/8Bw//g4f/8MH//HB//5g//+YP//sD///A///wP//8D///A///wP//2D//5g//+cH//jB//w4f/8HD/+A8//AH3/gAf/gAA/AAA==",
|
||||
"LastQuarterNorth" : "AD8AAH/4AH+PgD/g8B/4Dg/+AcP/gDH/4A5/+AGf/gBv/4AP/+AD//gA//4AP/+AD//gA3/4AZ/+AGf/gDj/4Aw/+AcH/gOA/4PAH+PgAf/gAA/AAA==",
|
||||
"LastQuarterSouth" : "AD8AAH/4AHx/gDwf8BwH/g4B/8MAf/HAH/5gB/+YAf/sAH//AB//wAf/8AH//AB//wAf/2AH/5gB/+cAf/jAH/w4B/8HAf+A8H/AHx/gAf/gAA/AAA==",
|
||||
"WaningCrescentNorth" : "AD8AAH/4AH8PgD+A8B/ADg/gAcP4ADH+AA5/AAGfwABv8AAP/AAD/wAA/8AAP/AAD/wAA38AAZ/AAGf4ADj+AAw/gAcH8AOA/gPAH8PgAf/gAA/AAA==",
|
||||
"WaxingCrescentSouth" : "AD8AAH/4AH8PgD+A8B/ADg/gAcP4ADH+AA5/AAGfwABv8AAP/AAD/wAA/8AAP/AAD/wAA38AAZ/AAGf4ADj+AAw/gAcH8AOA/gPAH8PgAf/gAA/AAA=="
|
||||
};
|
||||
return {
|
||||
width : 26, height : 26, bpp : 1,
|
||||
transparent : 0,
|
||||
buffer : E.toArrayBuffer(atob(data[i]))
|
||||
};
|
||||
}
|
||||
|
||||
//coordinates (will get from GPS later on real device)
|
||||
var lat = 52.96236,
|
||||
lon = 7.62571;
|
||||
|
||||
var PI = Math.PI,
|
||||
sin = Math.sin,
|
||||
cos = Math.cos,
|
||||
tan = Math.tan,
|
||||
asin = Math.asin,
|
||||
atan = Math.atan2,
|
||||
acos = Math.acos,
|
||||
rad = PI / 180;
|
||||
|
||||
// sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas
|
||||
// date/time constants and conversions
|
||||
var dayMs = 1000 * 60 * 60 * 24,
|
||||
J1970 = 2440588,
|
||||
J2000 = 2451545;
|
||||
|
||||
function toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; }
|
||||
function fromJulian(j) { return new Date((j + 0.5 - J1970) * dayMs); }
|
||||
function toDays(date) { return toJulian(date) - J2000; }
|
||||
|
||||
// general calculations for position
|
||||
var e = rad * 23.4397; // obliquity of the Earth
|
||||
function rightAscension(l, b) { return atan(sin(l) * cos(e) - tan(b) * sin(e), cos(l)); }
|
||||
function declination(l, b) { return asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l)); }
|
||||
function azimuth(H, phi, dec) { return atan(sin(H), cos(H) * sin(phi) - tan(dec) * cos(phi)); }
|
||||
function altitude(H, phi, dec) { return asin(sin(phi) * sin(dec) + cos(phi) * cos(dec) * cos(H)); }
|
||||
function siderealTime(d, lw) { return rad * (280.16 + 360.9856235 * d) - lw; }
|
||||
function astroRefraction(h) {
|
||||
if (h < 0) // the following formula works for positive altitudes only.
|
||||
h = 0; // if h = -0.08901179 a div/0 would occur.
|
||||
|
||||
// formula 16.4 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
|
||||
// 1.02 / tan(h + 10.26 / (h + 5.10)) h in degrees, result in arc minutes -> converted to rad:
|
||||
return 0.0002967 / Math.tan(h + 0.00312536 / (h + 0.08901179));
|
||||
}
|
||||
|
||||
// general sun calculations
|
||||
function solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); }
|
||||
function eclipticLongitude(M) {
|
||||
|
||||
var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center
|
||||
P = rad * 102.9372; // perihelion of the Earth
|
||||
|
||||
return M + C + P + PI;
|
||||
}
|
||||
|
||||
function sunCoords(d) {
|
||||
|
||||
var M = solarMeanAnomaly(d),
|
||||
L = eclipticLongitude(M);
|
||||
|
||||
return {
|
||||
dec: declination(L, 0),
|
||||
ra: rightAscension(L, 0)
|
||||
};
|
||||
}
|
||||
|
||||
var SunCalc = {};
|
||||
|
||||
// adds a custom time to the times config
|
||||
SunCalc.addTime = function (angle, riseName, setName) {
|
||||
times.push([angle, riseName, setName]);
|
||||
};
|
||||
|
||||
// moon calculations, based on http://aa.quae.nl/en/reken/hemelpositie.html formulas
|
||||
function moonCoords(d) { // geocentric ecliptic coordinates of the moon
|
||||
var L = rad * (218.316 + 13.176396 * d), // ecliptic longitude
|
||||
M = rad * (134.963 + 13.064993 * d), // mean anomaly
|
||||
F = rad * (93.272 + 13.229350 * d), // mean distance
|
||||
l = L + rad * 6.289 * sin(M), // longitude
|
||||
b = rad * 5.128 * sin(F), // latitude
|
||||
dt = 385001 - 20905 * cos(M); // distance to the moon in km
|
||||
|
||||
return {
|
||||
ra: rightAscension(l, b),
|
||||
dec: declination(l, b),
|
||||
dist: dt
|
||||
};
|
||||
}
|
||||
|
||||
SunCalc.getMoonPosition = function (date, lat, lng) {
|
||||
|
||||
var lw = rad * -lng,
|
||||
phi = rad * lat,
|
||||
d = toDays(date),
|
||||
c = moonCoords(d),
|
||||
H = siderealTime(d, lw) - c.ra,
|
||||
h = altitude(H, phi, c.dec),
|
||||
// formula 14.1 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
|
||||
pa = atan(sin(H), tan(phi) * cos(c.dec) - sin(c.dec) * cos(H));
|
||||
h = h + astroRefraction(h); // altitude correction for refraction
|
||||
return {
|
||||
azimuth: azimuth(H, phi, c.dec),
|
||||
altitude: h,
|
||||
distance: c.dist,
|
||||
parallacticAngle: pa
|
||||
};
|
||||
};
|
||||
|
||||
// calculations for illumination parameters of the moon,
|
||||
// based on http://idlastro.gsfc.nasa.gov/ftp/pro/astro/mphase.pro formulas and
|
||||
// Chapter 48 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
|
||||
|
||||
SunCalc.getMoonIllumination = function (date) {
|
||||
var year = date.getFullYear();
|
||||
var month = date.getMonth();
|
||||
var day = date.getDate();
|
||||
var Moon = {
|
||||
phases: ['new', 'waxing-crescent', 'first-quarter', 'waxing-gibbous', 'full', 'waning-gibbous', 'last-quarter', 'waning-crescent'],
|
||||
phase: function (year, month, day) {
|
||||
let c = 0;
|
||||
let e = 0;
|
||||
let jd = 0;
|
||||
let b = 0;
|
||||
if (month < 3) {
|
||||
year--;
|
||||
month += 12;
|
||||
}
|
||||
++month;
|
||||
c = 365.25 * year;
|
||||
e = 30.6 * month;
|
||||
jd = c + e + day - 694039.09; // jd is total days elapsed
|
||||
jd /= 29.5305882; // divide by the moon cycle
|
||||
b = parseInt(jd); // int(jd) -> b, take integer part of jd
|
||||
jd -= b; // subtract integer part to leave fractional part of original jd
|
||||
b = Math.round(jd * 8); // scale fraction from 0-8 and round
|
||||
if (b >= 8) b = 0; // 0 and 8 are the same so turn 8 into 0
|
||||
//print ({phase: b, name: Moon.phases[b]});
|
||||
return {phase: b, name: Moon.phases[b]};
|
||||
}
|
||||
};
|
||||
return (Moon.phase(year, month, day));
|
||||
};
|
||||
|
||||
function hoursLater(date, h) {
|
||||
return new Date(date.valueOf() + h * dayMs / 24);
|
||||
}
|
||||
|
||||
// calculations for moon rise/set times are based on http://www.stargazing.net/kepler/moonrise.html article
|
||||
|
||||
SunCalc.getMoonTimes = function (date, lat, lng, inUTC) {
|
||||
var t = new Date(date);
|
||||
if (inUTC) t.setUTCHours(0, 0, 0, 0);
|
||||
else t.setHours(0, 0, 0, 0);
|
||||
var hc = 0.133 * rad,
|
||||
h0 = SunCalc.getMoonPosition(t, lat, lng).altitude - hc,
|
||||
h1, h2, rise, set, a, b, xe, ye, d, roots, x1, x2, dx;
|
||||
|
||||
// go in 2-hour chunks, each time seeing if a 3-point quadratic curve crosses zero (which means rise or set)
|
||||
for (var i = 1; i <= 24; i += 2) {
|
||||
h1 = SunCalc.getMoonPosition(hoursLater(t, i), lat, lng).altitude - hc;
|
||||
h2 = SunCalc.getMoonPosition(hoursLater(t, i + 1), lat, lng).altitude - hc;
|
||||
a = (h0 + h2) / 2 - h1;
|
||||
b = (h2 - h0) / 2;
|
||||
xe = -b / (2 * a);
|
||||
ye = (a * xe + b) * xe + h1;
|
||||
d = b * b - 4 * a * h1;
|
||||
roots = 0;
|
||||
if (d >= 0) {
|
||||
dx = Math.sqrt(d) / (Math.abs(a) * 2);
|
||||
x1 = xe - dx;
|
||||
x2 = xe + dx;
|
||||
if (Math.abs(x1) <= 1) roots++;
|
||||
if (Math.abs(x2) <= 1) roots++;
|
||||
if (x1 < -1) x1 = x2;
|
||||
}
|
||||
if (roots === 1) {
|
||||
if (h0 < 0) rise = i + x1;
|
||||
else set = i + x1;
|
||||
} else if (roots === 2) {
|
||||
rise = i + (ye < 0 ? x2 : x1);
|
||||
set = i + (ye < 0 ? x1 : x2);
|
||||
}
|
||||
if (rise && set) break;
|
||||
h0 = h2;
|
||||
}
|
||||
var result = {};
|
||||
if (rise) result.rise = hoursLater(t, rise);
|
||||
if (set) result.set = hoursLater(t, set);
|
||||
if (!rise && !set) result[ye > 0 ? 'alwaysUp' : 'alwaysDown'] = true;
|
||||
return result;
|
||||
};
|
||||
|
||||
function getMPhaseComp (offset) {
|
||||
var date = new Date();
|
||||
date.setDate(date.getDate() + offset);
|
||||
var dd = String(date.getDate());
|
||||
if(dd<10){dd='0'+dd;}
|
||||
var mm = String(date.getMonth() + 1);
|
||||
if(mm<10){mm='0'+mm;}
|
||||
var yyyy = date.getFullYear();
|
||||
var phase = SunCalc.getMoonIllumination(date);
|
||||
return dd + "." + mm + "." + yyyy + ": "+ phase.name;
|
||||
}
|
||||
|
||||
function getMPhaseSim (offset) {
|
||||
var date = new Date();
|
||||
date.setDate(date.getDate() + offset);
|
||||
var dd = String(date.getDate());
|
||||
if(dd<10){dd='0'+dd;}
|
||||
var mm = String(date.getMonth() + 1);
|
||||
if(mm<10){mm='0'+mm;}
|
||||
var yyyy = date.getFullYear();
|
||||
var phase = SunCalc.getMoonIllumination(date);
|
||||
return phase.name;
|
||||
}
|
||||
|
||||
function drawMoonPhase(offset, x, y){
|
||||
if (lat >= 0 && lat <= 90){ //Northern hemisphere
|
||||
if (getMPhaseSim(offset) == "new") {g.drawImage(getImg("NewMoon"), x, y);}
|
||||
if (getMPhaseSim(offset) == "waxing-crescent") {g.drawImage(getImg("WaxingCrescentNorth"), x, y);}
|
||||
if (getMPhaseSim(offset) == "first-quarter") {g.drawImage(getImg("FirstQuarterNorth"), x, y);}
|
||||
if (getMPhaseSim(offset) == "waxing-gibbous") {g.drawImage(getImg("WaxingGibbousNorth"), x, y);}
|
||||
if (getMPhaseSim(offset) == "full") {g.drawImage(getImg("FullMoon"), x, y);}
|
||||
if (getMPhaseSim(offset) == "waning-gibbous") {g.drawImage(getImg("WaningGibbousNorth"), x, y);}
|
||||
if (getMPhaseSim(offset) == "last-quarter") {g.drawImage(getImg("LastQuarterNorth"), x, y);}
|
||||
if (getMPhaseSim(offset) == "waning-crescent") {g.drawImage(getImg("WaningCrescentNorth"), x, y);}
|
||||
}
|
||||
else { //Southern hemisphere
|
||||
if (getMPhaseSim(offset) == "new") {g.drawImage(getImg("NewMoon"), x, y);}
|
||||
if (getMPhaseSim(offset) == "waxing-crescent") {g.drawImage(getImg("WaxingCrescentSouth"), x, y);}
|
||||
if (getMPhaseSim(offset) == "first-quarter") {g.drawImage(getImg("FirstQuarterSouth"), x, y);}
|
||||
if (getMPhaseSim(offset) == "waxing-gibbous") {g.drawImage(getImg("WaxingGibbousSouth"), x, y);}
|
||||
if (getMPhaseSim(offset) == "full") {g.drawImage(getImg("FullMoon"), x, y);}
|
||||
if (getMPhaseSim(offset) == "waning-gibbous") {g.drawImage(getImg("WaningGibbousSouth"), x, y);}
|
||||
if (getMPhaseSim(offset) == "last-quarter") {g.drawImage(getImg("LastQuarterSouth"), x, y);}
|
||||
if (getMPhaseSim(offset) == "waning-crescent") {g.drawImage(getImg("WaningCrescentSouth"), x, y);}
|
||||
}
|
||||
}
|
||||
|
||||
function drawMoon(offset, x, y) {
|
||||
g.setFont("6x8");
|
||||
g.clear();
|
||||
g.drawString("Key1: increase day, Key3:decrease day",10,10);
|
||||
g.drawString(getMPhaseComp(offset),x,y-10);
|
||||
drawMoonPhase(offset, x, y);
|
||||
|
||||
g.drawString(getMPhaseComp(offset+2),x,y+40);
|
||||
drawMoonPhase(offset+2, x, y+50);
|
||||
|
||||
g.drawString(getMPhaseComp(offset+4),x,y+90);
|
||||
drawMoonPhase(offset+4, x, y+100);
|
||||
|
||||
g.drawString(getMPhaseComp(offset+6),x,y+140);
|
||||
drawMoonPhase(offset+6, x, y+150);
|
||||
}
|
||||
|
||||
function start() {
|
||||
var x = 10;
|
||||
var y = 40;
|
||||
var offsetMoon = 0;
|
||||
drawMoon(offsetMoon, x, y); //offset, x, y
|
||||
|
||||
//define button functions
|
||||
setWatch(function() {
|
||||
offsetMoon++; //jump to next day
|
||||
drawMoon(offsetMoon, x, y); //offset, x, y
|
||||
}, BTN1, {edge:"rising", debounce:50, repeat:true});
|
||||
setWatch(function() {
|
||||
offsetMoon--; //jump to next day
|
||||
drawMoon(offsetMoon, x, y); //offset, x, y
|
||||
}, BTN3, {edge:"rising", debounce:50, repeat:true});
|
||||
}
|
||||
|
||||
start();
|
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
Loading…
Reference in New Issue