Barnsley fern, a fractal
In the spirit of bringing plants and math together, this lesson is about the Barnsley fern, a fractal first described by Dr. Michael Barnsley. Let's see what we can learn, by applying flawed, biological approaches to understand the algorithm underlying a fractal: Can a biologist fix a fern? Or, what I learned while studying fractals.
Although foolhardy, it is hoped that this lesson will teach computational scientists and mathematicians a little bit about where plant biologists are coming from, and likewise that the plant biologists can see how well their principles apply to dissecting mathematics and code!
First, explore the generation of Barnsley fern using the links below. What are your first impressions about how this frond is caculated while observing its generation in real time? After playing with some of the parameters, how much diversity in shape can you generate, and in what ways are you limited? Does this algorithm replicate the shape of different fern species well?
Watch the fern generated in real time
As beautiful as this fractal fern frond is, you should know that it has its critics, with respect to its biological validity. In this lesson, we will be treating this fractal as an extended metaphor for how biologists tackle problems.
The code for the Barnsley fern is reproduced below (taken from here).
식물과 수학을 결합하는 것
프랙탈을 통해서, 식물을 생성할 수 있다
▶ The Barnsley fern fractal (바네사이드 프렉탈)
아래 코드는 프랙탈의 기하학적 구조 중 하나인 바네사이드 프렉탈을 생성하는 코드이다.
(이것을 사용해서 식물의 잎 모양을 나타낼 수 있다)
# 숫자를 랜덤으로 생성하기 위해 사용
import random
# 그래프 플로팅할 때 쓴다
import matplotlib.pyplot as plt
# 시작좌표를 (0,0)으로 둔다
X = [0]
Y = [0]
# 프렉탈의 점을 생성할 때, 10만번 반복하면서 만든다
# (숫자를 줄여도 된다)
for n in range(100000):
# 0부터 100까지의 임의의 실수 만들기
# r은 0~100 사이의 확률을 의미한다.
# 다음 점을 결정하는데 사용됨
r = random.uniform(0, 100)
# r의 크기에 따라서 서로 다른 규칙을 적용시킨다
if r < 1.0:
x = 0
# x좌표를 0으로 설정한다
# y좌표를 이전 y좌표의 16%로 설정한다
y = 0.16*Y[n-1]
elif r < 86.0:
# x좌표를 이전 x좌표의 85%와 이전 y좌표의 4%로 정한다
# y좌표를 이전 x좌표의 -4%와 이전 y좌표의 85%에 1.6을 더한 값으로 정한다
x = 0.85*X[n-1] + 0.04*Y[n-1]
y = -0.04*X[n-1] + 0.85*Y[n-1]+1.6
elif r < 93.0:
# x좌표를 이전 x좌표의 20%와 이전 y좌표의 -26%로 정한다
# y좌표를 이전 x좌표의 23%와 이전 y좌표의 22%에 1.6을 더한 값으로 정한다
x = 0.2*X[n-1] - 0.26*Y[n-1]
y = 0.23*X[n-1] + 0.22*Y[n-1] + 1.6
else:
# x좌표를 이전 x좌표의 -15%와 이전 y좌표의 28%로 정한다
# y좌표를 이전 x좌표의 26%와 이전 y좌표의 24%에 0.44를 더한 값으로 정한다
x = -0.15*X[n-1] + 0.28*Y[n-1]
y = 0.26*X[n-1] + 0.24*Y[n-1] + 0.44
# 지정된 x좌표, y좌표를 리스트에 추가하기
X.append(x);Y.append(y)
# 그래픽 플롯의 크기 정하기
plt.figure(figsize = [5,5])
# color는 검은색
# alpha는 투명도를 이야기함
# 점의 크기 s는 2
plt.scatter(X,Y,color = 'k',alpha=0.1, s=2)
# x축과 y축의 비율을 동일하게 설정해서, 왜곡을 방지한다
plt.axes().set_aspect('equal', 'datalim')
# 축 숨김
plt.axis('off')
▷ 깔끔한 코드
import random
import matplotlib.pyplot as plt
X = [0]
Y = [0]
for n in range(100000):
r = random.uniform(0, 100)
if r < 1.0:
x = 0
y = 0.16*Y[n-1]
elif r < 86.0:
x = 0.85*X[n-1] + 0.04*Y[n-1]
y = -0.04*X[n-1] + 0.85*Y[n-1]+1.6
elif r < 93.0:
x = 0.2*X[n-1] - 0.26*Y[n-1]
y = 0.23*X[n-1] + 0.22*Y[n-1] + 1.6
else:
x = -0.15*X[n-1] + 0.28*Y[n-1]
y = 0.26*X[n-1] + 0.24*Y[n-1] + 0.44
X.append(x);Y.append(y)
plt.figure(figsize = [5,5])
plt.scatter(X,Y,color = 'k',alpha=0.1, s=2)
plt.axes().set_aspect('equal', 'datalim')
plt.axis('off')
* 참고
https://nbviewer.org/github/DanChitwood/PlantsAndPython/tree/master/
'Game AI & Unity > L-system algorithm' 카테고리의 다른 글
[Plants and Python][prac7] 함수와 프랙탈 1 (0) | 2024.03.29 |
---|---|
[Plants and Python][prac6] 유전자 knock-out (0) | 2024.03.27 |
[Plants and Python][prac4] 해바라기 만들기2 (0) | 2024.03.22 |
[Plants and Python][prac3] 해바라기 만들기1 (0) | 2024.03.22 |
[Plants and Python][prac2] 피보나치 수열, 패턴 출력 (0) | 2024.03.22 |