Rで双曲鉤針編み

  • 数学セミナーの2014年3月号に双曲平面の話があります
  • 双曲平面はなかなか「この世」に作るのが面倒くさいと思うのですが、自然界には、サンゴとか、そこらに転がっています
  • Rでそれらしく作ろうとすると、それはそれで面倒くさいように思いますが、その理由は、計算機ではユークリッド的に座標を与えたいのに、双曲平面は「余って」しまってその余分なところが「自由きまま」なために、「確定」させにくいからのように思います
  • そんな双曲平面ですが鉤針編みなら、どんどん作れるのはこちらの記事にもある通り
  • じゃあ、R上で鉤針編みをしてしまえばなんとかなるか…
  • スティッチを刻み、それをグラフにして、グラフを3次元座標として表現させるための力学モデル(こちら)とかに座標化の部分をやってもらっては…
  • というのがこちら
  • 1点から始めて、1段進むごとに各フロントノードは1個か2個の個ノードを生みながら大きくなっていく
  • そうやってできたグラフを「描かせる」


# 初期状態はノード1個
x <- c(1)
# k世代の増殖
k <- 11
# 初期状態の「フロント」はノード1のみ
current <- 1
# フロントn.kidから1つ値を選んで、その数の子ノードを生じる
n.kid <- 1:2
# 子ノードの数を確率的に選ぶ
P <- 0.3
p <- c(P,1-P)
# グラフのエッジリスト。初期値はなし
el <- matrix(0,0,2)
# 世代ごとに成長させる
for(i in 1:k){
# 現時点のフロントノードの生む子の数を決める
	n <- sample(n.kid,length(current),replace=TRUE,prob=p)
# 新世代の子の総数
	new.kid <- sum(n)
# 処理のために、累積和ベクトルを作っておく
	cumsum.kid <- cumsum(n)
	cumsum.kid <- c(0,cumsum.kid)
	max.x <- max(x)
# 1個しか増えないときは、子同士の間のエッジはないが、2個以上の子がいれば、子-子間エッジを引く
	if(new.kid > 1){
		tmp <- (max.x+1):(max.x+new.kid-1)
		el <- rbind(el,cbind(tmp,tmp+1))
	}
# 親子のエッジを引く
	for(j in 1:length(n)){
		el <- rbind(el,cbind(rep(current[j],n[j]),(max.x + cumsum.kid[j]+1):(max.x+cumsum.kid[j+1])))
	}
	#print(el)
	current <- (max.x+1):(max.x+new.kid)
	x <- c(x,current)
}
# グラフオブジェクト化する
library(igraph)
g <- graph.edgelist(el,directed=FALSE)
plot(g,vertex.size=1,vertex.label=NA)

# 3次元でのノード配置を計算する。なるべくい各エッジの長さが等しくなるようにするアルゴリズム
coords <- layout.fruchterman.reingold(g, dim=3)
rglplot(g, layout=coords,vertex.size=0.1,vertex.label=NA)