• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

visgl / deck.gl / 13122625430

03 Feb 2025 08:52PM UTC coverage: 91.635%. Remained the same
13122625430

Pull #9399

github

web-flow
Merge 790aa8b61 into 276508372
Pull Request #9399: chore(deps): bump actions/setup-node from 4.0.0 to 4.2.0

6689 of 7324 branches covered (91.33%)

Branch coverage included in aggregate %.

54089 of 59002 relevant lines covered (91.67%)

14875.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/modules/core/src/effects/lighting/suncalc.ts
1
// deck.gl
×
2
// SPDX-License-Identifier: MIT
×
3
// Copyright (c) vis.gl contributors
×
4

×
5
// sun position calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas
×
6
// and inspired by https://github.com/mourner/suncalc/blob/master/suncalc.js
×
7
const DEGREES_TO_RADIANS = Math.PI / 180;
×
8

×
9
const DAY_IN_MS = 1000 * 60 * 60 * 24;
×
10
const JD1970 = 2440588; // Julian Day year 1970
×
11
const JD2000 = 2451545; // Julian Day year 2000
×
12

×
13
// This angle ε [epsilon] is called the obliquity of the ecliptic and its value at the beginning of 2000 was 23.4397°
×
14
const e = DEGREES_TO_RADIANS * 23.4397; // obliquity of the Earth
×
15

×
16
// Refer https://www.aa.quae.nl/en/reken/zonpositie.html
×
17
// "The Mean Anomaly" section for explanation
×
18
const M0 = 357.5291; // Earth mean anomaly on start day
×
19
const M1 = 0.98560028; // Earth angle traverses on average per day seen from the sun
×
20

×
21
const THETA0 = 280.147; // The sidereal time (in degrees) at longitude 0° at the instant defined by JD2000
×
22
const THETA1 = 360.9856235; // The rate of change of the sidereal time, in degrees per day.
×
23

×
24
export function getSolarPosition(timestamp, latitude, longitude) {
×
25
  const longitudeWestInRadians = DEGREES_TO_RADIANS * -longitude;
×
26
  const phi = DEGREES_TO_RADIANS * latitude;
×
27
  const d = toDays(timestamp);
×
28

×
29
  const c = getSunCoords(d);
×
30
  // hour angle
×
31
  const H = getSiderealTime(d, longitudeWestInRadians) - c.rightAscension;
×
32

×
33
  // https://www.aa.quae.nl/en/reken/zonpositie.html
×
34
  // The altitude is 0° at the horizon, +90° in the zenith (straight over your head), and −90° in the nadir (straight down).
×
35
  // The azimuth is the direction along the horizon, which we measure from south to west.
×
36
  // South has azimuth 0°, west +90°, north +180°, and east +270° (or −90°, that's the same thing).
×
37
  return {
×
38
    azimuth: getAzimuth(H, phi, c.declination),
×
39
    altitude: getAltitude(H, phi, c.declination)
×
40
  };
×
41
}
×
42

×
43
export function getSunlightDirection(timestamp, latitude, longitude) {
×
44
  const {azimuth, altitude} = getSolarPosition(timestamp, latitude, longitude);
×
45

×
46
  // solar position to light direction
×
47
  return [
×
48
    Math.sin(azimuth) * Math.cos(altitude),
×
49
    Math.cos(azimuth) * Math.cos(altitude),
×
50
    -Math.sin(altitude)
×
51
  ];
×
52
}
×
53

×
54
function toJulianDay(timestamp) {
×
55
  return timestamp / DAY_IN_MS - 0.5 + JD1970;
×
56
}
×
57

×
58
function toDays(timestamp) {
×
59
  return toJulianDay(timestamp) - JD2000;
×
60
}
×
61

×
62
function getRightAscension(eclipticLongitude, b) {
×
63
  const lambda = eclipticLongitude;
×
64
  return Math.atan2(Math.sin(lambda) * Math.cos(e) - Math.tan(b) * Math.sin(e), Math.cos(lambda));
×
65
}
×
66

×
67
function getDeclination(eclipticLongitude, b) {
×
68
  const lambda = eclipticLongitude;
×
69
  return Math.asin(Math.sin(b) * Math.cos(e) + Math.cos(b) * Math.sin(e) * Math.sin(lambda));
×
70
}
×
71

×
72
function getAzimuth(hourAngle, latitudeInRadians, declination) {
×
73
  const H = hourAngle;
×
74
  const phi = latitudeInRadians;
×
75
  const delta = declination;
×
76
  return Math.atan2(Math.sin(H), Math.cos(H) * Math.sin(phi) - Math.tan(delta) * Math.cos(phi));
×
77
}
×
78

×
79
function getAltitude(hourAngle, latitudeInRadians, declination) {
×
80
  const H = hourAngle;
×
81
  const phi = latitudeInRadians;
×
82
  const delta = declination;
×
83
  return Math.asin(Math.sin(phi) * Math.sin(delta) + Math.cos(phi) * Math.cos(delta) * Math.cos(H));
×
84
}
×
85

×
86
// https://www.aa.quae.nl/en/reken/zonpositie.html
×
87
// "The Observer section"
×
88
function getSiderealTime(dates, longitudeWestInRadians) {
×
89
  return DEGREES_TO_RADIANS * (THETA0 + THETA1 * dates) - longitudeWestInRadians;
×
90
}
×
91

×
92
function getSolarMeanAnomaly(days) {
×
93
  return DEGREES_TO_RADIANS * (M0 + M1 * days);
×
94
}
×
95

×
96
function getEclipticLongitude(meanAnomaly) {
×
97
  const M = meanAnomaly;
×
98
  // equation of center
×
99
  const C =
×
100
    DEGREES_TO_RADIANS * (1.9148 * Math.sin(M) + 0.02 * Math.sin(2 * M) + 0.0003 * Math.sin(3 * M));
×
101
  // perihelion of the Earth
×
102
  const P = DEGREES_TO_RADIANS * 102.9372;
×
103

×
104
  return M + C + P + Math.PI;
×
105
}
×
106

×
107
function getSunCoords(dates) {
×
108
  const M = getSolarMeanAnomaly(dates);
×
109
  const L = getEclipticLongitude(M);
×
110

×
111
  return {
×
112
    declination: getDeclination(L, 0),
×
113
    rightAscension: getRightAscension(L, 0)
×
114
  };
×
115
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc