📐 Guía y Demostración Matemática

Cómo Funcionan las Coordenadas Geográficas: La Verdad Esférica

Por qué la mayoría de generadores están rotos matemáticamente y cómo la proyección de área igual produce puntos uniformes en la Tierra.

📐 Precisión Matemática

Distribución Esférica de Área Igual vs. Error de Sesgo Polar

La mayoría de generadores tratan a la Tierra como un plano en lugar de una esfera 3D. Así es como nuestras matemáticas lo solucionan.

❌ Cuadrícula Plana Ingenua (Error Común)

Incorrecto
// ❌ Flat 2D Rectangular Bug:
const lat = (Math.random() * 180) - 90;
const lng = (Math.random() * 360) - 180;

El Problema: Una banda de 1° cerca del ecuador mide 40.075 km, mientras que a 80°N mide solo 6.950 km. Elegir latitud uniformemente sobre-representa las regiones polares hasta en un 400%.

✅ Área Igual de Marsaglia (Nuestro Algoritmo)

Verificado y Exacto
// ✅ Marsaglia Equal-Area Sphere Math:
const u = Math.random();
const lat = Math.asin(2 * u - 1) * (180 / Math.PI);
const lng = -180 + Math.random() * 360;

La Solución: Muestrear el seno de la latitud sin(θ) de forma uniforme compensa la reducción del área esférica cos(lat). Cada kilómetro cuadrado tiene la misma probabilidad.

1. El Error Fundamental de la Asunción Rectangular

En una proyección plana 2D (como Mercator), la Tierra parece un rectángulo plano con latitud de -90° a +90° y longitud de -180° a +180°.

Muchos tutoriales sugieren generar coordenadas con fórmulas ingenuas:

// ❌ Naive algorithm (Suffers from polar bias bug)
const latitude = (Math.random() * 180) - 90;
const longitude = (Math.random() * 360) - 180;

Aunque produce números válidos, asume que todas las bandas tienen la misma área física. En una esfera real, la circunferencia disminuye con el coseno de la latitud:

Circumference(θ) = 2πR · cos(θ)

En el ecuador (0°), la circunferencia es de 40.075 km. A 80° Norte, se reduce a solo 6.950 km. ¡El algoritmo plano concentra 5,7 veces más puntos en los polos que en el ecuador!

2. La Transformación Esférica de Área Igual de Marsaglia

Para generar puntos uniformemente distribuidos en la esfera, la densidad debe ser proporcional al elemento diferencial de superficie:

dA = R² · cos(θ) dθ dφ = R² · d(sin θ) dφ

Dado que el elemento de área es proporcional a d(sin θ), elegimos sin(θ) uniformemente en el intervalo [-1, 1]:

// ✅ Correct Archimedes-Lambert-Marsaglia equal-area algorithm:
function getRandomSpherePoint() {
  const u = Math.random(); // Uniform in [0, 1)
  const v = Math.random(); // Uniform in [0, 1)

  // Invert the cumulative distribution function:
  const sinLat = 2 * u - 1; // Uniform in [-1, 1]
  const latRad = Math.asin(sinLat); // In radians
  const lat = latRad * (180 / Math.PI); // In degrees [-90, +90]

  const lng = -180 + v * 360; // In degrees [-180, +180]

  return { lat, lng };
}

Esta elegante transformación matemática garantiza que cada kilómetro cuadrado de la Tierra tenga exactamente la misma probabilidad de ser seleccionado.

3. Muestreo por Rechazo en Tierra y Reproducibilidad PRNG

Aproximadamente el 71% de la superficie de la Tierra es océano. Cuando el usuario selecciona solo tierra firme, utilizamos muestreo por rechazo:

  1. Generar un punto esférico de área igual.
  2. Comprobar contra las cajas delimitadoras y vectores de masa continental.
  3. Si cae en mar abierto, descartar y regenerar con un umbral máximo de 250 intentos.

Para garantizar la reproducibilidad, usamos un hash cyrb53 de 53 bits combinado con el PRNG mulberry32 de 32 bits, logrando resultados 100% deterministas.