@agpwhy
2022-07-12T03:12:32.000000Z
字数 2094
阅读 213
教程来自:https://rpubs.com/mstefan-rpubs/fractals
遥想十年前我在一所男校学微积分的时候,最后一节课老师没啥好上的了,就给大家讲了一个概念叫分型几何Fractal Geometry。这个具体的数学比较复杂,但实际上我的理解就是不断的迭代重复。比如我们看菜花,看支气管,看血管,看雪花等等,都有这个的影子。
大家感兴趣可以自行搜索一些视频看看,这里就不赘述了。
这里分享一下看到的一个用R来实现重复迭代然后做图的一个案例。
emptyCanvas <- function(xlim, ylim, bg="gray20") {
par(mar=rep(1,4), bg=bg)
plot(1,
type="n",
bty="n",
xlab="", ylab="",
xaxt="n", yaxt="n",
xlim=xlim, ylim=ylim)
} # 这个函数是用来整理画布的可以调颜色
drawLine <- function(line, col="white", lwd=1) {
segments(x0=line[1],
y0=line[2],
x1=line[3],
y1=line[4],
col=col,
lwd=lwd)
} # 这个函数是用来画线的
drawObject <- function(object, col="white", lwd=1) {
invisible(apply(object, 1, drawLine, col=col, lwd=lwd))
} # 画线多画一点就是画物体了
iterate <- function(object, ifun, ...) {
linesList <- vector("list",0)
for(i in 1:nrow(object)) {
old_line <- matrix(object[i,], nrow=1)
new_line <- ifun(old_line, ...)
linesList[[length(linesList)+1]] <- new_line
}
new_object <- do.call(rbind, linesList)
return(new_object)
} # 是为了能够重复
# iterator function: koch curve
koch <- function(line0) {
# new triangle (starting at right)
line1 <- newLine(line0, angle=180, reduce=1/3)
line2 <- newLine(line1, angle=-60, reduce=1)
line3 <- newLine(line2, angle=120, reduce=1)
line4 <- newLine(line3, angle=-60, reduce=1)
# reorder lines (to start at left)
line1 <- line1[c(3,4,1,2)]
line2 <- line2[c(3,4,1,2)]
line3 <- line3[c(3,4,1,2)]
line4 <- line4[c(3,4,1,2)]
# store in matrix and return
mat <- matrix(c(line4,line3,line2,line1), byrow=T, ncol=4)
return(mat)
}
# example: Koch curve (after six iterations)
fractal <- matrix(c(10,0,20,1e-9), nrow=1)
for(i in 1:6) fractal <- iterate(fractal, ifun=koch)
emptyCanvas(xlim=c(10,20), ylim=c(0,3))
drawObject(fractal)
tree <- function(line0, angle=30, reduce=.7, randomness=0) {
angle1 <- angle+rnorm(1,0,randomness) # left branch
angle2 <- -angle+rnorm(1,0,randomness) # right branch
line1 <- newLine(line0, angle=angle1, reduce=reduce)
line2 <- newLine(line0, angle=angle2, reduce=reduce)
mat <- matrix(c(line1,line2), byrow=T, ncol=4)
return(mat)
}
# 加一点随机性
fractal <- matrix(c(0,0,0,10), nrow=1)
emptyCanvas(xlim=c(-30,30), ylim=c(0,35))
lwd <- 7
drawObject(fractal, lwd=lwd)
for(i in 1:12) {
lwd <- lwd*0.75
fractal <- iterate(fractal, ifun=tree, angle=29, randomness=9)
drawObject(fractal, lwd=lwd)
}
然后可以根据你的需要设随机种子,然后做图。
花哨一点还能做NFT呢。