私の以前のコードでこのわずかな変形は、すべてのループを見つけ、外側だけループでなければならない最大のXと1座標を取ることによって穴があるかどう機能します。ループは触れていない限り...ためにもバグの機能の一つでXとYを使用する必要性を注意してください...厳密おそらくそれは最大の面積を持つループを取る必要がありIGRAPHパッケージに(私が報告してきました)。
perimeterGrid <- function(pts, maxdist=6000, mindist=1){
g = edgeP(makegrid(pts, maxdist=maxdist, mindist=mindist))
## there might be holes. Find the loop with the largest X coordinate.
parts = components(g)
outer = which.max(tapply(V(g)$x, parts$membership, function(x){max(x)}))
g = induced_subgraph(g, which(parts$membership==outer))
loop = graph.dfs(minimum.spanning.tree(g),1)$order
cbind(V(g)$x, V(g)$y)[loop,]
}
# haversine distance matrix
dmat <- function(pts){
n=nrow(pts)
do.call(rbind,lapply(1:n,function(i){distHaversine(pts[i,],pts)}))
}
# make the grid cells given a maxdist (and a mindist to stop self-self edges)
makegrid <- function(pts, maxdist=6000, mindist=1){
dists = dmat(pts)
g = graph.adjacency(dists<maxdist & dists>mindist,
mode="undirected")
## use X and Y here not x and y due to igraph bug
## these get copied to the output later...
V(g)$X=pts[,1]
V(g)$Y=pts[,2]
g
}
# clever function that does the grid edge count etc
edgeP <- function(g){
# find all the simple squares
square=graph.ring(4)
subs = graph.get.subisomorphisms.vf2(g,square)
# expand all the edges
subs = do.call(rbind, lapply(subs, function(s){
rbind(s[1:2], s[2:3], s[3:4], s[c(4,1)])
}))
# make new graph of the edges of all the squares
e = graph.edgelist(subs,directed=FALSE)
# add the weight as the edge count
E(e)$weight=count.multiple(e)
# copy the coords from the source back
V(e)$x=V(g)$X
V(e)$y=V(g)$Y
# remove multiple edges
e=simplify(e)
# internal edges now have weight 256.
e = e - edges(which(E(e)$weight==256))
# internal nodes how have degree 0
e = e - vertices(degree(e)==0)
return(e)
}
たぶん(chull)https://stat.ethz.ch/R-manual/R-devel/library/grDevices/html/chull.html – bluefish
@bluefishを助けることができます。過去に私はchulllを使いました。しかし、ポイントが等間隔ではないため、いくつかの境界点が欠けています。したがって、この場合は役に立ちません。 – Janak
うーん、私は問題を見る。穴は正方形に相同であるため、他の質問からの私のアルゴリズムはそれらを境界として認識します。今私はこれが解決... – Spacedman