繁花规的R实现 2011-08-05

繁花规是一种玩具,大塑料圆片的内侧和小塑料圆片的外侧有可啮合的齿轮,用不同颜色的笔在圆片上某个小孔随齿轮自然移动,就可画出繁复而美丽的图案。可能大家小时候都玩过吧,或者像我一样玩过,但是当时却不知道它叫做繁花规。

从几何的观点看,繁花规的本质就是记录小圆在大圆里面转动的时候,小圆上某一点的轨迹。利用R的作图功能给出了繁花规的实现,把下面这段代码复制进RGui里面运行即可。如果给fanhuagui()函数设置不同的rate参数,就可以得到不同样子的图案。快试试自己的生日是什么样子的吧。

#make circle
circle <- function(o = c(0,0), r, n = 720, append=F,...)
{
  x <- 0:n
  theta <- x*2*pi/n
  if(append)
  {
    polygon(o[1] + r*cos(theta), o[2] + r*sin(theta),...)
  }
  else
  {
    plot(o[1] + r*cos(theta), o[2] + r*sin(theta), xlab="", ylab="",
    main="繁花规", axes=F, type="n", asp=1,...)
    polygon(o[1] + r*cos(theta), o[2] + r*sin(theta),...)
  }
  points(o[1], o[2], pch=16,...)
}

#rate belongs to (-1,1)
fanhuagui <- function(rate1, rate2, N, color)
{
  R=1;
  r=R*rate1;
  d=r*rate2;
  c0<-c(R-r+d, 0)
  for(theta in seq(0, N*2*pi, length = N*36))
  {
    o1 = c((R-r)*cos(theta), (R-r)*sin(theta))
    circle(r = R, col = 0, append = F)
    circle(o = o1, r = r, col=0, append = T)
    c0 <- rbind(c0, c(d*cos(-theta*R/r), d*sin(-theta*R/r)) + o1)
    lines(rbind(o1, c(d*cos(-theta*R/r), d*sin(-theta*R/r)) + o1), col=0)
    lines(c0, col = color)
  }
}

#have a try
fanhuagui(1.1,0.4,20,4)
fanhuagui(0.7,1.1,20,4)
fanhuagui(0.3,0.8,20,4)
fanhuagui(0.1,1.2,20,4)

代码中几个例子画出的图:



Powered by Jekyll on GitHub | ©2016 Meroa | Last modified: 2018-03-22