Una forma de abordar este interesante problema es verlo como un estimador robusto del centro de una distribución puntual bivariante. Una solución (bien conocida) es pelar los cascos convexos hasta que no quede nada . El centro de la última carcasa no vacía localiza el centro.
(Esto está relacionado con el bagplot . Para más información, busque en la web "convex hull peeling multivariate outlier").
El resultado de los 16 puntos ilustrados se muestra como el triángulo central en este mapa. Los tres polígonos circundantes muestran los cascos convexos sucesivos. Los cinco puntos periféricos (¡el 30% del total!) se eliminaron en los dos primeros pasos.
El ejemplo se calculó en R
. El algoritmo propiamente dicho se implementa en el bloque central, "peeling convexo". Utiliza el sistema incorporado de chull
que devuelve los índices de los puntos del casco. Estos puntos se eliminan mediante la expresión de indexación negativa xy[-hull, ]
. Esto se repite hasta que se eliminen los últimos puntos. En el último paso, se calcula el centroide promediando las coordenadas.
Tenga en cuenta que en muchos casos ni siquiera es necesario proyectar los datos: los cascos convexos no cambiarán a menos que los rasgos originales abarquen el antimeridiano (+/-180 grados de longitud), cualquiera de los polos, o sean tan extensos que la curvatura de los segmentos entre ellos marque la diferencia. (Incluso en ese caso, la curvatura será de poca importancia, porque el pelado seguirá convergiendo hacia un punto central).
#
# Project the data.
#
dy <- c(8,7,5,10,7,17,19,19,21,22,22,22,24,24,26,26)
dx <- c(66,67,66,89,89,79,78,76,75,81,78,77,75,80,77,83)
lat <- (28.702 + dy/1e5) / 180 * pi
lon <- (77.103 + dx/1e5) / 180 * pi
y <- dy
x <- cos(mean(lat)) * dx
#
# Convex peeling.
#
xy <- cbind(x, y)
while(TRUE) {
hull <- chull(xy)
if (length(hull) < nrow(xy)) {
xy <- xy[-hull, ]
} else {
xy.0 <- matrix(apply(xy, 2, mean), 1, 2)
break
}
}
#
# Plot the data `xy` and the solution `xy.0`.
#
plot(range(x), range(y), type="n", asp=1)
points(x, y, pch=21, bg="#a01010")
points(xy.0, pch=24, cex=1.2, bg="#404080")