Один из способов решения этой интересной проблемы состоит в том, чтобы рассматривать ее как надежную оценку центра двумерного распределения точек. (Хорошо известное) решение состоит в том, чтобы очистить выпуклые корпуса, пока ничего не останется . Центроид последнего непустого корпуса находит центр.
(Это относится к багплоту . Для получения дополнительной информации, поиск в Интернете «выпуклый пилинг корпуса многофакторный.»)
Результат для 16 иллюстрированных точек показан как центральный треугольник на этой карте. Три окружающих многоугольника показывают последовательные выпуклые корпуса. Пять отдаленных точек (30% от общего количества!) Были удалены в первые два шага.
Пример был вычислен в R
. Сам алгоритм реализован в среднем блоке «выпуклый пилинг». Он использует встроенную chull
подпрограмму, которая возвращает индексы точек на корпусе. Эти точки удаляются с помощью отрицательного индексационного выражения xy[-hull, ]
. Это повторяется до тех пор, пока последние точки не будут удалены. На последнем шаге центроид вычисляется путем усреднения координат.
Обратите внимание, что во многих случаях проецирование данных даже не требуется: выпуклые корпуса не изменятся, если исходные элементы не будут охватывать антимеридиан (+/- 180 градусов по долготе), либо полюс, либо настолько обширными, что кривизна сегментов между ними будет Сделать разницу. (Даже тогда искривление не будет иметь большого значения, потому что шелушение все равно будет сходиться к центральной точке.)
#
# 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")