Skip to content

Instantly share code, notes, and snippets.

@mbostock
Forked from mbostock/.block
Last active March 10, 2019 08:11
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save mbostock/4712128 to your computer and use it in GitHub Desktop.
The Sun’s View of the Earth
license: gpl-3.0
redirect: https://observablehq.com/@mbostock/the-suns-view-of-the-earth
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
background: #fcfcfa;
}
.sun {
fill: red;
}
.stroke {
fill: #fff;
stroke: #000;
stroke-width: 1.5px;
}
.land {
fill: #222;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
var width = 960,
height = 960;
var π = Math.PI,
radians = π / 180,
degrees = 180 / π;
var projection = d3.geo.orthographic()
.clipAngle(90)
.scale(475)
.translate([width / 2, height / 2])
.precision(.1);
var path = d3.geo.path()
.projection(projection);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.append("circle")
.attr("class", "stroke")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
.attr("r", projection.scale());
svg.append("circle")
.attr("class", "sun")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
.attr("r", 2.5);
d3.json("/mbostock/raw/4090846/world-50m.json", function(error, world) {
if (error) throw error;
var land = svg.insert("path", ".sun")
.datum(topojson.feature(world, world.objects.land))
.attr("class", "land")
.attr("d", path);
redraw();
setInterval(redraw, 1000);
function redraw() {
var position = solarPosition(new Date);
projection.rotate([-position[0], -position[1]]);
land.attr("d", path);
}
});
function solarPosition(time) {
var centuries = (time - Date.UTC(2000, 0, 1, 12)) / 864e5 / 36525, // since J2000
longitude = (d3.time.day.utc.floor(time) - time) / 864e5 * 360 - 180;
return [
longitude - equationOfTime(centuries) * degrees,
solarDeclination(centuries) * degrees
];
}
// Equations based on NOAA’s Solar Calculator; all angles in radians.
// http://www.esrl.noaa.gov/gmd/grad/solcalc/
function equationOfTime(centuries) {
var e = eccentricityEarthOrbit(centuries),
m = solarGeometricMeanAnomaly(centuries),
l = solarGeometricMeanLongitude(centuries),
y = Math.tan(obliquityCorrection(centuries) / 2);
y *= y;
return y * Math.sin(2 * l)
- 2 * e * Math.sin(m)
+ 4 * e * y * Math.sin(m) * Math.cos(2 * l)
- 0.5 * y * y * Math.sin(4 * l)
- 1.25 * e * e * Math.sin(2 * m);
}
function solarDeclination(centuries) {
return Math.asin(Math.sin(obliquityCorrection(centuries)) * Math.sin(solarApparentLongitude(centuries)));
}
function solarApparentLongitude(centuries) {
return solarTrueLongitude(centuries) - (0.00569 + 0.00478 * Math.sin((125.04 - 1934.136 * centuries) * radians)) * radians;
}
function solarTrueLongitude(centuries) {
return solarGeometricMeanLongitude(centuries) + solarEquationOfCenter(centuries);
}
function solarGeometricMeanAnomaly(centuries) {
return (357.52911 + centuries * (35999.05029 - 0.0001537 * centuries)) * radians;
}
function solarGeometricMeanLongitude(centuries) {
var l = (280.46646 + centuries * (36000.76983 + centuries * 0.0003032)) % 360;
return (l < 0 ? l + 360 : l) / 180 * π;
}
function solarEquationOfCenter(centuries) {
var m = solarGeometricMeanAnomaly(centuries);
return (Math.sin(m) * (1.914602 - centuries * (0.004817 + 0.000014 * centuries))
+ Math.sin(m + m) * (0.019993 - 0.000101 * centuries)
+ Math.sin(m + m + m) * 0.000289) * radians;
}
function obliquityCorrection(centuries) {
return meanObliquityOfEcliptic(centuries) + 0.00256 * Math.cos((125.04 - 1934.136 * centuries) * radians) * radians;
}
function meanObliquityOfEcliptic(centuries) {
return (23 + (26 + (21.448 - centuries * (46.8150 + centuries * (0.00059 - centuries * 0.001813))) / 60) / 60) * radians;
}
function eccentricityEarthOrbit(centuries) {
return 0.016708634 - centuries * (0.000042037 + 0.0000001267 * centuries);
}
d3.select(self.frameElement).style("height", height + "px");
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment