필유홈2.0

admin | write

웹을 잠깐 찾아봤는데 아무래도 없는 듯해서, 직접 만들어봤다. 별 거 아닌데 오래 걸렸다-_-; 기본적인 원리는 다음과 같다.

const T1:int=144;    // 큰 변의 길이. 작은 변의 길이와 황금비율이다
const T2:int=55;    // (표시되지 않는) 작은 변의 길이. 큰 변의 길이와 황금비율이다
const ANGLE:Number=72*Math.PI/180;    // 5각형의 내각 72도의 라디안 값

var real:Shape=new Shape();

real.graphics.beginFill(0xaabbff, 1);
real.graphics.lineStyle(1,0xff6699,1,true);
real.graphics.moveTo(Point.polar(T1,-ANGLE).x,Point.polar(T1,-ANGLE).y);
for(var i=0;i<5;i++)
{
    real.graphics.lineTo(Point.polar(T2,(i-1)*ANGLE+ANGLE/2).x,
                         Point.polar(T2,(i-1)*ANGLE+ANGLE/2).y);
    real.graphics.lineTo(Point.polar(T1,i*ANGLE).x,Point.polar(T1,i*ANGLE).y);
}
real.graphics.endFill();

이건 Shape 인스턴스일 뿐이고 위의 코드에서는 화면(stage)에 표시(addChild)하는 부분은 없다. 실제로 활용하기 위해서는 MovieClip 등의 인스턴스를 만들고 그 안에 이걸 추가해준 뒤에 그 인스턴스를 다시 stage에 자식으로 추가하거나 한 뒤에 사용해야 정석이다...라는 당연한 얘기는 생략.

만약 변의 교차를 그리고 싶다면 for 문 앞의 moveTo 라인을 삭제하고 for 문 안을 다음으로 바꾸면 된다. 이 경우는 당연히(?) 속을 채울 수 없다.

    real.graphics.moveTo(Point.polar(T1,(i-1)*ANGLE).x,Point.polar(T1,(i-1)*ANGLE).y);
    real.graphics.lineTo(Point.polar(T1,(i+1)*ANGLE).x,Point.polar(T1,(i+1)*ANGLE).y);

설명을 잘 못 알아듣겠다면(말주변이 없어서-_-) 그냥 다음 플래시 파일을 다운받아 볼 것;


star3.fla

위 파일의 소스


황금비율 혹은 황금분할에 대해선 만국기의 보편적 상징에 대하여(새창) 등의 문서를 참고할 것.




'프로그래밍' 카테고리의 다른 글

actionscript로 별 그리기  (0) 2008/07/02
[마리가 연주하는 음악]에 부쳐  (0) 2008/06/28
[actionscript 3.0] 소리 페이드인(Sound fade-in)  (0) 2008/05/17
플래시 이것저것  (6) 2008/05/09

지난 달에 산 만화 중에 ← 이런 만화가 있다. 이 작가(후루야 우사마루)는 사실 [파이]라는 애로 만화-_- 때문에 알게 된 작가였는데, 단순한 애로 만화가로 판단했던 게 실수였달까. 꽤나 괜찮은 만화였다.

만화방에서 꽤나 흥미진진하게 감상한 뒤에 구매까지 결정한 계기는, 실은 내용보다는 그림 때문이다. 뭐, 같은 이유 때문에 [코제트의 초상]도 같이 사긴 했는데... 후자는 사실 아직 포장도 안 뜯어봤다-_- (애니메이션도 있다던데 그것도 아직 못 봤다)

어쨌든 내용을 떠나서, 만화에 등장하는 톱니바퀴들의 이미지와 세계관이 꽤 인상적이었다. 그래서 어제 (학교도 안 가고) 집에서 대충 만들어본 게 ↓ 이거.




언제나처럼, 새로고침을 연타해주시길.




이건 보너스.




'프로그래밍' 카테고리의 다른 글

actionscript로 별 그리기  (0) 2008/07/02
[마리가 연주하는 음악]에 부쳐  (0) 2008/06/28
[actionscript 3.0] 소리 페이드인(Sound fade-in)  (0) 2008/05/17
플래시 이것저것  (6) 2008/05/09

각설하고,

소리(Sound) 인스턴스(instance)의 음량(volume)은 그 자체로 조절할 수 없습니다. 아시다시피(?) SoundTransform 클래스로만 변경이 가능하죠. 또한 transform을 거치는 인스턴스에는 tween을 줄 수 없기 때문에(문법상으로는 문제가 없지만 실행해보면 당연히 tween이 안 먹힙니다) 페이드인(fade-in)을 구현하는 데 어려움이 있었습니다.

그래서 찾아본 결과:
Fading sound using AS3 (새창)

요약하자면 다음 fla 소스(임의로 행순서를 바꾸고 주석을 달았습니다):
var fadeInIncr = 0.1;   // 음량 전역변수
var soundFadeInTimer:Timer = new Timer(100,30);
var snd:Sound = new Sound(new URLRequest("myLoop.mp3"));
var trans:SoundTransform = new SoundTransform(fadeInIncr, 0);
var channel:SoundChannel = snd.play(0, 1, trans);

soundFadeInTimer.addEventListener("timer", soundFadeIn);
soundFadeInTimer.start();

function soundFadeIn(e:TimerEvent){   // 이벤트 핸들러
    fadeInIncr += 1/30;

    var sAmbienceVol:SoundTransform = new SoundTransform(fadeInIncr, 0);
    channel.soundTransform = sAmbienceVol;
}


수정:
위 방법으로는 여러 개의 인스턴스에 각각 페이드인 효과를 구현할 수 없다는 내용의 장문-_-을 썼다가, 별 의미 없어서 지웠습니다. 여러 개의 인스턴스에서 사용하려면 ENTER_FRAME 이벤트 핸들러(즉 idle 함수)에서 for문 돌려가며 해당 인스턴스의 음량 변수를 가지고 와서 변경하면 됩니다(물론 SoundTransform을 통해서). 타이머 클래스에는 currentCount라는 속성(property)이 있는데, 이걸 사용해도 되겠죠. 방법은 여러가지. 페이드아웃 역시 마찬가지로 구현하면 됩니다.

페이드인/페이드아웃을 구현한 예제 (새창)




3월부터 플래시(Flash)라는 녀석을 처음으로 만지게 됐다. ...이유는 묻지 마시라. 워낙 시각적인 센스도 없고 그쪽으로는 잼병이기에, 죄다 볼품없는 것들뿐이다. 그냥 나라는 바보가 액션스크립트(ActionScript)라는 프로그래밍 언어를 공부해온 흔적들이랄까. 갖다 붙이자면 랜덤함의 미학... 뭐, 나중에 돌아보면 피식, 이러겠지.


배경음악은 math-rock 밴드 toe의 past and language.




ball


rain


fluid


ball_3


ekg



night_sky (5월 14일 추가)



나도 이딴 것들을 내가 왜 만들었는지 모르겠다. 그냥 이것들을 가만히 들여다보고 있으면 시간은 잘 가더라.




과제#1 실험결과결과분석에 이어지는 마지막 포스트로 코드를 올립니다. 사실상 대부분의 학생들에게는 이 포스트만이 쓸모있겠죠; 물론 검색 조금만 하면 비슷한 코드가 수두룩 쏟아지지만요.

행여 이 코드를 사용하실 분들께 주의드릴 점이 몇 가지 있습니다. 먼저 일반적으로 숙제용(;)으로 짤 때는 자료형을 대충 int로 지정하지만 저는 입력자료의 자료형을 typedef로 data_type이라고 정의해서 작성했습니다. 다른 자료형을 사용하시려면 헤더 파일에서 그 부분만 고치시면 됩니다(물론 if 문까지 함수화하지는 않았기 때문에 숫자형만 가능합니다. 만약 if 문을 함수화하면 문자형이나 구조체 등에 대해서까지도 적용 가능해지겠죠. 또 지난번 포스트에도 썼듯, 분포수세기 정렬 및 직접 기수 정렬은 양의 정수만 제대로 정렬할 수 있습니다). 같은 맥락에서, 자료의 개수 및 첨자(index)에 관련된 자료형 역시 index_type으로 정의했습니다. 이 점 유의하시고... 그외 더 있지만... 음-_-a 주석을 보시고 알아서 수정해서 사용하시길...;

코드 튜닝: 과제에 사용한 프로그램은 언어 의존적인 코드 최적화(for 대신 do – while 사용하여 반복 횟수를 줄이는 방법, register 변수 사용 등등) 모두 포기하고 코드의 명확성과 가독성을 높이는 중점을 두었다. 대신 컴파일시 옵션으로 –O3 지정하여 최적화는 모두 컴파일러에게 맡겼다. 또한 재귀적인 알고리즘은 반복적인 알고리즘으로 고쳐 성능을 높일 있지만 역시 포기하고 교재에 소개된 의사 코드대로 재귀적인 알고리즘을 사용했다. 변수명이나 함수명도 대부분 의사 코드를 그대로 따르고 있다.

깜빡했는데; 과제 스펙은 이 pdf 파일입니다. 뭐 읽으셔도 그만, 안 읽으셔도 그만;; 교재는 그 유명한(;) Introduction to Algorithms, 2nd Ed. 혹은 CLRS라고들 부르는 바로 그 책입니다. 강의노트는 저희 강의 홈페이지에 있습니다. 지난번에도 썼지만 이 강의노트는 MIT 2001년 강의노트를 아주 약간(;) 수정한 내용입니다.

서문이 길어졌군요; 이제 헤더 파일과, 각 정렬 알고리즘 파일을 붙여넣겠습니다. 글꼴은 MS의 개발자용 & 클리어타입용 글꼴 consolas입니다. 이게 없다면... fixedsys로 보일 겁니다; 여기 올린 코드와 여기에는 올리지 않은 실험에 사용한 Makefile 및 main 파일은 압축하여 따로 첨부합니다. 이 main 파일에서 시간을 구하는 함수는 리눅스 전용이므로, 윈도우나 도스에서 돌리시려면 다른 함수를 사용해야 합니다.
 
HW1_200011079_LeeSangBok.tgz

코드, main 파일, Makefile



헤더파일
[universal_sorter.h]

more..




삽입 정렬
[insertion_sort.c]

more..



병합 정렬
[merge_sort.c]

more..



힙 정렬
[heap_sort.c]

more..



퀵 정렬
[quick_sort.c]

more..



분포수세기 정렬
[counting_sort.c]

more..



직접 기수 정렬 - 이재규씨의 C로 배우는 알고리즘을 많이 참고했습니다;
[radix_sort.c]

more..



개선된 퀵 정렬: 세 값의 중간값(median-of-three) 방법 이용
[quick_sort3.c]

more..



사용예

more..



지난번 포스트에 이은, 결과 분석과 결론, 부록입니다. 분포수세기 정렬에 대해서 행한 추가실험 결과도 포함됩니다.

사실 결과 분석은 모두 간단한 선형 회귀분석에 의존했는데, 지금 와서 보면 조금 아쉬운 부분이 있습니다.
가령 알고리즘별로 추정한 절편을 비교하여 초기비용(overhead)을 비교한다든가 하는 식의 분석이 이루어졌다면 더 좋았을 듯하네요.

다음 포스트에는 실험에 사용한 코드를 올리겠습니다.


덧: 지난번 포스트 올린 후에 학교에서 접속해서 익스플로러로 보니 주석처리가 안 되고 표의 테두리도 이상하게 나오더군요. MS 워드에서 그냥 붙여넣기했을 뿐인데 왜 파폭에선 제대로 보여주고 익스플로러에선 제대로 못 보여주는지 모르겠습니다. MS는 자사에서 만든 프로그램에 대한 지원을 어째서 이렇게 못하는 걸까요-_-? 왜 옛날에 MS 인텔리포인트 마우스도 XP에서 드라이버를 자동으로 잡아내지 못했었죠. 장치관리자에 알 수 없는 장치-_- 이 따위로 나오고-_- 아니 자기네 회사에서 만든 마우스를 왜 알 수 없냔 말입니다-_-




1.    결과 분석

그래프(x축은 log(n)이다) 보면 배운 결과대로 나왔음을 있다. 각각의 알고리즘에 대해 회귀분석한 결과는 다음과 같다. 모든 실험 결과 분석 결과는 별도의 엑셀 파일에 자세히 들어있다.

     1)    삽입 정렬

그래프에서 보이듯 평균적으로, 그리고 최악의 경우 n2 성능을 보이며, 정렬이 자료에 대해서는 선형 성능을 보인다. 실제로 엑셀로 회귀분석을 해보면 각각의 경우의 회귀식에 맞아떨어진다(well-fitted). 다음 표에서 오른쪽 3열은 각각 정렬이 상태, 정렬이 상태, 역순으로 정렬된 상태를 의미하고, 회귀식은 1행의 경우 y=mn + b, 2행의 경우 y=mn2 + b이다. R2 1 가까울수록 모형의 설명력이 강함을 의미한다.

n

m

88.5217

0.0060

178.0101

b

9.3893

0.0001

18.8473

R^2

0.9270

0.9980

0.9272

n^2

m

0.0014

0.0000

0.0029

b

0.0000

0.0000

0.0000

R^2

1.0000

0.9244

1.0000

 

2)    병합 정렬

그래프에서도 보이듯, 별도의 기억장치를 사용하기 때문에 다른 n·log(n) 정렬 알고리즘에 비해 성능이 떨어진다. 그런데 정렬이 상태, 역순으로 정렬된 상태에 비해 정렬이 되지 않았을 때의 성능이 약간 느리게 측정되는 일이 일어났다. 알고리즘상 성능은 분명 θ(n)=n·log(n)이고 코드 또한 그렇게 작성했으므로, 이는 런타임 최적화가 일어났기 때문이 아닐까 싶다(if ~ else 문에서 한쪽 선택으로만 계속 분기하기 때문). 결과적으로 다음 표에서 보이듯 정렬된 상태, 역순으로 정렬된 상태일 때에는 선형에 가까운 성능으로 회귀되었다. 회귀식은 1행이 y=mn + b, 3행은 y=m(n·log(n)) + b이다(이론적으로는 빨간색 칸의 값이 노란색 칸보다 작아야 하는데 실제로는 빨간색 칸이 크게 나왔다).

n

m

0.8346

0.6355

0.6488

b

0.0090

0.0045

0.0041

R^2

0.9992

0.9996

0.9997

n*log(n)

m

0.0522

0.0397

0.0405

b

0.0005

0.0004

0.0006

R^2

0.9994

0.9994

0.9987

 

3)    힙 정렬

정렬은 안정성은 없지만 입력자료의 상태와 무관하고 최악의 경우에도 O(n·log(n)) 성능을 보여주기 때문에 실제로 가장 범용성 있는 정렬 알고리즘이 아닐까 싶다. 그래프를 보면, 입력자료 상태와 무관하게 꿋꿋하게 병합 정렬과 개선된 정렬 사이에 위치하고 있다. 회귀분석 결과 특이사항은 없다.

n*log(n)

m

0.0375

0.0331

0.0318

b

0.0004

0.0001

0.0001

R^2

0.9994

0.9999

1.0000

 

4)    퀵 정렬

정렬은 입력자료가 이미 정렬이 되어있거나 역순으로 정렬이 되어 있을 경우 O(n<