走性

  • アメーバや粘菌が移動する
  • 動きたい方向がある
  • 個々のパーツは孤立できない
  • そんな条件で動かしてみたい
  • 動きは離散的になる
  • こちらのベクトル場を借用
  • 以下のソースは少々重い
# 時空間
X<-1:100
Y<-1:100
Niter<-1000

N<-1000 # 個体数・細胞数
# 位置別個体数
A<-array(0,c(length(X),length(X),Niter))

# 初期値:一か所集中
A[20,20,1]<-N
# 個別個体の位置格納マトリクス
L<-matrix(0,N,2)
L[,1]<-20
L[,2]<-20

# ベクトル場
phi<-pi/8
Ox<-100/2
Oy<-100/2
V<-array(0,c(length(X),length(Y),2))

f<-function(x,y,Ox,Oy,phi){
#r<-sqrt((x-Ox)^2+(y-Oy)^2)
r<-1/3
th<-atan2(y-Oy,x-Ox)
v<-c(-r*sin(th+phi),r*cos(th+phi))
v
}

for(i in X){
for(j in Y){
V[i,j,]<-f(i,j,Ox,Oy,phi)
}
}
# シミュレーション
for(i in 2:Niter){
	for(j in 1:N){
# 縦横に確率的に移動させることでベクトル場を反映する
		tmpx<-runif(1)
		tmpy<-runif(1)
		if(A[L[j,1],L[j,2],i]>0){
			if(tmpx<abs(V[L[j,1],L[j,2],1])){
			delta<-1
			if(V[L[j,1],L[j,2],1]<0){
				delta<--1
			}
			L[j,1]<-L[j,1]+delta
		}
		if(tmpy<abs(V[L[j,1],L[j,2],2])){
			delta<-1
			if(V[L[j,1],L[j,2],2]<0){
				delta<--1
			}
			L[j,2]<-L[j,2]+delta
		}
		}
		
		if(is.element(L[j,1],X) && is.element(L[j,2],Y)){
			A[L[j,1],L[j,2],i]<-A[L[j,1],L[j,2],i]+1
		}
		
	}
# distで定める周囲で単一個体となったら死亡、その代わりに、仲間のいる位置で1個体増やす
	dist<-5
	for(j in 1:N){
		if(sum(A[min(1,L[j,1]-dist):max(X[length(X)],L[j,1]+dist),min(1,L[j,2]-dist):max(Y[length(Y)],L[j,2]+dist),i])<=1){
			A[L[j,1],L[j,2],i]<-A[L[j,1],L[j,2],i]-1
			L[j,1]<-sample(L[,1],1)
			L[j,2]<-sample(L[,2],1)
			
			A[L[j,1],L[j,2],i]<-A[L[j,1],L[j,2],i]+1
		}
	}
}

for(t in 1:Niter){
	num<-Niter*10+t
	filename<-paste("out",num,".jpg")
	jpeg(filename)
#persp(A[,,t],col=6,theta=20,phi=60,zlim=(c(0,max(A))))
image(A[,,t],col=topo.colors(10))
dev.off()
#print(sum(U[,,t]))
}