프랙탈로 그리는 크리스마스 카드

이제 크리스마스 시즌이 슬슬 다가오니 본인이 좋아하는 블로그인 WALKING RANDOMLY에서 요런 장난을 소개한다.

Christmas greetings – SAGE style in WALKING RANDOMLY

Barnsley 고사리라는 프랙탈 도형이 있는데, 이름은 고사리지만-_- 요게 크리스마스 트리스럽게 생겼으니 엽서에 넣으면 그럴듯 하다. ㅋㅋ

WALKING RANDOMLY에서 소개한 소스코드를 본인의 sage에서 돌려봤는데, 그림이 멋있게 나오지 않아서 본인이 수치를 조금씩 수정했다. 그래서 완성!
sage0
이제 이 그림에 글자를 써 넣으면 크리스마스 엽서가 완성이 된다. 우왕 멋있다 ㅋㅋㅋ

sage 소스코드는 다음과 같다. sage 설치한 사람은 돌려보시라. ㅋ

def f(i,P):
    x = P[0]
    y = P[1]
    if i==0:
        return [ 0.65*x + 0.04*y - 0.10, -0.01*x + 0.65*y + 1.60]
    if i==1:
        return [-0.15*x + 0.28*y + 0.10,  0.26*x + 0.24*y + 0.44]
    if i==2:
        return [0.20*x  - 0.26*y - 0.10,  0.23*x + 0.22*y + 0.60]
    if i==3:
        return [-0.10*x + 0.20*y + 0.10, 0.00*x + 0.26*y + 1.50]


def fern_leaf(num_pts, clr, pt_size=2, initial_pt = (0,0), center_pt = (0,0)):
    p0 = 0.01 # prob pick f0
    p1 = 0.07 # prob pick f1
    p2 = 0.07 # prob pick f2
    p3 = 0.85 # prob pick f3
    #p = [p0,1,p2,p3]
    P = initial_pt
    pts = [P]
    for i in range(num_pts):
        r = random()
        #print i, r
        if 0<r<p0:
            P = tuple(f(3,P))
            pts.append(P)
        elif p0<r<p0+p1:
            P = tuple(f(1,P))
            pts.append(P)
        elif p0+p1<r<p0+p1+p2:
            P = tuple(f(2,P))
            pts.append(P)
        else:
            P = tuple(f(0,P))
            pts.append(P)
    if center_pt != (0,0):
        pts_centered = [center_pt]
        for p in pts:
            pts_centered.append((p[0]+center_pt[0],p[1]+center_pt[1]))
    else:
        pts_centered = pts
    return point(pts_centered,rgbcolor=clr, axes=False, pointsize=pt_size)
    
P1 = fern_leaf(100000, (0,0.95,0.3))
P2a = fern_leaf(1, (0.9, 0.9, 0), pt_size=50, center_pt=(0.7,0.1))
P2b = fern_leaf(2, (0.1, 0.1, 0.7), pt_size=50, center_pt=(-0.2,1.3))
P2c = fern_leaf(2, (0.9, 0.1, 0), pt_size=50, center_pt=(0,1.5))
P2d = fern_leaf(2, (0.9, 0.1, 0), pt_size=50, center_pt=(0.25,1.1))
P3 = fern_leaf(2, (0.7, 0.1, 0.2), pt_size=80, center_pt=(-0.3,1))
P4a = fern_leaf(2, (0.9, 0.1, 0.2), pt_size=80, center_pt=(0.5,1.7))
P4b = fern_leaf(2, (0.9, 0.1, 0.6), pt_size=80, center_pt=(0.9,0.2))
P4c = fern_leaf(1, (0.9, 0.1, 0.7), pt_size=80, center_pt=(-0.9,1.2))
P5a = fern_leaf(2, (0.9, 0.1, 0.2), pt_size=10, center_pt=(0,1.8))
P5b = fern_leaf(2, (0.9, 0.1, 0.2), pt_size=10, center_pt=(0.2,1.5))
P5c = fern_leaf(2, (0.9, 0.1, 0.2), pt_size=10, center_pt=(-0.2,0.8))
(P2a+P2b+P2c+P2d+P3+P4a+P4b+P4c+P1+P5a+P5b+P5c).show(axes=False)

P1 은 몸체부분이고, 나머지 P2~P5는 장식용 점들이다. RGB색, 크기 및 대략적 위치를 정해주면 그 근방에서 랜덤하게 찍힌다.

아 그리고 물론 함수 f에 정의된 linear transform의 matrix를 다르게 바꾸면 전체적인 나무의 모양이 달라진다. 뭐 괜춘한 걸로 바꿔보시길. ㅋㅋㅋ

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중