Penrose tiling

  • 書き方 with python
  • Rに直す(タイルの塗り分けのみ。辺の太細の描き分けは省略)

# 黄金比
goldenRatio <- (1+sqrt(5))/2
# 適切な二等辺三角形を分割して三角形のリストを返す関数
# リストはタイルの色(三角形の形のタイプ)と3点の座標とからなるリストを要素とするリスト
my.subdivide <- function(trs){
	ret <- list()
	cnt <- 1
	for(i in 1:length(trs)){
		if(trs[[i]]$color==0){
			P <- trs[[i]]$A + (trs[[i]]$B-trs[[i]]$A)/goldenRatio
			ret[[cnt]] <- list(color=0,A=trs[[i]]$C,B=P,C=trs[[i]]$B)
			cnt <- cnt + 1
			ret[[cnt]] <- list(color=1,A=P,B=trs[[i]]$C,C=trs[[i]]$A)
			cnt <- cnt + 1
		}else{
			Q <- trs[[i]]$B + (trs[[i]]$A - trs[[i]]$B) / goldenRatio
			R <- trs[[i]]$B + (trs[[i]]$C - trs[[i]]$B) / goldenRatio
			ret[[cnt]] <- list(color=1, A=R, B=trs[[i]]$C, C=trs[[i]]$A)
			cnt <- cnt +1
			ret[[cnt]] <- list(color=1,A=Q,B=R,C=trs[[i]]$B)
			cnt <- cnt + 1
			ret[[cnt]] <- list(color=0, A=R, B=Q, C=trs[[i]]$A)
			cnt <- cnt+1
		}
	}
	return(ret)
}
# ある指定サイズの三角形をn回分割する
my.penrose <- function(n=5){
	trs <- list()
	trs[[1]] <- list(color=0,A=c(0,0),B=c(cos(2*pi/20),sin(2*pi/20)),C=c(cos(2*pi/20),-sin(2*pi/20)))
	for(i in 1:n){
		trs <- my.subdivide(trs)
	}
	return(trs)
}
# 色分けして描画
my.plot.trs <- function(trs){
	v <- unlist(trs)
	r <- range(v)

	plot(c(0,0),xlim=r,ylim=r,col=0)
	for(i in 1:length(trs)){
		polygon(c(trs[[i]]$A[1],trs[[i]]$B[1],trs[[i]]$C[1]),c(trs[[i]]$A[2],trs[[i]]$B[2],trs[[i]]$C[2]),col=trs[[i]]$color+2)
	}
}
# やってみる
trs <- my.penrose(n=8)
my.plot.trs(trs)