Jednym ze sposobów podejścia do tego interesującego problemu jest postrzeganie go jako solidnego estymatora środka dwuwymiarowego rozkładu punktów. (Dobrze znanym) rozwiązaniem jest odrywanie wypukłych kadłubów, dopóki nic nie zostanie . Środek ciężkości ostatniego niepustego kadłuba lokalizuje środek.
(Jest to związane z bagplotem . Aby uzyskać więcej informacji, wyszukaj w Internecie „wypukły łusek wielowariantowy odstający”).
Wynik dla 16 ilustrowanych punktów jest pokazany jako środkowy trójkąt na tej mapie. Trzy otaczające wielokąty pokazują kolejne wypukłe kadłuby. Pięć odległych punktów (30% całości!) Zostało usuniętych w pierwszych dwóch krokach.
Przykład został obliczony w R
. Sam algorytm jest zaimplementowany w środkowym bloku, „wypukłym peelingu”. Wykorzystuje wbudowaną chull
procedurę, która zwraca indeksy punktów na kadłubie. Punkty te są usuwane za pomocą ujemnego wyrażenia indeksującego xy[-hull, ]
. Jest to powtarzane do momentu usunięcia ostatnich punktów. W ostatnim kroku środek ciężkości jest obliczany przez uśrednienie współrzędnych.
Należy pamiętać, że w wielu przypadkach rzutowanie danych nie jest nawet konieczne: wypukłe kadłuby nie zmienią się, chyba że oryginalne cechy obejmują antimeridian (długość geograficzna +/- 180 stopni), biegun lub są tak rozległe, że krzywizna segmentów między nimi będzie robić różnicę. (Nawet wtedy krzywizna nie będzie miała większego znaczenia, ponieważ łuszczenie nadal zbiega się w centralnym punkcie).
#
# 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")