[关闭]
@agpwhy 2022-07-12T03:12:32.000000Z 字数 2094 阅读 213

王胖的生信笔记第四十九期:用R种棵树

教程来自:https://rpubs.com/mstefan-rpubs/fractals

遥想十年前我在一所男校学微积分的时候,最后一节课老师没啥好上的了,就给大家讲了一个概念叫分型几何Fractal Geometry。这个具体的数学比较复杂,但实际上我的理解就是不断的迭代重复。比如我们看菜花,看支气管,看血管,看雪花等等,都有这个的影子。

大家感兴趣可以自行搜索一些视频看看,这里就不赘述了。

这里分享一下看到的一个用R来实现重复迭代然后做图的一个案例。

  1. emptyCanvas <- function(xlim, ylim, bg="gray20") {
  2. par(mar=rep(1,4), bg=bg)
  3. plot(1,
  4. type="n",
  5. bty="n",
  6. xlab="", ylab="",
  7. xaxt="n", yaxt="n",
  8. xlim=xlim, ylim=ylim)
  9. } # 这个函数是用来整理画布的可以调颜色
  1. drawLine <- function(line, col="white", lwd=1) {
  2. segments(x0=line[1],
  3. y0=line[2],
  4. x1=line[3],
  5. y1=line[4],
  6. col=col,
  7. lwd=lwd)
  8. } # 这个函数是用来画线的
  9. drawObject <- function(object, col="white", lwd=1) {
  10. invisible(apply(object, 1, drawLine, col=col, lwd=lwd))
  11. } # 画线多画一点就是画物体了
  1. iterate <- function(object, ifun, ...) {
  2. linesList <- vector("list",0)
  3. for(i in 1:nrow(object)) {
  4. old_line <- matrix(object[i,], nrow=1)
  5. new_line <- ifun(old_line, ...)
  6. linesList[[length(linesList)+1]] <- new_line
  7. }
  8. new_object <- do.call(rbind, linesList)
  9. return(new_object)
  10. } # 是为了能够重复

画雪花

  1. # iterator function: koch curve
  2. koch <- function(line0) {
  3. # new triangle (starting at right)
  4. line1 <- newLine(line0, angle=180, reduce=1/3)
  5. line2 <- newLine(line1, angle=-60, reduce=1)
  6. line3 <- newLine(line2, angle=120, reduce=1)
  7. line4 <- newLine(line3, angle=-60, reduce=1)
  8. # reorder lines (to start at left)
  9. line1 <- line1[c(3,4,1,2)]
  10. line2 <- line2[c(3,4,1,2)]
  11. line3 <- line3[c(3,4,1,2)]
  12. line4 <- line4[c(3,4,1,2)]
  13. # store in matrix and return
  14. mat <- matrix(c(line4,line3,line2,line1), byrow=T, ncol=4)
  15. return(mat)
  16. }
  17. # example: Koch curve (after six iterations)
  18. fractal <- matrix(c(10,0,20,1e-9), nrow=1)
  19. for(i in 1:6) fractal <- iterate(fractal, ifun=koch)
  20. emptyCanvas(xlim=c(10,20), ylim=c(0,3))
  21. drawObject(fractal)

1

画树

  1. tree <- function(line0, angle=30, reduce=.7, randomness=0) {
  2. angle1 <- angle+rnorm(1,0,randomness) # left branch
  3. angle2 <- -angle+rnorm(1,0,randomness) # right branch
  4. line1 <- newLine(line0, angle=angle1, reduce=reduce)
  5. line2 <- newLine(line0, angle=angle2, reduce=reduce)
  6. mat <- matrix(c(line1,line2), byrow=T, ncol=4)
  7. return(mat)
  8. }
  1. # 加一点随机性
  2. fractal <- matrix(c(0,0,0,10), nrow=1)
  3. emptyCanvas(xlim=c(-30,30), ylim=c(0,35))
  4. lwd <- 7
  5. drawObject(fractal, lwd=lwd)
  6. for(i in 1:12) {
  7. lwd <- lwd*0.75
  8. fractal <- iterate(fractal, ifun=tree, angle=29, randomness=9)
  9. drawObject(fractal, lwd=lwd)
  10. }

然后可以根据你的需要设随机种子,然后做图。

ForPub

花哨一点还能做NFT呢。

IMG_2359

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注