- 空間にグラフがあるとする
- 空間に点があるとする
- 点からグラフへの最短距離を描く
- こちらで作った、「凸包」への垂線の足を利用する
- ループを回しているのでちょっと重いかも
- 垂線の足がどの辺に乗っているかで色分けすると、空間が塗り分けて見えやすそう
d<-2
n.node<-4
m<-matrix(runif(n.node^2),n.node,n.node)
m<-m+t(m)
mean.m<-mean(m)
m<-(m>mean.m)
diag(m)<-0
m
x<-matrix(runif(n.node*d),ncol=d)
x
n.pt<-1000
a<-matrix(runif(n.pt*d),ncol=d)
feet<-apply(a,1,calc.foot,x=x,m=m)
plot(x,col=2,xlim=c(0,1),ylim=c(0,1))
m2<-m
m2[lower.tri(m2)] <- 0
edges<-which(m2==1,arr.ind=TRUE)
for(i in 1:length(edges[,1])){
segments(x[edges[i,1],1],x[edges[i,1],2],x[edges[i,2],1],x[edges[i,2],2],col=2)
}
for(i in 1:n.pt){
for(j in 1:length(feet[[i]]$edge)){
segments(a[i,1],a[i,2],feet[[i]]$coods[j,1],feet[[i]]$coods[j,2],col=rainbow(sum(m2))[feet[[i]]$edge[j]])
}
}
nrm<-function(A){
sqrt(sum(A^2))
}
MinDistance2<-function(A,Xs,bothside=TRUE){
df<-length(A)
N<-length(Xs[,1])
Xs1<-t(t(Xs)-A)
C<-apply(Xs1,2,sum)/N
Xs2<-t(t(Xs1)-C)
いて
Xs3<-Xs2 %*% t(Xs1)
Xs4<-rbind(Xs3[1:(N-1),],rep(1,N))
coefs<-solve(Xs4,c(rep(0,(N-1)),1))
Apr<-t(Xs1) %*% coefs
L<-nrm(Apr)
Apr<-Apr+A
inside<-FALSE
if(length(coefs[coefs<0])==0 || (bothside & length(coefs[coefs>0])==0) ){
inside<-TRUE
}
list(A=A,Xs=Xs,distance=L,Apr=Apr,coefs=coefs,inside=inside)
}
calc.foot<-function(X,x,m){
difference<-t(x)-X
distance<-sqrt(apply(difference^2,2,sum))
m2<-m
m2[lower.tri(m2)] <- 0
edges<-which(m2==1,arr.ind=TRUE)
min.dist.per.edge<-rep(0,length(edges[,1]))
t.per.edge<-rep(0,length(edges[,1]))
closest<-matrix(0,length(edges[,1]),length(X))
for(i in 1:length(edges[,1])){
tmp.out<-MinDistance2(X,x[edges[i,],])
if(tmp.out$inside){
t.per.edge[i]<-tmp.out$coefs[1]
min.dist.per.edge[i]<-tmp.out$distance
closest[i,]<-tmp.out$Apr
}else{
if(distance[edges[i,1]]<distance[edges[i,2]]){
t.per.edge[i]<-1
min.dist.per.edge[i]<-distance[edges[i,1]]
closest[i,]<-x[edges[i,1],]
}else{
min.dist.per.edge[i]<-distance[edges[i,2]]
closest[i,]<-x[edges[i,2],]
}
}
}
min.pt<-which(min.dist.per.edge==min(min.dist.per.edge))
if(length(min.pt)==1){
return(list(coods=matrix(closest[min.pt,],nrow=1),edge=min.pt))
}else{
return(list(coods=closest[min.pt,],edge=min.pt))
}
}