如何从delaunay三角剖分中提取距离到R中的列表对象

时间:2014-10-10 13:32:12

标签: r delaunay

假设我有点的坐标,每个点都有ID。我如何从delaunay三角测量中提取距离到列表对象?

# My data are similar to this structure
id <- c("A","B","C","D","E","F","G","H","I","J","K","L","M","N")
x_coor <- c(0.5,1,1,1.5,2,3,3,3.5,4,4.5,5,5,6,7)
y_coor <- c(5.5,3,7,6.5,5,3.5,3,1.5,1,2.5,4,5,3.5,5.5)
my.data <- data.frame(id = id, x_coor = x_coor, y_coor = y_coor)

# When I perform Delaunay triangulation, I can see the distances....
library(tripack)
my.triangles<-tri.mesh(my.data$x_coor, my.data$y_coor)
plot(my.triangles, do.points=FALSE, lwd=0.2)
points(my.data$x, my.data$y, col = "black", pch=20, cex = 1.5)
text(my.data$x, my.data$y, labels = my.data$id)

enter image description here

如何像这样提取“对”点列表对象?

# I need something like this...
my.list
[[A]]
[1] 2.55  1.58  1.41  1.58 (all distances connected to "A")
[[B]]
[1] 2.55  2.24  2.06  2.00  2.92  3.61 (all distances connected to "B")
etc.

2 个答案:

答案 0 :(得分:3)

tri.mesh()开始,我们有:

my_triangles <- tri.mesh(my.data$x_coor, my.data$y_coor)
plot(my_triangles, do.points=FALSE, lwd=0.2)

str(my_triangles)?neighbours上的R文档,我们可以按照以下方式为每个点提取邻居:

neiblist <- neighbours(my_triangles)

然后附加原始数据帧中的点ID,以便您几乎拥有所需的列表,除了它包含邻居ID而不是距离:

names(neiblist) <- my.data$id         #append names for later reference

然后用所有点计算欧氏距离矩阵:

euc_dist <- as.matrix(dist(cbind(x=my_triangles$x, y=my_triangles$y)))

#Append dimnames for reference

colnames(euc_dist) <- my.data$id
rownames(euc_dist) <- my.data$id

查找一个点可能具有的最大邻居:需要内存预分配

max_n <- max(unlist(lapply(neiblist, length)))
npoints <- length(my.data$id)                 # This is just the total number of points

预分配收集结果的内存,计算效率和速度的重要性

dist_2neigh_mat <- matrix(nrow=npoints, ncol=max_n)    #Create results matrix

rownames(dist_2neigh_mat) <- my.data$id
colnames(dist_2neigh_mat) <- colnames(data.frame(dist=matrix(data=1:6, nrow=1)))

获取并收集所有点的距离向量。

for (i in my.data$id){
neighbors_i <- neiblist[[i]]
dist2neighbours_i <- euc_dist[,i][neighbors_i]

#Append vector with NAs to match ncol of results matrix

dist2neighbours_i <- c(dist2neighbours_i, rep(NA, 
times=(max_n-length(dist2neighbours_i))))

dist_2neigh_mat[i,] <- dist2neighbours_i   #Update results matrix with i'th distances
}

dist_2neigh_mat包含您的搜索结果。如果您坚持将结果完全按照问题中的说明列入清单,那么您只需将结果矩阵转换为如下列表:

results_list <- as.list(data.frame(t(dist_2neigh_mat)))

然后,出于矩阵完整性原因,您可以删除之前生成的NA:

#Function to remove NA's

fun_NA <- function(x){x=x[!is.na(x)]
return(x)}

从结果

中删除NA&#39
results_list <- lapply(results_list, FUN=fun_NA)  

我的想法是,即使有很多很多分数,这也会非常迅速。但有人可能会有不同的看法: - )

干杯。

答案 1 :(得分:1)

连接到'A'的所有段的端点之一等于'A'的坐标。找到那些坐标:

xy<- c(x-coor[id=='A'],y_coor[id=='A']) 

如果您这样做,例如,print.tri(my.triangles),您将获得邻接打印输出:

 #partial result
    triangulation nodes with neigbours:
    node: (x,y): neighbours
    1: (0.5,5.5) [4]: 2 3 4 5 
    2: (1,3) [6]: 1 5 6 7 8 9 
    3: (1,7) [3]: 1 4 14

通过观察xy值与此打印输出中的第一个坐标匹配,您可以抓取相邻顶点并查找其坐标。它可能更容易执行

my_neighbor<-neighbours(my.triangles)
# partial result:
[[1]]
[1] 2 3 4 5

[[2]]
[1] 1 5 6 7 8 9

[[3]]
[1]  1  4 14

[[4]]
[1]  1  3  5 12 14

然后抓住坐标。例如。对于第一个顶点,邻居是2,3,4,5。抓住坐标xtmp<- my.triangles$x[c(1,2:5)]ytmp<-my.triangles$y[c(1,2:5)],构建矩阵并生成距离:

dist(cbind(xtmp,ytmp))

第一列的结果是您想要my.list$A

的距离