Simular velocidad de la luz entre la Tierra y la Luna

Cómo crear una simulación sobre el tiempo que se tarda a enviar información desde la Tierra hasta la Luna y viceversa.

Simulación de la velocidad de la luz

Hace un tiempo me encontré con este vídeo en YouTube del Dr. James O'Donoghue de la NASA que presenta una animación sobre el tiempo que tarda la luz desde que es enviada desde la Tierra hasta que llega a la Luna. Es una animación simple pero fascinante. Curiosamente, me recordó a JavaScript y cómo, al utilizar Promises, experimentamos una demora entre el envío de una petición y la recepción de una respuesta.

Más allá de esta analogía, me pareció interesante recrear la simulación de forma programática. Desconozco cómo el autor generó la animación. Es posible que haya utilizado algún lenguaje de programación, o incluso alguna aplicación de edición de video especializada como Adobe After Effects u otra similar.

En cualquier caso, intentaremos crear la simulación en JavaScript utilizando el elemento HTML canvas para representar el tiempo que tarda la información desde que es enviada desde el Planeta Tierra hasta que es recibida en nuestro satélite natural, la Luna.

Datos físicos curiosos

La velocidad de la luz es asombrosamente rápida, viajando a aproximadamente 299.792 kilómetros por segundo. Esta velocidad constituye una constante fundamental en el universo y representa la rapidez con la que las ondas electromagnéticas se desplazan a través del espacio. Pero, ¿cómo influye esto en la comunicación entre la Tierra y la Luna?

Considerando la distancia promedio entre la Tierra y la Luna, que es aproximadamente 384.400 kilómetros, podemos calcular el tiempo que la luz tardaría en viajar desde nuestro planeta hasta el satélite. Al dividir la distancia entre ambos cuerpos celestes por la velocidad de la luz, obtenemos un resultado sorprendente: alrededor de 1.28 segundos. ¡Sí, tan solo 1.28 segundos para cubrir esa inmensa distancia!

tiempo = distancia / velocidad

tiempo = 384400 / 299792 = 1.2822223408229705 segundos

Aunque es poco tiempo, vemos claramente que no se podría mantener una comunicación en tiempo auténticamente real y habría una pequeña demora. Con las vastas distancias del universo, puedes imaginarte cómo sería comunicarse con planetas o satélites todavía más lejanos.

Simulación javascript

Ahora que ya tenemos una idea de los números, vamos a crear la simulación. Primero crearemos un archivo llamado index.html con un elemento canvas donde dibujaremos la animación:

<canvas id="canvas" width="800" height="150"></canvas>

Luego añadiremos unos tags <script></script> y dentro escribiremos todo el código Javascript.

Primero debemos guardar en una variable la referencia del elemento canvas y su contexto dónde dibujaremos el resto de figuras:

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

Seguidamente definimos algunas variables con información inicial:

const actualDistanceKm = 384400;
const earthX = 50;
const earthY = canvas.height / 2;
const earthRadius = 20
const moonX = canvas.width - 50;
const moonY = canvas.height / 2;
const moonRadius = 10

let transmissionX = earthX + earthRadius;
let transmissionY = earthY;
let transmissionWidth = 10;
let transmissionHeight = 3;

const transmissionDuration = 1.255;
let isTransmitting = false;
let transmissionStartTime = 0;
let transmissionElapsedTime = 0;
let isReturning = false;
let progress = 0

Luego creamos una función drawScene que dibujará los elementos visibles como el Planeta Tierra, la Luna y la elipsis que representará la luz o información transmitida. Además también escribiremos por pantalla el tiempo de transmissión y la distancia recorrida:

function drawScene() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  if (isTransmitting) {
    ctx.beginPath();
    ctx.ellipse(transmissionX, transmissionY, transmissionWidth, transmissionHeight, 0, Math.PI * 2, 0);
    ctx.fillStyle = '#fff';
    ctx.fill();
    ctx.closePath();
  }

  ctx.beginPath();
  ctx.arc(earthX, earthY, earthRadius, 0, Math.PI * 2);
  ctx.fillStyle = '#1831F5';
  ctx.fill();
  ctx.closePath();

  ctx.beginPath();
  ctx.arc(moonX, moonY, moonRadius, 0, Math.PI * 2);
  ctx.fillStyle = '#DAD9D7';
  ctx.fill();
  ctx.closePath();

  ctx.fillStyle = '#fff';
  ctx.font = '16px Arial';
  ctx.fillText(`Tiempo transcurrido: ${transmissionElapsedTime.toFixed(2)} segundos`, 10, 20);
  ctx.fillText(`Distancia recorrida: ${(progress >= 1 ? actualDistanceKm : progress * actualDistanceKm).toFixed(2)} kms`, 10, 40);
}

Finalmente escribiremos la función para iniciar la transmisión y la función para animarla:

function startTransmission() {
  transmissionStartTime = performance.now();
  isTransmitting = true;
  requestAnimationFrame(animateTransmission);
}

function animateTransmission(timestamp) {
  if (isTransmitting) {
    transmissionElapsedTime = (timestamp - transmissionStartTime) / 1000;

    const totalTransmissionDuration = transmissionDuration;
    progress = transmissionElapsedTime / totalTransmissionDuration;

    if (!isReturning) {
      transmissionX = earthX + progress * (moonX - earthX);
    } else {
      transmissionX = moonX - progress * (moonX - earthX);
    }

    if (progress >= 1) {
      isTransmitting = false;
      isReturning = !isReturning
      setTimeout(() => {
        startTransmission();
      }, 1500);
    }
  }

  drawScene();
  if (isTransmitting) {
    requestAnimationFrame(animateTransmission);
  }
}
startTransmission();

Y aquí puedes ver el resultado final:

Si te ha gustado la simulación te recomiendo que pruebes con otros parámetros. Como ejercicio podrías enviar información a Marte, te sorprenderá lo rápido que aumenta el tiempo que tarda la luz en llegar!