|
| 1 | +// Sun Position Calculations from https://github.com/mourner/suncalc |
| 2 | + |
| 3 | +// shortcuts for easier to read formulas |
| 4 | + |
| 5 | +var PI = Math.PI, |
| 6 | + sin = Math.sin, |
| 7 | + cos = Math.cos, |
| 8 | + tan = Math.tan, |
| 9 | + asin = Math.asin, |
| 10 | + atan = Math.atan2, |
| 11 | + acos = Math.acos, |
| 12 | + rad = PI / 180; |
| 13 | +// date/time constants and conversions |
| 14 | + |
| 15 | +var dayMs = 1000 * 60 * 60 * 24, |
| 16 | + J1970 = 2440588, |
| 17 | + J2000 = 2451545; |
| 18 | + |
| 19 | +function suncalc_toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; } |
| 20 | +function suncalc_fromJulian(j) { return new Date((j + 0.5 - J1970) * dayMs); } |
| 21 | +function suncalc_toDays(date) { return suncalc_toJulian(date) - J2000; } |
| 22 | + |
| 23 | + |
| 24 | +// general calculations for position |
| 25 | + |
| 26 | +var suncalc_e = rad * 23.4397; // obliquity of the Earth |
| 27 | + |
| 28 | +function rightAscension(l, b) { return atan(sin(l) * cos(suncalc_e) - tan(b) * sin(suncalc_e), cos(l)); } |
| 29 | +function declination(l, b) { return asin(sin(b) * cos(suncalc_e) + cos(b) * sin(suncalc_e) * sin(l)); } |
| 30 | + |
| 31 | +function suncalc_azimuth(H, phi, dec) { return atan(sin(H), cos(H) * sin(phi) - tan(dec) * cos(phi)); } |
| 32 | +function suncalc_altitude(H, phi, dec) { return asin(sin(phi) * sin(dec) + cos(phi) * cos(dec) * cos(H)); } |
| 33 | + |
| 34 | +function siderealTime(d, lw) { return rad * (280.16 + 360.9856235 * d) - lw; } |
| 35 | + |
| 36 | +// general sun calculations |
| 37 | + |
| 38 | +function solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); } |
| 39 | + |
| 40 | +function eclipticLongitude(M) { |
| 41 | + |
| 42 | + var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center |
| 43 | + P = rad * 102.9372; // perihelion of the Earth |
| 44 | + |
| 45 | + return M + C + P + PI; |
| 46 | +} |
| 47 | + |
| 48 | +function sunCoords(d) { |
| 49 | + |
| 50 | + var M = solarMeanAnomaly(d), |
| 51 | + L = eclipticLongitude(M); |
| 52 | + |
| 53 | + return { |
| 54 | + dec: declination(L, 0), |
| 55 | + ra: rightAscension(L, 0) |
| 56 | + }; |
| 57 | +} |
| 58 | + |
| 59 | +var SunCalc = {}; |
| 60 | + |
| 61 | + |
| 62 | +// calculates sun position for a given date and latitude/longitude |
| 63 | + |
| 64 | +SunCalc.getPosition = function (date, lat, lng) { |
| 65 | + |
| 66 | + var lw = rad * -lng, |
| 67 | + phi = rad * lat, |
| 68 | + d = suncalc_toDays(date), |
| 69 | + |
| 70 | + c = sunCoords(d), |
| 71 | + H = siderealTime(d, lw) - c.ra; |
| 72 | + |
| 73 | + return { |
| 74 | + azimuth: suncalc_azimuth(H, phi, c.dec), |
| 75 | + altitude: suncalc_altitude(H, phi, c.dec) |
| 76 | + }; |
| 77 | +}; |
| 78 | + |
0 commit comments