Click to fast-forward. Based on the math here. No guarantees of accuracy, this is not legal advice. Made in honor of Pi Day — which I think is borderline numerology, a random and arbitrary mapping, but I respect the ability to create meaning in life ex nihilo.
Last active
September 23, 2015 19:25
-
-
Save tophtucker/0387ae2d06220b23e215 to your computer and use it in GitHub Desktop.
Earth orbit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link rel="stylesheet" href="style.css"> | |
<div id="ecliptic"></div> | |
<p>Date: <span id="date"></span><p> | |
<p>Distance from sun: <span id="radius"></span> AU</p> | |
<p>True anomaly: <span id="true-anomaly"></span>°</p> | |
<p>True anomaly: <span id="true-anomaly-pi"></span>π</p> | |
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
<script src="script.js" charset="utf-8"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ALL GOOD STUFF ADAPTED FROM THIS WONDERFUL OLD SITE: | |
// http://www.stargazing.net/kepler/ellipse.html | |
// angles are in degrees | |
// distances are in a.u. | |
//////////////////////////////////////////// | |
// dates | |
var dayToMs = 24*60*60*1000; | |
var msToDay = 1/dayToMs; | |
// trig | |
var degToRad = (2*Math.PI)/360; | |
var radToDeg = 1/degToRad; | |
function sin(x) { return Math.sin(x * degToRad); } | |
function cos(x) { return Math.cos(x * degToRad); } | |
// "Osculating Elements" | |
var abbrevs = { | |
"i": "Inclination", | |
"o": "Longitude of the Ascending Node", | |
"p": "Longitude of Perihelion", | |
"a": "Mean distance", | |
"n": "Daily motion", | |
"e": "Eccentricity", | |
"L": "Mean Longitude", | |
"JD": "Julian Date" | |
} | |
var earth = { | |
"i": 0.00041, | |
"o": 349.2, | |
"p": 102.8517, | |
"a": 1.0000200, | |
"n": 0.9855796, | |
"e": 0.0166967, | |
"L": 328.40353, | |
"JD": 2450680.5, | |
"datetime": new Date("August 20, 1997 00:00:00"), | |
"radius": 0.000042563739 | |
}; | |
var mars = { | |
"i": 1.84992, | |
"o": 49.5664, | |
"p": 336.0882, | |
"a": 1.5236365, | |
"n": 0.5240613, | |
"e": 0.0934231, | |
"L": 262.42784, | |
"JD": 2450680.5, | |
"datetime": new Date("August 20, 1997 00:00:00"), | |
"radius": 0.00002263 | |
}; | |
var sun = { | |
"radius": 0.004649 | |
} | |
// MATH | |
function meanAnomaly(satellite, time) { | |
var days = (time-satellite.datetime)*msToDay; | |
return ((satellite.n * days + satellite.L - satellite.p) % 360 + 360) % 360; | |
} | |
function trueAnomaly(satellite, time) { | |
var M = meanAnomaly(satellite, time); | |
return M + (180/Math.PI) * | |
( | |
(2 * satellite.e - Math.pow(satellite.e, 3)/4) * Math.sin(degToRad*M) + | |
(5/4 * Math.pow(satellite.e, 2)) * Math.sin(degToRad*M*2) + | |
(13/12 * Math.pow(satellite.e, 3)) * Math.sin(degToRad*M*3) | |
); | |
} | |
function radius(satellite, time) { | |
return satellite.a * (1 - Math.pow(satellite.e, 2)) / (1 + satellite.e * Math.cos(trueAnomaly(satellite, time)*degToRad)); | |
} | |
function coordinates(satellite, time) { | |
var r = radius(satellite, time); | |
var v = trueAnomaly(satellite, time); | |
var o = satellite.o; | |
var p = satellite.p; | |
var i = satellite.i; | |
var X = r * (cos(o) * cos(v+p-o) - sin(o) * sin(v+p-o) * cos(i)); | |
var Y = r * (sin(o) * cos(v+p-o) + cos(o) * sin(v+p-o) * cos(i)); | |
var Z = r * (sin(v+p-o) * sin(i)); | |
return [X,Y,Z]; | |
} | |
// au to pixels | |
var minPx = Math.min(window.innerHeight, window.innerWidth); | |
var auScale = d3.scale.linear().domain([0,2.2]).range([0,minPx]); | |
var sunSel = d3.select("#ecliptic").append("div") | |
.classed('celestial-body', true) | |
.attr('id', 'sun') | |
.style('left', '0') | |
.style('top', '0') | |
.style('width', (auScale(sun.radius)*2)+'px') | |
.style('height', (auScale(sun.radius)*2)+'px'); | |
var earthSel = d3.select("#ecliptic").append("div") | |
.classed('celestial-body', true) | |
.attr('id', 'earth') | |
.style('width', (auScale(earth.radius)*2)+'px') | |
.style('height', (auScale(earth.radius)*2)+'px'); | |
function render(time) { | |
var earthRadius = radius(earth, time); | |
var earthTrueAnomaly = trueAnomaly(earth, time); | |
var earthCoords = coordinates(earth, time); | |
console.log(earthCoords); | |
d3.select("#date").text(time); | |
d3.select("#radius").text(earthRadius); | |
d3.select("#true-anomaly").text(earthTrueAnomaly); | |
d3.select("#true-anomaly-pi").text(earthTrueAnomaly*degToRad/Math.PI); | |
earthSel | |
.style('left', auScale(earthCoords[0]) + 'px') | |
.style('top', auScale(earthCoords[1]) + 'px') | |
} | |
render(new Date()); | |
var realtime = setInterval(function() { render(new Date()); }, 1000); | |
var fastForward; | |
window.onclick = function() { | |
clearInterval(realtime); | |
clearInterval(fastForward); | |
var t = 0; | |
fastForward = setInterval(function() { | |
var newTime = new Date(+new Date() + t*dayToMs); | |
render(newTime); | |
t++; | |
}, 50); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
html, body { | |
margin: 0; | |
padding: 0; | |
background: black; | |
width: 100%; | |
height: 100%; | |
min-width: 500px; | |
min-height: 500px; | |
color: #333; | |
font-family: courier; | |
font-size: 10px; | |
} | |
p { margin: 0; } | |
#ecliptic { | |
top: 50%; | |
left: 50%; | |
width: 1px; | |
height: 1px; | |
transform: translate(-50%, -50%); | |
-webkit-transform: translate(-50%, -50%); | |
-moz-transform: translate(-50%, -50%); | |
position: relative; | |
} | |
.celestial-body { | |
border: 1px solid rgba(255,255,255,.5); | |
border-radius: 100px; | |
position: absolute; | |
-webkit-transform: translate(-50%, -50%); | |
-moz-transform: translate(-50%, -50%); | |
transform: translate(-50%, -50%); | |
-webkit-box-shadow: 0px 0px 3px 0px rgba(255, 255, 255, 0.75); | |
-moz-box-shadow: 0px 0px 3px 0px rgba(255, 255, 255, 0.75); | |
box-shadow: 0px 0px 3px 0px rgba(255, 255, 255, 0.75); | |
} | |
#sun { | |
background: yellow; | |
} | |
#earth { | |
background: lightblue; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment