记得之前在 Matrix67 的博客上看过一个用三台摄影机制作分形图形的视频。原理很简单,每台摄影机都拍摄同一块大屏幕的内容,而大屏幕分三块,每块都显示摄像机拍摄的内容。这个想法太巧妙了,不用任何复杂的数学推导和编程就能画出复杂的图形。视频的原目的是为了不编程画分形,可惜三台摄影机比一台笔记本电脑贵多了。利用这个原理,用 R 能模拟实现这样的过程。
首先用 grid
包的 viewport
函数把一块屏幕分成三份,然后每份按照同样的方法再分成三份,如此递归下去,在最后一层放一个最简单的三角形或任何小图形。这样就可以跟视频中一样的方法在 R 里画出分形图形。还可以把图形或者是屏幕进行旋转得到更炫的图。
直接看图。
代码
library(grid)
re=function(k, vp.list, el){
k=k-1
if(k<=0){
el()
return(0)
}
for(vp in vp.list){
pushViewport(vp)
re(k-1, vp.list, el)
upViewport()
}
}
# 模拟三台摄影机
vp1 = viewport(x=1/4, y=1/4, w=1/2, h=1/2, angle=170)
vp2 = viewport(x=3/4, y=1/4, w=1/2, h=1/2, angle=70)
vp3 = viewport(x=1/2, y=3/4, w=1/2, h=1/2, angle=110)
grid.newpage()
re(13, vp.list = list(vp1, vp2, vp3),
function()grid.polygon(c(0, 1, .5), c(0, 0, 1), gp=gpar(col="green")))
# 五台摄影机
vp1 = viewport(x=1/6, y=1/6, w=1/3, h=1/3)
vp2 = viewport(x=5/6, y=1/6, w=1/3, h=1/3)
vp3 = viewport(x=1/6, y=5/6, w=1/3, h=1/3)
vp4 = viewport(x=5/6, y=5/6, w=1/3, h=1/3)
vp5 = viewport(x=1/2, y=1/2, w=1/3, h=1/3)
grid.newpage()
re(13, vp.list = list(vp1, vp2, vp3, vp4,vp5),
function()grid.polygon(c(0, 1, .5), c(0, 0, 1), gp=gpar(col="green")))