작성자:2008.12.23 권대용(Lunartail)
자연에서 보는 식물들은 복잡해 보이지만 원리를 알면 의외로 심플한 구조를 바탕으로 하고 있는 것을 발견할 수 있다. 여러 형태중 가장 기본적인 구조인 나뭇가지가 벌어지는 모양은 프랙탈의 자기유사성을 보여주므로 수학적으로 분석을 하여 재귀적으로 그리는 방법이 있다.
알고리즘 (dir#-각도, len#-길이, n-차수)
1. 주어진 길이와 각도를 이용하여 이동할 상대 좌표를 구한다.
2. 구한 상대 좌표로 선을 그린다.(제어점이 상대 좌표만큼 이동한다)
3. n이 0이면 6으로 간다.(종료조건)
4. (n - 1, 길이 * SCALE, 각도 + 기울기값)에 대해 프랙탈 나무 알고리즘을 실행한다.
5. (n - 1, 길이 * SCALE, 각도 - 기울기값)에 대해 프랙탈 나무 알고리즘을 실행한다.
6. 제어점을 1의 상태로 되돌린다.
1. 주어진 길이와 각도를 이용하여 이동할 상대 좌표를 구한다.
2. 구한 상대 좌표로 선을 그린다.(제어점이 상대 좌표만큼 이동한다)
3. n이 0이면 6으로 간다.(종료조건)
4. (n - 1, 길이 * SCALE, 각도 + 기울기값)에 대해 프랙탈 나무 알고리즘을 실행한다.
5. (n - 1, 길이 * SCALE, 각도 - 기울기값)에 대해 프랙탈 나무 알고리즘을 실행한다.
6. 제어점을 1의 상태로 되돌린다.
;Fractal Tree - 2008/12/23
;Fixed tree & Random tree - 고정프랙탈과 랜덤프랙탈을 생성
;Written By Daeyong Kwon
;http://fractalart.tistory.com
;Tip: Use Blitz Basic For Execution http://www.blitzbasic.com
;Fixed tree & Random tree - 고정프랙탈과 랜덤프랙탈을 생성
;Written By Daeyong Kwon
;http://fractalart.tistory.com
;Tip: Use Blitz Basic For Execution http://www.blitzbasic.com
Global x#=320 ;Tree X position
Global y#=400 ;Tree Y position
dir#= 0 ;Angle
Len#= 60 ;Length
Global y#=400 ;Tree Y position
dir#= 0 ;Angle
Len#= 60 ;Length
Graphics 640,480,0,2
SeedRnd MilliSecs () ;Seed the randomizer
SeedRnd MilliSecs () ;Seed the randomizer
While Not(num = 1 Or num = 2)
Cls
num=Input("Fixid(1) or Random?(2):") ;숫자입력 1 or 2
Cls
num=Input("Fixid(1) or Random?(2):") ;숫자입력 1 or 2
For n = 1 To 12
Cls
Select num
Case 1
fixed_tree(0,Len#, n) ;1을 누르면 고정Tree함수 호출
Case 2
rnd_tree(0,Len#,n) ;2를 누르면 랜덤Tree함수 호출
Default
Text 10,10,"Input Number 1 or 2"
Exit
End Select
Color 255,255,255
Text 240,416,"press any key!"
Text 80,408,"Level:"+n
WaitKey()
Next
Wend
Cls
Select num
Case 1
fixed_tree(0,Len#, n) ;1을 누르면 고정Tree함수 호출
Case 2
rnd_tree(0,Len#,n) ;2를 누르면 랜덤Tree함수 호출
Default
Text 10,10,"Input Number 1 or 2"
Exit
End Select
Color 255,255,255
Text 240,416,"press any key!"
Text 80,408,"Level:"+n
WaitKey()
Next
Wend
Function fixed_tree(dir#,Len#,n)
;고정트리를 생성한다
;dir# : 각도
;len# : 길이
;n : 차수
Color n*14,n*30,n*8
dx# = x# - Len# * Sin(dir#) ;가지의 상대 좌표
dy# = y# - Len# * Cos(dir#)
Line x#,y#, dx#,dy#
If n > 0
x# = x#- Len# * Sin(dir#) ;L가지의 출발좌표
y# = y#- Len# * Cos(dir#)
fixed_tree( dir# + 25, Len# * 0.8, n - 1 )
fixed_tree( dir# - 25, Len# * 0.8, n - 1 )
x# = x# + Len# * Sin(dir#) ;R가지의 출발좌표
y# = y# + Len# * Cos(dir#)
EndIf
y# = y# + Len# * Cos(dir#)
EndIf
End Function
Function rnd_tree(dir#,Len#,n)
;랜덤트리를 생성한다
;dir# : 각도
;len# : 길이
;n : 차수
Color n*6,n*20,n*3
dx# = x#- Len# * Sin(dir#) ;가지의 상대 좌표
dy# = y#- Len# * Cos(dir#)
For i =0 To n
Line x#+aa#,y#, dx#+aa#,dy#
aa# = aa#+0.8
Next
If n > 0
x# = x#- Len# * Sin(dir#) ;L가지의 출발좌표
y# = y#- Len# * Cos(dir#)
rnd_tree( dir# + Rnd(0,60), Len# * Rnd#(0.5,1), n - 1 )
rnd_tree( dir# - Rnd(0,60), Len# * Rnd#(0.5,1), n - 1 )
x# = x#+ Len# * Sin(dir#) ;R가지의 출발좌표
y# = y#+ Len# * Cos(dir#)
EndIf
;랜덤트리를 생성한다
;dir# : 각도
;len# : 길이
;n : 차수
Color n*6,n*20,n*3
dx# = x#- Len# * Sin(dir#) ;가지의 상대 좌표
dy# = y#- Len# * Cos(dir#)
For i =0 To n
Line x#+aa#,y#, dx#+aa#,dy#
aa# = aa#+0.8
Next
If n > 0
x# = x#- Len# * Sin(dir#) ;L가지의 출발좌표
y# = y#- Len# * Cos(dir#)
rnd_tree( dir# + Rnd(0,60), Len# * Rnd#(0.5,1), n - 1 )
rnd_tree( dir# - Rnd(0,60), Len# * Rnd#(0.5,1), n - 1 )
x# = x#+ Len# * Sin(dir#) ;R가지의 출발좌표
y# = y#+ Len# * Cos(dir#)
EndIf
End Function
알고리즘을 적용하는데 시행착오가 좀 있었지만 만족할 만한 결과가 나온것 같다. 변수 n은 차수(iteration value)로 프랙탈 나무의 재귀 깊이를 결정하므로 반복할수록 풍성한 나무를 만들게 된다. 프로그램을 실행시키면 아래의 그림1과 같이 규칙적인 형태의 기본 프랙탈 트리를 볼 수 있는데 랜덤을 이용해 가지의 길이와 기울기값 그리고 단계별 가지의 굵기등을 변화시키면 그림2 또는 그림3과 같이 확연히 차이가 나는 사실적인 나무를 만들 수 있다.
그림1) 고정 프랙탈 트리(fixed)
그림2) 랜덤프랙탈 트리
그림3) 랜덤프랙탈 트리
'About Fractal' 카테고리의 다른 글
코흐곡선(Koch Curve) (0) | 2008.12.13 |
---|---|
원형순환프랙탈(Circular infinity) (0) | 2008.12.09 |
베이직(basic)언어로 구현한 시에르핀스키삼각형(Sierpinski Gasket) (1) | 2008.11.29 |
프랙탈 이야기 2편 (1) | 2008.11.22 |
프랙탈 이야기 1편 (2) | 2008.11.22 |