forked from mourner/suncalc
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathsuncalc.js
106 lines (73 loc) · 2.09 KB
/
suncalc.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
(c) 2011-2015, Vladimir Agafonkin
SunCalc is a JavaScript library for calculating sun position and light phases.
https://github.com/mourner/suncalc
*/
var suncalc = (function () {
'use strict';
// shortcuts for easier to read formulas
var PI = Math.PI,
sin = Math.sin,
cos = Math.cos,
tan = Math.tan,
asin = Math.asin,
atan = Math.atan2,
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 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;
}
// 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)
};
}
// calculates sun position for a given date and latitude/longitude
return function(date, lat, lng) {
var lw = rad* -lng,
phi = rad*lat,
d = toDays(date),
c = sunCoords(d),
H = siderealTime(d, lw) - c.ra;
return {
azimuth: azimuth(H, phi, c.dec),
altitude: altitude(H, phi, c.dec)
};
};
}());