<html>
<head>
<meta charset="utf-8">
<title>Movimiento en elipse</title>
<script>
function astro(cx, cy, rad, color){
lapiz.arc(cx, cy, rad, 0, 2*Math.PI);
lapiz.fillStyle = color;
lapiz.fill();
lapiz.strokeStyle = color;
lapiz.stroke();
}
//Aproximaciones sucesivas por método Newton
//Calcula el ángulo del foco al planeta
//excentricidad, semieje, periodo, tiempo girando
function keplerE(exc, per, dt)
{
let E0, E1, M;
//Realmente es M = (2*pi/periodo como argumento)*dt
M = (0.0001/per)*dt
E1 = M + exc*Math.sin(M);
while (Math.abs(E1-E0) > 0.0000001) {
E0 = E1;
E1 = E0 - ( E0 - M - exc*Math.sin(E0) )/(1-exc*Math.cos(E0));
}
return E1;
}
//Dibuja la posición del planeta o satélite en su órbita
//Parámetros: radio planeta, excentricidad, semieje, tiempo, periodo, color, si lleva satelite
function orbita(rad, exc, semieje, tiempo, per, color, sat)
{
let E = keplerE(exc, per, tiempo)
//coords. X, Y respecto al foco
let cx = semieje*(Math.cos(E)-exc);
let cy = semieje*Math.sqrt(1-exc*exc)*Math.sin(E);
//reinicia lapiz tras cada vuelta
lapiz.beginPath()
astro(cx,cy,rad, color);
//si se quiere dibujar las elipses
//dibOrbita(exec, semije, color);
if (sat){ lapiz.translate(cx,cy) }
}
function mover(time)
{
let dt = Math.round((time-iniAnim))*100;
lapiz.putImageData(fondo,0,0);
//Pongo planeta con satelite es necesario guardar contexto
lapiz.save()
orbita(5, 0.2, 100, dt, 12 , "blue", true);
orbita(2, 0.1, 15, dt, 1 ,"pink", false);
lapiz.restore()
orbita(4, 0.5, 250, dt, 18 ,"red", false);
oAnim = window.requestAnimationFrame(mover)
}
//Si se quieren dibujar las órbitas se usarí esta función
//exc: excentricidad de la orbita,
//eje: semieje mayor de la orbita,
//color: color de la orbita
function dibOrbita(exc, eje, color){
lapiz.beginPath();
lapiz.strokeStyle = color;
let eje2 = eje*Math.sqrt(1-exc*exc);
lapiz.ellipse(-eje*exc, 0, eje, eje2, 0, 0, 2*Math.PI);
lapiz.stroke();
}
//globales (habría que mejorar esto)
var iniAnim, oAnim, lapiz, fondo;
function iniciar()
{
let marco=document.getElementById("marco")
lapiz = marco.getContext("2d");
lapiz.translate(marco.width/1.5, marco.height/2 - 100)
//Poner sol
lapiz.beginPath()
astro(0, 0, 10, "yellow");
fondo = lapiz.getImageData(0,0,marco.width, marco.height);
iniAnim = window.performance.now();
oAnim = window.requestAnimationFrame(mover)
}
</script>
</head>
<body onload="iniciar()">
<canvas id="marco" width="800" height="800" style="background-color: black"></canvas>
</body>
</html>