본문 바로가기

About Fractal

프랙탈 나무(Fractal Tree)

작성자:2008.12.23 권대용(Lunartail)

자연에서 보는 식물들은 복잡해 보이지만 원리를 알면 의외로 심플한 구조를 바탕으로 하고 있는 것을 발견할 수 있다. 여러 형태중 가장 기본적인 구조인 나뭇가지가 벌어지는 모양은 프랙탈의 자기유사성을 보여주므로 수학적으로 분석을 하여 재귀적으로 그리는 방법이 있다. 

알고리즘 (dir#-각도, len#-길이, n-차수)
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
 
Global x#=320    ;Tree X position
Global y#=400    ;Tree Y position
dir#= 0      ;Angle
Len#= 60     ;Length

Graphics 640,480,0,2
SeedRnd MilliSecs ()  ;Seed the randomizer

While Not(num = 1 Or num = 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

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
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
End Function

알고리즘을 적용하는데 시행착오가 좀 있었지만 만족할 만한 결과가 나온것 같다. 변수 n은 차수(iteration value)로 프랙탈 나무의 재귀 깊이를 결정하므로 반복할수록 풍성한 나무를 만들게 된다. 프로그램을 실행시키면 아래의 그림1과 같이 규칙적인 형태의 기본 프랙탈 트리를 볼 수 있는데 랜덤을 이용해 가지의 길이와 기울기값 그리고 단계별 가지의 굵기등을 변화시키면 그림2 또는 그림3  같이 확연히 차이가 나는 사실적인 나무를 만들 수 있다. 

그림1) 고정 프랙탈 트리(fixed)

그림2) 랜덤프랙탈 트리

그림3) 랜덤프랙탈 트리