У меня есть правильная прямоугольная сетка значений x, y, z (изображение).
У меня также есть линия x, y, z, которая пересекает сетку.
Для каждой плоскости (z-уровня) в сетке, я хочу вычислить евклидово расстояние между каждой точкой сетки и точкой пересечения линии с этой сеткой.
Пример:
# create regular 3D array of values
vec <- array(1:21,c(21,21,21))
dimnames(vec) = list(seq(-10,10), seq(-10,10), seq(-10,10))
# convert to data.frame (with names x, y, z, value)
grid <- melt(vec, varnames=c("x","y","z"))
# and a set of points along a line
line <- data.frame(
x = seq(-10, 10),
y = seq(-10, 10),
z = seq(-10, 10)
)
Iпопробовал несколько вещей и остановился на использовании цикла for
для z-значений.
Решение:
# loop through each z-level to compute the euclidean distance between
# all points on the plane at that level, and
# the point on the line at that level.
tmp = data.frame()
for(i in line$z) {
point <- subset(line, z == i)
plane <- subset(grid, z == i)
plane$euclidean = (plane$x - point$x)^2 + (plane$y - point$y)^2
if(nrow(tmp) == 0) {
tmp = plane
} else {
tmp = rbind(tmp, plane)
}
}
Я не был особенно доволен этим решением, хотя оно было относительно быстрым.Мне не понравилась идея, что мне пришлось разделить и рекомбинировать набор данных, что привело к новому упорядочению / сортировке, и я чувствовал, что я делаю что-то не так, когда прибегаю к циклу for
в r.
У меня есть сильное чувство, что этот способ несколько неэффективен и что могут быть другие (более эффективные?) Способы сделать это, используя один или несколько из следующих вариантов:
- без
for
цикл, subset
и rbind
метод. - с использованием линейной алгебры
- с использованием одной из
apply
функций - с использованием пространственных типов данных и функции
sp::spDistsN1()
Другое решениебыло merge
сетки и линии на z-значении, а затем выполнить прямой расчет, но шаг merge
был очень медленным, и столбцы x, y, z в результирующем data.frame переименовывались из-за дублирующего столбцаимена.
Обновления для уточнения:
- Хотя значение в каждой точке (пикселе) изображения не имеет значения для расчета расстояния, оно требуется позже и должно бытьпринес с собой.
- Как и в моем собственном решении, мне нужны значения расстояния, назначенные для каждой точки x, y, z.Таким образом, выходные данные должны включать (x, y, z, value, евклидово), но не обязательно должны быть
data.frame
.