컴퓨터 소프트웨어의 GUI 요소 중에는 잘 알다시피 체크 박스와 라디오 박스가 있다.
전자는 n개의 항목을 제각각 복수 선택할 수 있기 때문에 선택의 가짓수가 2^n개가 가능하다.
그 반면 후자는 n개의 항목 중 하나만 선택할 수 있기 때문에 선택의 가짓수가 딱 n이 된다.

그리고 이런 개념은 사실 메뉴에도 존재한다.
메뉴 항목은 사용 가능 여부(enabled)와 더불어 체크 여부(checked)라는 상태가 존재하여, 자신이 체크된 것처럼 보이는 시각적 피드백을 줄 수 있다.

Windows는 초창기엔(=16비트 시절) 말 그대로 √ 1종류만이 존재했다. 이를 제어하는 함수는 CheckMenuItem이다.
그러다가 Windows 95/NT4에서부터는 ● 모양의 체크를 표시해 주는 CheckMenuRadioItem 함수도 추가되었다. 이로써 각각의 항목들을 따로 체크할 수 있는 메뉴와, 여러 개 중 한 모드만 선택할 수 있는 메뉴의 구분이 가능해졌다.
CheckMenuRadioItem는 특정 메뉴 항목 하나의 속성을 바꾸는 여타 함수들과는 달리, 메뉴 항목들을 여러 개 한꺼번에 지정한 뒤 하나만 체크를 하고 나머지는 체크를 모두 자동으로 해제하는 형태로 동작한다.

그런데 재미있는 것은, MFC는 95/NT4 이전의 16비트 시절에서부터 메뉴에다 custom 비트맵을 지정하는 독자적인 방식으로 라디오 박스를 자체 지원해 왔다는 점이다.
운영체제에 CheckMenuRadioItem가 추가된 뒤에도 내부적으로 그 함수를 쓰지 않는다. 이것은 비주얼 C++ 2012의 최신 MFC도 변함이 없다.

MFC는 동일한 명령 ID에 대해서 메뉴, 도구모음줄 등 여러 GUI 요소에 대해 일관되게 checkd/enabled 상태를 관리할 수 있게 이 계층만을 CCmdUI라는 클래스로 따로 뽑아 냈다. 그리고 윈도우 메시지의 처리가 끝난 idle 시점 때 모든 GUI 상태들을 업데이트한다.
MFC 소스를 보면, CCmdUI::SetCheck는 CheckMenuItem 함수를 호출하는 형태이다. 그러나 CCmdUI::SetRadio는 운영체제의 API를 쓰는 게 아니라 자체 생성한 bullet 모양 비트맵을 SetMenuItemBitmaps로 지정하는 좀 더 힘든 방법을 쓴다.

고전 테마를 포함해 심지어 Windows XP의 Luna에서도 운영체제가 그려 주는 radio 그림과 MFC가 그려 주는 radio 그림은 차이가 거의 없었다. 둘 다 그냥 글자와 동일한 모양으로 동그란 bullet을 그리는 게 전부였다. 그렇기 때문에 두 구현이 따로 노는 건 그리 문제될 게 없었다.

그러나 문제는 Vista 이후에서부터이다. 운영체제가 그리는 radio 그림은 더 알록달록해지고 배경까지 가미되어 화려해진 반면, MFC가 그리는 radio 그림은 아직까지 단색의 단조로운 bullet이 전부이다. 그래서 시각적으로 이질감이 커졌다. 그것도 일반 체크(√) 항목은 괜찮은데 라디오(●) 그림만 차이가 생긴 것이다.

사용자 삽입 이미지사용자 삽입 이미지

이해를 돕기 위해 그림을 첨부한다. Windows Vista 이후에 운영체제가 메뉴에다 그려 주는 라디오 체크는 배경에 은은한 무늬가 생겨 있다(왼쪽). 그러나 MFC가 그리는 라디오 체크는 여전히 옛날 스타일대로 단색 동그라미밖에 없으며, 일반 체크와도 형태가 다르다(오른쪽). 오른쪽의 프로그램은 본인이 예전에 MFC 기반으로 개발했던 오목 게임이다. ㅋㅋ

MFC는 운영체제의 새로운 함수를 왜 쓰지 않는 걸까?
그냥 이런 사소한 데에까지 신경을 안 써서 그런 것일 수도 있고, 또 CCmdUI는 각각의 메뉴 항목에 대해 개별적으로 호출되는 반면 CheckMenuRadioItem는 그 자체가 여러 메뉴 항목의 상태를 한꺼번에 바꾸는 함수이기 때문에 기능의 구현 형태가 서로 맞지 않아서 도입하지 않은 것일 수도 있다.

물론, SetMenuItemInfo라는 만능 함수를 쓰면, 개별적으로 라디오 체크 상태를 바꾸는 것도 불가능하지는 않다. 다만, 구조체를 준비해야 하는 데다, 상태(state)만 옵션으로 간단히 바꾸면 되는 게 아니라 메뉴의 유형(type)까지 바꿔야 하니 일이 좀 번거로운 건 사실이다.

다만, 요즘은 MFC에도 잘 알다시피 MS Office나 Visual Studio의 모양대로 GUI 외형을 싹 바꿔 주는 툴킷이 도입되었고, 이런 상태에서는 어차피 메뉴의 요소들이 무조건 모조리 자체적으로 그려진다. 그러니 저런 SetRadio와 SetCheck의 동작 방식의 차이 같은 것도 존재하지 않으며, 그런 걸 논하는 게 아무 의미가 없다. 저건 오로지 운영체제 표준 GUI를 쓸 때만 발생하는 이슈이기 때문이다. ^^

* 글을 맺으며..

WinMain 함수를 포함해 윈도우 클래스 등록, 프로시저 구현을 전부 직접 하면서 Windows용 응용 프로그램을 밑바닥부터 만들어 본 사람이라면, MFC가 내부적으로 프로그래머에게 몰래 해 주는 일이 얼마나 많은지를 어렴풋이 짐작할 수 있다.

  • 대화상자를 창의 가운데에다 배치해 주는 것,
  • 프레임 윈도우와 뷰 윈도우 사이의 경계에 깔끔한 입체 모양 테두리 넣는 것,
  • 고대비 모드일 때 도구 아이콘의 검은색을 흰색으로 바꾸는 것,
  • 심지어 콤보 박스 내부에 디폴트 데이터(리소스 에디터에서 만들어 넣었던)들을 집어넣는 것,
  • 프레임 윈도우가 키보드 포커스를 얻었을 때 그 아래의 view 윈도우로 포커스를 옮기는 것,
  • 프로퍼티 시트의 내부에 들어가는 프로퍼티 페이지들의 글꼴을 운영체제 시스템 글꼴로 바꾸는 것 등..

이런 사소한 것들도 공짜가 아니라 죄다 MFC가 내부에서 해 주는 일들이다.
Windows API만 써서 프로그램을 만드는 방식은 최고의 작고 가볍고 성능 좋은 프로그램을 만들 수 있지만 생산성도 미칠 듯한 저질이기 때문에, 인제 와서 이런 불편한 방식으로 프로그램을 만들 프로그래머는 거의 없을 것이다. 요즘 세상에 C++도 아닌 C는 사실상 어셈블리나 마찬가지다.

Posted by 사무엘

2013/04/29 08:34 2013/04/29 08:34
, ,
Response
No Trackback , 8 Comments
RSS :
http://moogi.new21.org/tc/rss/response/824

1980년대생이라면 페스카마 호 선상 반란 사건을 기억하시는가?
강릉 무장공비 침투 사건의 딱 한 달쯤 전인 1996년 8월경에 벌어진 참극이다.

페스카마 호는 원양어선이었다. 어업, 아니 선원 생활이라는 건 정말 고되고 힘든 일이다. 그리고 저기서 하는 일은 대규모 육체 노동이 그렇듯이 정교한 팀웍이 요구되며, 누구 한 명이 실수하면 큰 영업 손해와 인명 피해가 발생할 수 있다. 그렇기 때문에 선원들 조직 내부엔 군대만큼이나 엄한 군기와 규율이 존재해 왔다.

그랬는데, 업무에 미숙하여 폭언과 인격모독--당한 사람의 입장에서 쓴 표현--을 자주 당하던 조선족 선원들과, 한국인 선장 및 선원 사이에 마찰이 생겼다. 그들은 나중에는, 옛날에 공산주의자들에게 현혹되어 기업 무너뜨리려 위장 취업한 붉은 노동자들처럼, 업주가 정황상 도저히 들어 줄 수 없는 임금과 복지를 요구하면서 태업과 꾀병을 일삼고, 정상적인 조업을 지속적으로 방해했다.

아무리 구슬리고 타일러도 말이 안 통하니, 선장은 참다못해 조업을 중단하는 손해까지 감수하면서 인근의 항구에다 그들을 하선시켜 버리기로 결정했다. 그들이 그렇게도 원하던 대로 말이다. 단, 이로 인해 발생하는 모든 손해들을 걔네들에게 청구하고, 그들을 앞으로 다시는 배를 못 타게 만드는 블랙리스트 낙인까지 업계 전체에다 찍으면서 말이다.

예상 외의 강경한 조치로 인해 돈이고 일자리고 다 잃고 인생이 송두리째 꼬이게 된 그들은 결국 극단적인 선택을 했다. 7명의 한국인 선원을 한 명씩 꾀어내어 흉기로 잔인하게 살해하여 바다에 던지고, 자기네 반란에 가담하지 않은 조선족 1명, 그리고 범행을 우연히 목격한 인도네시아 선원 3명까지 추가로 살해했다. 총 11명. 그러나 항해에 필요해서 살려 둔 1등 항해사 한국인 선원이 목숨을 건 기지와 노력을 다한 덕분에 범행은 꼬리가 잡혔다.

선원들을 11명이나 살해하고 배를 탈취한 건, 오늘날의 소말리아 해적들도 차마 못 저지른 매우 극악한 범죄이기에 저 조선족 선원 6명은 전원 사형이 선고되었다. 비슷한 시기에 지존파가 모조리 형장의 이슬로 사라진 것을 생각해 보라.
그러나 그들을 선량하고 불쌍한 동포라고 적극 변호하여 조직적이고 잔인한 살인극을 우발 범행으로 둔갑시키고, 사형에서 무기징역으로 감형시키고, 그나마 수괴 1명만 최종적으로 사형 선고된 것조차 그 미만으로 크게 감형시킨 일등공신은 바로..

'독재자의 딸'(?)을 대신하여 지난 18대 대선에서 대통령이 될 뻔했던 유력 대선 후보였다.
덕분에 이때도 피해자는 싹 묻히고, 오히려 살인범 조선족들에게 국민 성금이 가고, 중국 내부에서까지 “한국에서는 중국인이 한국인을 죽여도 무거운 처벌 안 받는구나” 하는 인식이 퍼졌을 정도였다. 훗날 어민을 빙자한 중국 해적들이 한국 공권력을 아주 우습게 여기게 되는 데에도 이 사건이 어느 정도 기여했다고 해석하는 건 좀 비약일까?

세상에 조선족 포함 외노자들이 사회적 약자이니 인권 보호하자고 외치는 배부른 사람들치고, 자기 바로 옆집에 외노자가 사는 걸 좋아할 사람이 과연 있을지 양심을 걸고 솔직하게 묻고 싶다. (오 원춘이 어디 출신이더라? ㄲㄲㄲ) 세상에 약자에 대한 편견과 차별은 괜히 생긴 게 아니다. 약자를 가장한 악인을 분간할 방법이 없으니 생기는 것이다. 주한 미군이 여성을 성폭행· 살해한 것하고 외노자가 더 끔찍한 범죄를 저지른 것이 언론에서는 절대로 동등한 비중으로 다뤄지지 않는 게 현실이다!

이런 와중에 피해자 인권은 없고 오로지 불쌍한 척 하는 놈, 가해자 인권만 챙기는 세상을 만드는 데만 열심인 사람이 정권을 잡아서 국정을 계속 그런 식으로 운영했다면 이 나라는 얼마나 더 도덕적으로 타락하고 얼마나 사회 기강이 무너지고 막장으로 치달았을지 상상만 해도 끔찍하고 몸서리가 쳐진다. 현 대통령이 발언한 취임사에서 언급되었던 상당수의 건전한 문장을 들을 수 없거나 정반대의 논조로 바뀐 채 듣게 됐을 가능성이 높다.

내 블로그의 옛날 글들을 보면 아시겠지만, 본인은 정작 대선 기간 도중에는 정치 발언을 극도로 자제하고 삼가 왔다. 오히려 그땐 <날개셋> 한글 입력기 6.71 작업하느라 바빴다.
겨우 신변잡기· 흠집내기 식의 신문 기사 한두 개를 근거로 특정 후보의 호불호 같은 내 정치관을 표출하고 싶지 않았기 때문이다.

그러나 이제는 다 지난 일이고 흥분도 좀 가라앉았을 테니, 빼도 박도 못할 검증된 심성, 팩트를 기반으로 좀 더 적극적으로 내 의견을 표출해 보련다. 이번 대선 결과는 정말로 축복이고 다행이며, 우리나라가 국운이 최소한 몇 년은 더 남아 있다는 증거이다. 여당이 예쁜 구석이 있어서가 결코 아니라, 야당이 해도 해도 너무하기 때문이다.

Posted by 사무엘

2013/04/27 08:43 2013/04/27 08:43
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/823

1.

남이 짠 레거시 코드를 업무상 들여다보다가 우연히 발견한 건데,
아래의 코드는 비주얼 C++에서는 컴파일되지만 gcc 계열의 다른 컴파일러에서는 컴파일되지 않는다.

class A {
public:
    class B;
};

class A::B {
public:
    A::B() { }
};

일단, 클래스 내부의 하위 클래스를 저런 식으로 forward 선언했다가 나중에 다시 선언하는 문법 자체를 본인은 직접 구사한 적이 전혀 없었다.
그랬는데, 어찌된 일인지 생성자 함수를 선언할 때 클래스 A까지 다 써 주는 것을 비주얼 C++은 허용하지만 다른 컴파일러들은 그러하지 않았다.
왜 그런지, 이와 관련된 표준 규정은 없는지 궁금하다.

2.

Lyn Tono 님의 블로그를 보다가, 평소에 미처 생각도 못 했던 흥미로운 사실을 발견하여 이곳에다가도 소개하겠다.

void foo() { puts("global function"); }

template<typename T>
class C {
    T m;
public:
    //static이든 아니든 사실 상관은 없음
    static void foo() { puts("Member function"); }
};

template<typename T>
class D: public C<T> {
public:
    void bar() { foo(); }
};

위와 같은 함수와 템플릿 클래스를 선언한 뒤 D<int> q; q.bar(); 라고 실행하면,
비주얼 C++에서는 클래스에 소속된 foo 멤버 함수가 불리지만, 역시 gcc 계열의 다른 컴파일러에서는.. 놀랍게도 global 함수가 불린다!
이건 우선순위 문제도 아닌지라, global 함수를 없앤다고 해서 멤버 함수가 차선으로 지명되지도 않는다. 그 경우에도 클래스 멤버는 존재가 무시되고 그냥 컴파일 에러가 난다. -_-;;

그렇다. 템플릿 클래스는 기반 클래스의 멤버 지명이 비템플릿 클래스처럼 그렇게 쉽게 되질 않는다.
this-> (멤버. 심지어 this 포인터가 존재하지 않는 static 함수이더라도) 혹은 :: (전역)을 명시적으로 써 줘야 한다.

내가 생업을 위한 코딩을 하는데 비주얼 C++을 벗어날 일은 거의 없지만, 저 상황에서 당연히 멤버 함수가 불릴 거라고 예상한 게 다른 컴파일러에서는 그렇지 않을 수도 있다는 걸 염두에 둬야겠다.

3.

예전에 비주얼 C++이 지원하는 for each 문에 대해 소개를 했었고, 친절하게 의견을 남겨 주신 김 진 님으로부터 다른 컴파일러에도 range-based for 문에 대한 비슷한 문법이 존재한다는 보충 설명도 들었다.

그런데 비주얼 C++의 경우, for each() 내부에서 중괄호 없이 if...else문을 썼는데, else부터가 왜 인식이 안 되지? 최신 2012까지도. 아무래도 버그가 아닌지 의심된다. 아래의 예들을 보시라.

for(i=0; i<10; i++) if(a) b(); else c(); //원래 OK

for each(auto i in container) if(a) b(); else c(); //ERROR: 이것만 안 될 이유가 없잖아? 왜? 게다가 인텔리센스 컴파일러는 이를 에러로 지적하지 않음.

for each(auto i in container) { if(a) b(); else c(); } //중괄호를 해 주면 OK

for each(auto i in container) a ? b(): c(); //차라리 이렇게 하는 것도 OK

for(auto i: container) if(a) b(); else c(); //xcode의 이 문법도 당연히 아무 문제 없이 OK. 참고로 비주얼 C++도 2012부터는 for each뿐만 아니라 이 문법도 지원하기 시작했으며, else문에 이상이 없다.

웹 표준만큼이나 C++ 표준도 세밀한 부분에서의 이행 여부가 컴파일러마다 케바케인 것 같다.
옛날엔 IE6이 웹 표준을 안 지킨다고 욕 얻어먹은 것만큼이나 VC6도 C++ 표준 미준수 때문에 많은 비판을 받았었다. for 문 안에서 선언한 변수의 scope 문제가 제일 유명하고 말이다.

하지만 표준 자체가 모호하거나 아예 커버하지 않고 있는 사항이 있다면 그저 묵념..

여담이지만, 2차원 배열을 순회하는 경우 비주얼 C++의 for each는 배열 안의 각 원소를 하나씩 일일이 순회하는 반면, for(:) 문은 각 배열의 포인터를 변수에다 넘겨 주면서 여전히 1차원적으로만 순회한다는 차이도 있다.

4.

C/C++에서 작은따옴표는 문자 상수를 나타낸다. sizeof('a')의 값이 C에서와 C++에서 서로 다르다는 건 이미 잘 알려진 사실. 그런데 작은따옴표 안에 탈출문자가 아닌 일반 문자가 둘 이상 중첩되는 게 문법적으로 가능하며, 에러가 아니다. 그리고 더욱 기괴한 것은, 그렇게 중첩되었을 때 이 문자 상수가 갖는 값은 표준으로 정해져 있지 않고 컴파일러 구현체가 해석하기 마음대로라는 것! 일부러 그렇게 규격을 '미정'으로 남겨 놨다.

대부분의 컴파일러에서는 'ab'를 0x4142라고 합성해서 인식하는 식의 배려는 해 주고 있다. 그러나 이것은 애초에 표준 동작이 아니다 보니, 컴파일러의 기반 아키텍처 또는 코드 생성 대상 아키텍처의 엔디언에 따라 세부적인 동작이 달라진다. 다시 말해 이것은 이식성을 전혀 보장받을 수 없는 지뢰밭 같은 테크닉이며, 그렇기 때문에 IOCCC 같은 대회에서 써먹을 수도 없다.

그럴 거면 둘 이상의 문자는 차라리 깔끔하게 경고나 에러 처리라도 해 주지 하는 아쉬움이 있다.
<날개셋> 한글 입력기의 수식은 문자 상수로 둘 이상의 문자를 집어넣으면 문법 에러로 간주한다.

Posted by 사무엘

2013/04/25 08:38 2013/04/25 08:38
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/822

우리나라 철도의 역사에 관심이 많은 철덕이라면 반드시 짚고 넘어가야 할 중요한 주제가 하나 있는데, 그건 바로 여객 열차의 이름의 변천사이다. 열차의 이름은 그 열차의 차종을 식별하는 동시에 등급을 식별하기도 하기 때문에 그 위상이 조금 모호하다. 철도는 고속버스나 비행기처럼 출발지와 도착지만이 중요한 point-to-point 수송 교통수단이 아니라 중간 정차가 차지하는 비중이 높으며, 정차 빈도에 따라 속도의 편차가 큰 여러 열차 등급이 존재할 수 있다.

1899년에 우리나라에 최초의 철도인 경인선이 개통하고 1905년에 경부선이 개통했을 때는 고유명사라 불릴 열차의 이름 같은 건 딱히 없었다. 그냥 빠르다는 수식어가 붙은 ‘급행열차’라는 용어만이 쓰일 뿐이었다. 프랑스의 떼제베(TGV)가 거창한 뜻이 담겨 있는 게 아니라 그냥 ‘아주 빠른 열차’가 전부이듯이 말이다. 증기 기관차로 경인선 제물포-노량진이 1시간 40분 가까이 걸렸고 지금의 서울-부산뻘인 경부선 서대문-초량이 17시간이나 걸렸지만, 그 시절엔 그것만으로도 속도 혁명이라 불리기 충분했다.

그 해 5월부터는 서울-부산이 14시간대로 단축된 특급 열차가 운행을 시작했지만, 아직 그것만을 식별하는 명칭은 없었다. 조선 침략의 원흉인 이토 히로부미가 원 태우 의사에게서 짱돌을 맞아 얼굴을 크게 다친 게 1905년 11월이니, 그건 바로 이 열차의 탑승 중에 발생한 사건일 것이다. 열차의 표정 속도가 아직 시속 30km를 채 못 넘어서 지하철보다도 느리던 시절이다. (그나마 요즘 지하철은 1km를 채 못 달리고 정차를 반복하면서도 그런 표정 속도를 내는데!) 그러니 그 시절엔 열차 밖에서 돌을 던져서 열차 안의 승객을 맞히는 게 가능했다.

한국 철도에서 최초로 고유명사 이름이 붙은 열차는 1906년 4월 16일부터 경부선을 달리기 시작한 ‘융희호’이다. 이것은 망해 가던 대한제국의 연호에서 따 온 명칭이다. 서대문-초량을 11시간 만에 주파했으니 경부선 개통 직후의 열차 운행 시간인 17시간에 비하면 상당히 빨라진 것이고 사실 KTX 개통 전까지 다니던 청량리-부전 전역정차 통일호보다도 빨랐다 (12시간 반이나 걸리던 1221 열차)! 표정 속도는 30km/h를 드디어 돌파하여 지하철을 따라잡았고, 최고 속도는 60km/h 정도에 진입했다.

융희호의 중간 정차역은 KTX 개통 전에 정차를 좀 많이 하던 경부선 새마을호와 얼추 비슷한 수준(8~9개역?)이었다. 여객 취급뿐만 아니라 물과 석탄 보충을 위한 정차도 불가피했다. 그러나 가감속이 병맛인 증기 기관차로 통일호만치 정차를 많이 했다간 그 속도를 절대로 낼 수 없을 것이다.

그때는 ‘융희’라는 이름을 반으로 쪼개서 서울 방면 상행은 ‘융호’라고, 부산 방면 하행은 ‘희호’라고 불렀다고 한다. 이때는 경인선과 경부선이 두 말할 나위가 없이 단선이고 열차 운행도 몹시 드물었기 때문에 특정 열차에 곧바로 고유한 이름이 붙는 것이나 마찬가지였다.

그 당시엔 물가 대비 열차 운임이 지금보다 훨씬 더 비쌌음은 자명한 사실이다. 서민들은 장거리 여행을 하려면 지금으로 치면 고속버스나 KTX가 아니라, 비행기 정도는 타는 각오를 하고 열차를 타야 했다. 박리다매를 할 수 있을 정도로 사람들의 이동이 빈번한 것도 아니었을 뿐더러, 지금도 일본은 본토의 열차 운임이 사철 위주이고 비싼 걸로 악명 높은데 그 시스템이 식민지라고 예외가 아니었다. 실제로 일제가 조선 땅에서 철도를 운영하여 벌어들인 수익은 굉장한 흑자를 냈다고 한다.

융희호가 첫 운행한 건 한강 철교가 완공되고 서울에서 신의주까지 가는 경의선이 개통한(1906년 4월 3일) 거의 직후였다. 다만, 지금과 같은 서울 역은 없었고 공덕, 서강으로 가는 오늘날의 용산선이 그때의 경의선 본선이었으니 그 길을 통해 열차는 서울 이북의 신의주로 갔다. 융희호는 1908년부터 부산-서울이 아니라 부산-신의주를 몽땅 직통 운행하기 시작했다.

자, 그 후 조선이 망하고 일제 식민지가 되고부터는 열차 이름도 대놓고 하카리(빛), 노조미(소망) 같은 일본어가 등장했다. 그리고 스케일은 더 커져서 부산에서 아예 만주까지 열차가 다니기 시작했다. 일제는 애초에 대륙 침략의 발판을 닦으려고 철도를 놓기도 했으니 말이다.

그러다 1936년 12월 1일부터는 ‘아까스키(여명)’ 호라는 특급 열차가 다니기 시작했는데 이것이 일제 강점기를 통틀어 한반도에서 가장 빠른 열차였다. 경부선이 전구간 복선화되기도 전에 그것도 증기 기관차로 서울-부산 무려 6시간 45분을 달성했다는 건 사기에 가깝다. 나중엔 6시간 반으로 더 단축!

일제 강점기 때 이 정도로 인프라가 구축됐으니 그 당시엔 육지에서 철도보다 더 빠른 교통수단은 없었고, 6· 25 때도 대통령과 참모진은 열차를 타고 피난을 갔다. 자동차는 서울을 벗어나면 빠르게 달릴 만한 포장 도로가 없어서 서울-대전이 과장 좀 보태면 8시간씩 걸리는 지경이었다. (사실 지금은 북한이 평양만 벗어나면 이 지경이기도 하고. ㄲㄲ)

우리나라가 일제로부터 해방된 뒤인 1946년 5월 27일, 시대가 시대인 만큼 ‘해방자호’라는 이름의 증기 기관차가 경부선을 다니기 시작했다. 그냥 해방호도 아니고 왜 ‘자’가 붙었나 하면 이건 者를 뜻하기 때문이다. 영어로는 Korean Liberator. 이 열차는 고급 컨셉을 표방하지 않았고 일본인 철도 경영자가 물러나서 그런지 서울-부산 운행 시간이 9시간으로 크게 늘었다.

그리고 한국 철도는 이 승만 정권의 말기인 1960년 초가 돼서야 ‘특급 무궁화호’를 통해 옛날 아까스키 호의 표정 속도를 회복하게 되었다. 동력원은 증기가 아닌 디젤이다.

자막: 특급 무궁화호 등장
경부선에 또 하나의 특별 급행열차가 등장했습니다.
새로운 특급열차는 우리 이 대통령 각하께서 '무궁화호'라고 명명해 주셨는데, 2월 21일 아침부터 운행했습니다.
종래의 통일호보다도 30분이나 빠른 무궁화호는 서울-부산간을 6시간 40분에 달리고 있는 것입니다.


‘호’라는 접미사에서 알 수 있듯이 이때까지 열차의 명명 방식은 배의 명명 방식과 비슷했다. 경부선을 다니는 열차와 호남선을 달리는 열차의 호칭이 달랐다. 이때의 무궁화호는 지금의 무궁화호와는 전혀 관계 없는 경부선 열차였고, 호남선에는 동급의 열차인 삼천리호나 태극호가 달리는 식이었다. 마치 옛날에 타이타닉 호에도 올림픽, 브리타닉 같은 동급의 자매선이 또 있었듯이 말이다.

또한 옛날에 증기 기관차는 오늘날의 디젤이나 전기 기관차와는 달리 외형적인 차륜 배치가 동력비 변환 방식에 직접적인 영향을 끼쳤기 때문에, 여객용 기관차와 화물용 기관차의 구분이 더욱 분명했으며 차륜 형태를 식별하는 이름이 존재했다는 것이 특이점이다. 미카, 901호, 파시 같은 이름이 바로 그 예이다. 이미 아시는 분도 있듯이, 우리나라에서 증기 기관차는 1967년 8월 31일을 끝으로 현역 운행을 완전히 종료한다.

자, 1960년대 이후로는 시대가 시대이다 보니 재건호, 맹호호, 청룡호, 백마호처럼 호가 아니라 ‘부대’를 붙여도 될 것 같은 북한/군대스러운 명칭도 열차에 부여되었는데.. 실제로 박통 시절엔 월남전 참전 부대 이름들이 전부 열차 명칭으로도 의도적으로 쓰였다. 군사 정권 아니랄까봐. 그것 외에도 배에 이름 붙이듯이 열차에도 노선별로 다양한 이름이 난립(?)하기 시작했으니, 상록호, 풍년호, 부흥호까지. 비둘기호와 통일호도 옛날부터 명칭 자체는 존재했다. 단지 이름의 용도 내지 의미가 지금과는 완전히 달랐을 뿐이다.

그러면서 열차의 속도는 특급열차를 위주로 점차 빨라지기 시작했고, 1969년 6월 10일에 등장한 초호화 특급 열차인 관광호가 드디어 서울-부산을 5시간대도 극복한 4시간 50분 주파를 달성했다. 경부 고속도로도 아직 없던 시절에 속도도 속도이거니와, 그 옛날에 객실에 천장 선풍기 대신 에어컨이 달려 있었을 정도면 얼마나 호화로웠을지 상상이 된다. 단지 관광호의 물가 대비 운임은 일본의 신칸센보다도 더 비쌌다는 점 역시 감안하시길. 진짜 돈지랄용이었다.

이 열차는 훗날 1974년 8월 15일, 서울 지하철 1호선이 개통한 날부터 ‘새마을호’라는 새로운 명칭으로 바뀌었으며 이것이 그로부터 30년 뒤에 KTX가 개통할 때까지 대한민국 최고급 열차의 혈통을 이어 나갔다. 서울-대전-대구-부산만 찍는 그 고매한 열차 라인 말이다.

1977년 8월부터는 새마을호를 제외한 모든 열차들은 그냥 등급만으로 우등-특급-보통으로 바뀌게 정리되었다. 일일이 이름을 붙이기에는 열차의 운행 노선과 횟수가 크게 늘어서 이렇게 단순화가 이뤄진 셈이다. 우등열차가 오늘날의 무궁화호의 전신이며, 통일호가 특급이라고 불렸다니 믿어지지 않을 것이다.

1984년 1월 1일이 돼서야 드디어 새마을-무궁화-통일-비둘기 체계가 정립되어서 열차의 이름은 오로지 등급만을 나타나게 바뀌었다. 새마을을 제외한 나머지 이름들은 국민 공모를 통해 뽑은 거라고 하지만, 결국 옛날에 한 번씩 쓰인 적이 있는 명칭들을 재사용한 셈이다.

그로부터 얼마 되지 않아 새마을호는 잘 알다시피 1985년 11월 16일에 서울-부산 운행 시간이 4시간 10분으로 단축되어 표정 속도가 드디어 100km/h를 돌파하였으며, 이것이 한국 철도 역사상 기존선에서 이뤄진 최후의 표정속도 향상 기록이다. 기관차의 출력 증대를 통해 최대 시속 150km 주행 자체는 관광호 시절부터 가능했지만, 선로/선형 개량과 신호 시스템 개선을 통해서 고속 주행 가능 구간을 늘린 덕분에 가능했던 결과이다.

지금까지 과거 얘기가 길어졌으니 이제 미래 전망을 하고서 글을 맺겠다. 1984년 이래로 거의 30년간 쓰여 온 재래식 ‘-호’ 체계는 오늘날 심하게 문란해지고 의미가 퇴색해 있기 때문이다.
일단 지난 2000년 말에 비둘기호가 멸종하였으며, 고속철이 개통하면서 통일호 역시 문서상으로는 사라지고 객차형은 전량 퇴역했다. 통일호 중 통근형 디젤 동차만 통근열차라고 명맥을 잠시 유지했지만, 그나마 얘도 이제 경의선/경원선의 극소수 구간에만 남아 있지 다 멸종이다.

문제는 여기서 그치지 않는다. KTX에 밀려 콩라인이 된 새마을호마저도 사망이 임박했다. 2013년 1월에는 전후동력형 디젤 동차가 드디어 전량 퇴역했고 2014년 말을 끝으로 지금의 새마을호는 객차형까지 죄다 역사 속으로 사라진다.
그럼 ‘-호’ 열차는 무궁화호 하나만 남으니 기존 ‘-호’ 체계가 다 붕괴되는 셈이다.

무궁화호도 디젤 동차(NDC)는 진작에 다 퇴역하고 없기 때문에, 무궁화호는 그냥 재래식 기관차 견인형 일반열차를 총칭하는 상징적인 명칭으로만 남을 것이다. 요컨대 오로지 통일호만이 새마을호와 무궁화호와는 달리 객차형이 동차형보다 먼저 없어졌다. 등급이 등급이다 보니까 말이다.

이런 재래식 열차를 대신하여 꿰차고 들어온 것은 KTX부터 시작해 누리로, ITX-청춘 같은 신형 전동차들이다. KTX는 워낙 특별한 물건이고 누리로는 어차피 무궁화호와 거의 같은 위상과 운임 체계를 계승했다지만, ITX 청춘은 새마을호를 꿰차고 들어와서 새로운 등급을 만들어 냈다. 거기에다 새마을호의 후속 열차로는 ‘ITX 새마을’이라는 이름이 정해졌다고 한다. 1974년 이래로 40년을 이어 가는 ‘새마을’의 명줄은 참 길기도 하다!

오늘날 철도계의 높으신 분들이 생각하는 새로운 명명 전략은, 열차 명칭을 ‘등급-차종’으로 이원화하는 것이라 생각된다.
등급으로는 고속열차를 뜻하는 KTX, 그 다음으로 장거리 특급 간선을 뜻하는 ITX가 있으며, 이보다 낮은 등급에 대한 이름도 정해져야 할 것이다.

다음 차종으로 말할 것 같으면 ‘KTX-산천’이 있으니 재래식 떼제베 열차를 나타내는 ‘KTX-TGV’ 같은 차종명 짝이 있어야 한다. 그리고 경춘선에 ITX-청춘이라는 2층 열차가 다니듯이 기존 경부선이나 호남선에는 ITX-새마을이 다닐 것이고 중앙선에는 틸팅 열차가 다니게 될 수 있다. ‘새마을’이 이제는 등급명이 아니라 차종명으로 쓰이는 셈이다.

그보다 더 아래의 무궁화급라면 ‘누리로’는 등급명이 될지 차종명이 될지 확실치 않으나, 아마 차종명이 될 가능성이 높다. 그리고 새마을(ITX)급이든 무궁화급이든 재래식 기관차-객차형 열차는 ‘클래식’(?)이나 그에 준하는 차종명이 붙지 않을까 싶다. 선박의 명명 스타일에서 유래되었던 한국 철도의 열차 명명 방식이 앞으로 어떻게 바뀔지가 기대된다.

이렇게 열차 이름을 중심으로 우리나라 철도의 역사를 처음부터 끝까지 쭉 읊어 보니 참 훈훈하고 기쁘다. 독자 여러분에게도 철도가 희망과 동경, 기쁨과 평안을 주는 존재이기를 본인은 원한다. May the railroad richly bless you!

Posted by 사무엘

2013/04/22 08:33 2013/04/22 08:33
, , , , ,
Response
No Trackback , a comment
RSS :
http://moogi.new21.org/tc/rss/response/821

세상의 무신론자 중에서
“세상에 신은 존재하지 않으며 내세도 심판도 없다. 내 마음대로 얼마든지 상대적인 잣대로 살아도 된다. 그걸 모르고 하나님이나 찾는 무능하고 어리석은 인생들이 너무 불쌍하다. 나는 그들을 너무 사랑하기 때문에, 무신론이 진리임을 알리기 위해 어떤 희생도 감수하고 내 생명이라도 내어 놓겠다
이렇게 말하고 행하는 사람은 없습니다.

킹 제임스 성경을 알고도 받아들이지 않는 구원받은 크리스천 중에서
“내게는 개역성경/NIV가 최종 권위인 하나님 말씀이다. KJV야말로 6만 구절의 단어를 변개하고 13구절을 후대에 ‘추가’하여 하나님 말씀을 뜯어고친 무시무시한 죄를 저질렀다. 나는 이 엄청난 사실을 정반대로 알고 있는 KJV 지지자들을 계몽하고, 진짜 절대무오한 다른 성경을 대안으로 내놓겠다.
라고 말하는 사람은 없습니다.

제가 무슨 말을 하려는지 아시겠죠?
두 진영은 서로 계산 결과만 다른 게 아니라 계산 과정과 초기의 변수, 생각하는 전제 조건부터가 완전히 다릅니다.

* 평소의 내 블로그 스타일답지 않게 무지하게 짧은 글이 돼 버렸는데..
그래도 내 생각의 핵심은 다 담겨 있으니..ㅎㅎ

Posted by 사무엘

2013/04/20 08:27 2013/04/20 08:27
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/820

마인크래프트 단상

* 마인크래프트를 보면서 떠오르는 것:

  • 이건 “집마다 지은 사람이 있으되 모든 것을 지으신 분은 하나님이시니라.”(히 3:4)를 매우 쉽게 떠올릴 수 있는 게임이다.
  • 비록 그래픽 디테일은 진짜 딱 1990년대 중반의 퀘이크+툼 레이더 1~2 수준이지만, BSP처럼 고정불변 맵에 딱 최적화된 자료구조가 아니라 임의의 광활한 지형을 실시간으로 생성하고 중간 로딩도 거의 없이 실시간으로 3D로 표현하는 게 굉장히 신기하다.
  • 블록의 단위 크기가 1m라는 특성상, 마인크래프트가 제공하는 철도는 762mm짜리 협궤와 비슷하다.
  • 철덕의 기상. 코레일과 KTX CI를 새겨 놓은 용자가 있다! 존경스럽기 그지없다. (첨부 그림 참고. 단, 마인크래프트 실제 게임은 1인칭 3D 시점이 지원된다. 저런 3인칭 2D 시점이 아님.)

사용자 삽입 이미지


Posted by 사무엘

2013/04/18 08:20 2013/04/18 08:20
,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/819

본인이 예전에 글로 썼듯, 비주얼 C++ 201x의 IDE는 소스 코드의 구문 체크 및 인텔리센스를 제공하기 위해 백그라운드에서 완전한 형태의 컴파일러를 실시간으로 돌린다. ncb 파일을 사용하던 200x 시절에는 불완전한 모조 컴파일러였지만 201x부터는 그렇지 않다. 컴파일은 그걸로 하고, 자료 저장은 아예 별도의 DB 엔진으로 하니 계층이 전문화된 셈이다.

그런데 실시간으로 돌리는 컴파일러는, MS가 자체적으로 빌드를 위해 구동하는 컴파일러하고는 다른 별개의 종류이다. 이 개발툴로 오래 개발을 해 본 분은 이미 아시겠지만 같은 문법 에러에 대해서도 메시지가 서로 미세하게 다르고 심지어 문법 해석 방식이 불일치하는 경우도 있다. 마치 MS Office의 리본 UI와 MFC의 리본 UI는 구현체가 서로 별개이고 다르듯이 말이다.

그럼 이 보이지 않는 백그라운드 컴파일러의 정체는 뭘까? 이건 ‘에디슨 디자인 그룹(Edison Design Group)’이라고 유수 프로그래밍 언어들의 컴파일러 ‘프런트 엔드’만 미들웨어 형태로 전문적으로 개발하여 라이선스를 판매하는 어느 벤처기업의 작품이다. MS에서는 이 물건을 구입하여 자기 제품에다 썼다.

컴파일러를 만드는 것은 오토마타 같은 계산 이론부터 시작해서 어려운 자료구조와 알고리즘, 컴퓨터 아키텍처 지식이 총동원되는 매우 까다롭고 어려운 과정이다. 그렇기에 컴파일러는 전산학의 꽃이라 불리며, 대학교 전산학과에서도 4학년에 가서야 맛보기 수준으로만 다뤄진다.

그리고 컴파일 메커니즘은 프런트 엔드와 백 엔드라는 두 단계로 나뉜다. 소스 코드의 구문을 분석하여 문법 오류가 있으면 잡아 내고 각종 심벌 테이블과 parse tree를 만드는 것이 전자요, 이를 바탕으로 각종 최적화를 수행하고 실제 기계어 코드를 생성하는 건 후자이다.

굳이 코드 생성까지 하지 않아도 구문을 분석하여 인텔리센스를 구현하는 것까지는 프런트 엔드만 있어도 충분할 것이다. 프런트 엔드를 담당하는 쪽은 언어의 문법을 직접적으로 다루고 있으니, C++11 표준이 뭐가 바뀌는 게 있는지를 늘 매의 눈으로 감시하고 체크해야 한다. 그리고 그런 엔지니어들이 역으로 표준의 제정에 관여하기도 한다.

에디슨 디자인 그룹은 5명의 베테랑 프로그래머들로 구성된 아주 작은 회사이다. (홈페이지부터 디자인이 심하게 단촐하지 않던가?) 하지만 세계를 움직이는 굴지의 IT 회사들에 자기 솔루션을 납품하고 있다. 작지만 기술이 강한 이런 회사야말로 컴퓨터 공돌이들이 꿈꾸는 이상적인 사업 모델이 아닐 수 없으니 매우 부럽다. 개인이 아닌 기업이나 교육 기관이 고객이며, 한 솔루션의 소스 코드를 납품하는 라이센스 비용은 수만~수십만 달러에 달한다.

마이크로소프트 컴파일러는 인텔리센스만 이 회사의 솔루션으로 구현한 반면,
Comeau C++ 컴파일러는 프런트 엔드가 이것 기반이다. Comeau라 하면, C++의 export 키워드까지 다 구현했을 정도로 표준을 가장 충실하게 따른 걸로 유명한 그 컴파일러 말이다.

굳이 백 엔드와 연결된 컴파일러가 아니어더라도, 프런트 엔드가 만들어 낸 소스 코드 parse tree는 IDE의 인텔리센스를 구현한다거나 소스 코드의 정적 분석, 리팩터링, 심벌 브라우징(browsing), 난독화 등의 용도로 매우 다양하게 쓰일 수 있다. 나름 이것도 황금알을 낳는 거위 같은 기술이라는 뜻이다.

한편, 전세계 유수의 컴파일러들에 C++ 라이브러리를 공급하는 회사는 Dinkumware이라는 걸 난 예전부터 알고 있었다. 헤더 파일의 끝에 회사 설립자인 P.J. Plauger 이름이 늘 들어가 있었기 때문이다. 난독화가 따로 없는 그 암호 같은 복잡한 템플릿들을 다 저기서 만들었다 이 말이지?
비주얼 C++이라는 그 방대한 제품은 당연한 말이지만 모든 부품이 MS 독자 개발은 아니라는 걸 알 수 있다.

그나저나, 비주얼 C++ 201x의 백그라운드 컴파일러는 C 코드에 대해서도 언제나 C++ 문법을 기준으로만 동작하더라.. ㅎㅎ

Posted by 사무엘

2013/04/16 08:40 2013/04/16 08:40
, , , ,
Response
No Trackback , 3 Comments
RSS :
http://moogi.new21.org/tc/rss/response/818

다음 버전 개발 근황 ㅋ

<날개셋> 한글 입력기 6.8이 나온 지 벌써 두 달 정도 시간이 지났다. 이 버전은 잘 알다시피 외부 모듈까지 Windows 8을 정식 지원하기 시작한 첫 버전이라고 선전... 은 했는데, 그 후로 Win8 사용자들로부터 역시 여러 미흡한 점들이 보고되었다..

  • IE의 주소 입력란 말고, 웹페이지 폼의 입력란에서 글자를 입력하는 중에 한/영 상태 버튼을 우클릭하면 메뉴 항목들이 disabled되어 나오는 것: 무척 괴이한 현상이지만 어쨌든 해결함
  • Modern(Metro) UI의 IE에서는 데스크톱 모드에서 맞춰 놓은 입력 설정이 제대로 반영되지 않고 동작하는 것: 파일 읽기에 문제가 있는 듯
  • 날씨(Weather) 같은 일부 자바스크립트 기반 앱에서는 <날개셋> 한글 입력기 커널 자체가 제대로 구동되지 못하고 영문만 입력되는 것: 역시 커널 DLL 파일에 접근하는 과정에 문제가 있는 듯. 권한 문제?

저것 말고 여전히 Windows 8의 Modern UI에서 <날개셋> 한글 입력기의 사용에 문제가 있는 분은 운영체제의 부팅 이후로 문제를 재연하는 모든 step을 마우스 클릭 단위로 상세하게 알려 주시기 바란다. 난 Windows 8 안 써서 그쪽 UI를 잘 모른다..;;더구나 데스크톱 앱과는 달리, Modern 앱들은 디버깅을 위해서 꼭 인터넷 접속을 해야 한다는 게 개인적으로 굉장히 불편하다. 정작 내 프로그램은 인터넷 같은 건 전혀 사용하지 않는데...

또한 근본적으로 Win8은 기존 데스크톱 환경과 Modern(메트로) 환경 사이에 장벽을 너무 많이 쳐 놨다. 그래서 데스크톱을 근간으로 하고 있으면서 Modern용 프로세스의 안에서도 서식해야 하는 외부 모듈에게 보안상 걸리는 제약이 너무 많다. 서로 memory mapped-file도 공유가 안 되고, Modern 프로세스 안에서는 대부분의 디렉터리에 접근도 안 되고.. 내 문서, ProgramData 다 안 된다.

Program Files와 Windows 디렉터리만 접근을 허용한다고 하는데, 전자는 32비트와 64비트가 따로 존재하기 때문에 사전이나 테이블 같은 공용 데이터를 놔 두기에는 적절하지 않은 위치이며 더구나 관리자 권한이 없으면 파일을 쓸 수도 없다. Windows\IME는 공식 설정상으로는 애초에 운영체제의 보급 IME들만이 사용하는 위치이다. 도대체 IME는 뭐 어떻게 동작하면서 Modern와 데스크톱 사이에 설정을 공유하라는 건지 모르겠다. 결국 레지스트리를 파일처럼 정보 공유 매체로 다루는 수밖에 없어 보인다.

뭐, 다음 버전을 개발하는 과정에서 이 이슈 말고도 다른 쪽으로도 <날개셋> 한글 입력기는 6.8 이래로 소스 코드가 많이 바뀌었다. 6.8은 다행히도 그 버전 자체만의 예기치 못한 버그가 들어있지 않으며 그럭저럭 잘 만들어졌다. 그래서 이 버전에 대한 유지 보수를 따로 할 필요가 없이 다음 버전인 7.0이 잘 개발되고 있는 중이다. 본인으로서는 다행스러운 점이다.

다음 버전 개발 근황을 좀 마이너한 아이템 위주로 늘어놓자면 이렇다.

1. 한컴 2바이트 코드와 한양 PUA 코드 변환과 관련된 모든 기능들은 드디어 <날개셋> 커널에서 완전히 삭제되었다. legacy 문자 코드에 대한 지원은 이미 4.8x대에서부터 차츰차츰 줄어들고, 커널에 있던 코드가 플러그 인 변방으로 이동하는 식으로 리팩터링이 진행되고 있었는데 그게 다 끝을 본 것이다. 이제 커널인 ngs3.dll에는 그런 문자 코드의 처리와 관련된 일체의 코드(프로그램)가 들어있지 않다.

2. 유니코드 문자열로부터 한글을 읽거나 쓰는 알고리즘을 미세하게나마 좀 더 최적화하고, 문자 인코딩을 자동 판단하는 알고리즘도 더 똑똑하게 개선했다. 한글이 없이 특수문자만 가득한 2바이트 인코딩을 제대로 판단을 못 하거나, 1바이트 아스키 문자 나열을 UTF16으로 오인하는 경우를 대폭 줄였다.
이 프로그램은 예나 지금이나 유니코드 UTF16, UTF8, 완성형(CP949), 그리고 조합형 코드(CP1361)을 자동 인식할 수 있다.

3. <날개셋> 편집기는 지난 3.0 시절부터 ‘기타 가져오기’ 기능을 통해 콘솔 프로그램의 출력 결과를 그대로 가져오는 기능이 있는데, 이 기능이 먼 옛날 버전부터 지금에 이르기까지 무척 비효율적으로 구현되어 있었음을 발견하여 대대적으로 개선했다.
언제든지 ‘취소’를 누르면 작업이 즉시 취소된다. stdout뿐만 아니라 stderr의 출력 결과도 가져온다. 그리고 프로그램의 실행이 끝난 뒤에도 작업 스레드가 정상적으로 끝나지 않고 강제 종료되고 있었던 것을 고쳤으며, 이 때문에 heap과 stack 메모리에서 발생하던 숱한 메모리 누수들도 덩달아 해결했다..

4. <날개셋> 편집기는 MFC를 쓰지 않고 자체 개발된 이래로 '창' 메뉴를 보면, 현재 선택되어 있는 문서 창의 항목에 체크가 표시되지 않는 버그가 있었다.. =_=;; 이걸 뒤늦게 인지하여 고침.

5. 외부 모듈의 경우 잘 알다시피 아이콘이 Windows 8 스타일의 흑백 배색으로 바뀌었는데, 표준 가이드라인에 따르면 겉의 테두리가 회색이 아니라 사실은 50% 알파가 적용된 검정이었다. 그것을 고쳤다.
그리고 사용 중인 글자판의 종류를 판단할 때, 비록 알파벳과 한글을 모두 입력할 수 있는 모호한 글자판이라도 한글(가/한) 판정이 후하게 나도록(A) 알고리즘을 살짝 고쳤다.

6. 외부 모듈은 제어판을 열어서 ‘확인’을 눌러서 종료하면 새로 바꾼 입력 방식이 모든 프로그램에서 곧바로 적용되어야 한다. 하지만 32비트 프로그램과 64비트 프로그램 사이에서는 이것이 동기화가 되지 않던 문제가 있었다. 새 버전은 이것을 해결했다. <날개셋> 한글 입력기가 64비트 플랫폼을 지원한 건 4.x시절 말기부터이고 시기적으로는 무려 5~6년이 지났는데 지금까지 이 점에 대해서는 전혀 생각을 못 하고 있었다.

7. 한글 로마자 입력 방식에서 표준 방식은 O+A로는 ‘ㅘ’가 되지 않고 오로지 W+A로만 ‘ㅘ’가 되게 규칙을 수정했다..

8. 일반적인 세로 스크롤용 휠뿐만 아니라 가로 스크롤 휠도 이제 드디어 지원한다. 일부 노트북 PC에서 터치패드 한쪽 끝을 가로로 드래그하면 이 메시지가 가는 경우가 있는데, 덕분에 편집기나 화면 인쇄 등 주요 화면에서 가로 스크롤이 가능해졌다.

<날개셋> 한글 입력기는 글쇠배열이나 오토마타 같은 걸 자유롭게 사용자 정의 가능하고 한글 입력과 관련된 거의 모든 아이디어들을 한데 기술할 수 있는 기반을 마련한 것으로 잘 알려져 있다. 하지만 그것 못지않게 이 프로그램의 독특한 면모는 바로 다양하고 개성 있는 구현체들이다. 문자 입력 기능을 제공할 수 있는 모든 형태의 구현체를 제공하기 때문이다.

편집기는 자체 한글 텍스트 에디터로, 문서 편집 창이 뜨는 일반적인 응용 프로그램과 가장 비슷한 형태이다. 전용 환경이다 보니 제공되는 기능이 가장 많고 특히 텍스트 필터를 써 볼 수 있는 사실상 유일한 구현체이다.
흔히 IME라고 불리는 외부 모듈은 EXE가 아니라 DLL이다. 범용성과 존재감이 가장 큰 구현체이다. 제공하는 기능의 양은 편집기보다 적지만, Windows 95부터 8까지의 모든 운영체제들의 특이사항을 커버하느라 코드의 양은 이게 편집기의 그것보다 더 많다.

변환기는 문자를 입력하는 기능은 없지만 한글의 표현과 관련된 호환성 유지를 위해 필요한 기능들을 한데 담은 유틸리티로, 간단한 대화상자 형태이다.
끝으로 입력 패드는 포인팅 장비를 이용한 문자 입력 기능만 제공하는 작은 프로그램으로, EXE 형태이지만 IME 내부 자료구조에 대한 훅킹을 통해 동작한다.

이런 모든 경우를 다 생각해서 개발되었다는 뜻이다. 이 구현체들은 심지어 도움말 내지 About 명령조차 서로 전부 제각각인 위치에 있을 정도로 사용자 인터페이스가 천차만별이다. (편집기는 프로그램의 도움말 메뉴, 외부 모듈은 입력 도구모음줄의 도움말 버튼, 변환기는 프로그램의 시스템 메뉴, 입력 패드는 시스템 트레이의 우클릭 메뉴)

개인적인 생각은 이들 프로그램의 아이콘도 마치 MS Office의 Word, Excel 등처럼 뭔가 한 제품에 속한다는 통일성이 느껴지는 형태로 바꾸고 싶다. <날개셋> 편집기의 지금 아이콘도 써먹은 지 벌써 10년이나 됐는데..

가끔은 까마득한 옛날의 1.x와 2.x버전을 꺼내서 실행해 본다. 내가 세상에 이런 완전 캐허접한 프로그램만으로 옛날에 정보 올림피아드 입상을 했구나 하는 생각이 든다. 1은 텍스트 에디터 하나 제대로 만들 기술도 없던 상태에서 그냥 세벌식 자판만을 위한 똘끼어린 최소한의 기술 데모일 뿐이었고 2는 버전 3을 만들기 위한 숱한 시행착오 단계였다.

3에서는 진짜 최소한의 뿌리와 기반이 갖춰지긴 했으나 아직도 허접한 UI와 외부 모듈의 안정성을 갖추기 위해 갈 길은 멀고도 험했다. 4는 버전 3이 경험한 시행착오들을 수습하면서 운영체제에 대한 독자적인 기술과 노하우가 차츰차츰 쌓이던 단계였고, 개발 8주년이 된 버전 5가 돼서야 내가 보기에 슬슬 쓸 만한 물건이 나오기 시작했다. 그리고 그 컨디션이 6에서 계속되는 중이다.

이 정도로 혼자 오래 꾸준히 개발한 프로그램이니, 내가 무슨 게임을 만든 것도 아닌데 이 프로그램에 대한 나의 애착과 중독성은 상당한 수준이다.
일단 결과물 자체부터 내가 매우 애용하고 있다. 비록 현실적으로는 외부 모듈이 가장 대중적으로 쓰이는 구현체일지 모르나 내가 가장 애용하는 구현체는 편집기이다. 자체적으로 문서를 편집하는 기능을 갖춘 일반적인 애플리케이션이며, 가장 먼저 개발되기도 했기 때문이다. 그냥 습관적으로 띄워서 뭐라도 글을 쓰고 한글 오덕질을 하고 싶은 생각이 절로 든다.

결과물뿐만이 아니라 도움말도 계속 읽어보고 싶고, 딱히 코딩을 안 해도 소스 코드를 꺼내서 뭐라도 리팩터링이나 최적화를 하고 싶다. 불행인지 다행인지 이 프로그램에 대한 모든 정체성과 권리는 본인이 혼자서 완전히 꽉 잡고 있기 때문이다. 1인 독재. <날개셋> 한글 입력기의 모든 바이너리들은 100% 자작 코드로만 이뤄져 있다.

그런데 여기에만 매여 있느라 다음 다른 연구도 제대로 못 할 정도인 건 문제인 것 같다.
이것과 관련된 개발 말고 다른 분야에는 도무지 관심이 생기질 않아서, 이걸 못 하고 덕업일치를 못 하느니 프로그래밍은 확실하게 취미 수준으로 접고 차라리 철도 같은 업종 전환도 고려할 정도로 진로가 좀 이상한(?) 방향으로 흘러가고 있다. 난 어지간한 다른 IT 분야 엔지니어들과는 애초부터 입문한 계기도 달랐고, 적성이나 취향도 다른 것 같다.

Posted by 사무엘

2013/04/13 08:30 2013/04/13 08:30
Response
No Trackback , 13 Comments
RSS :
http://moogi.new21.org/tc/rss/response/817

IOCCC라고, 사람이 가장 알아 보기 힘들고 충공깽스러운 형태로 작성된 C 프로그램 코드를 접수받는 공모 대회가 있다.
단순 코더가 아니라 전산학 내공과 해커 기질이 충만한 레알 베테랑 프로그래머라면 이미 들어서 알 것이다.

입상작들은 내가 보기에 크게 (1) 아스키 아트형, 아니면 (2) 크기 줄이기 암호형이라는 두 갈래로 나뉜다. 대회에 공식적으로 이런 식으로 참가 부문이 나뉘어 있는 건 아니지만, 여기 참가자들이 추구하는 오덕질의 목표가 대체로 이 둘 중 한 갈래로 나뉘기 때문이다.

전자는 영락없이 아스키 문자로 사람 얼굴이나 문자 같은 그림을 그려 놨는데 그건 컴파일 되는 올바른 C 코드이다. 그뿐만이 아니라 그걸 실행하면 기가 막힌 유의미한 결과물이 나온다. 간단한 게임이라든가 원주율값 계산 같은 것부터 시작해 심지어 CPU 에뮬레이터나 간단한 컴파일러, 운영체제까지 들어있는 경우도 있다.

후자는 수단과 방법을 가리지 않고 길이를 줄이기 위해 들여쓰기, 주석, 헝가리언 표기법 따위는 다 쌈싸먹고 진짜 정체를 알 수 없는 이상한 숫자와 기호와 문자로 범벅이 된 코드인데, 빌드해 보면 역시 소스 코드의 길이에 비해 믿을 수 없는 퀄리티의 동작이 나온다. 자바스크립트 같은 코드를 난독화 처리한 것과 비슷한 형태가 된다.

어떤 언어에서 소스 코드 자신을 출력하는 프로그램을 콰인(Quine)이라고 부른다. GWBASIC이라면 언어에 LIST라는 명령이 있으니 쉽겠지만, 일반적인 컴파일 기반 언어에서는 그걸 만드는 게 보통일이 아니다. 그런데 이 IOCCC 대회 입상작 중에는 A라는 코드가 있는데 그걸 실행하면 B라는 소스 코드가 출력되고, B를 빌드하여 실행하면 C라는 소스 코드가 나오고, 다음으로 C를 빌드하면 다시 A가 나오는... 중첩 콰인을 실현한 충격과 공포의 프로그램도 있었다. 그것도 A, B, C는 다 형태가 완전히 다르고 인간이 인식 가능한 아스키 아트! Don Yang이라는 사람이 만든 2000년도 입상작이다.

역대 수상작들을 보면 프로그래머로서 인간의 창의력과 잉여력, 변태스러움이 어느 정도까지 뻗칠 수 있는지를 알 수 있다. 그리고 이런 대회는 한 프로그래밍 언어의 극악의 면모를 시험한다는 점에서 전산학적으로도 나름 의미가 있다. 들여쓰기와 긴 변수명과 풍부한 주석이 갖춰진 깔끔한 코드든, 저런 미친 수준의 난독화 코드든 컴파일러의 입장에서는 어차피 아무 차이 없는 똑같은 코드라는 게 아주 신기하지 않은가?

다른 언어가 아니라 C는 시스템 레벨에서 프로그래머의 권한이 강력하다. 그리고 전처리기를 제외하면 특정 공백 문자에(탭, 줄바꿈 등) 의존하지 않는 free-form 언어이며, 언어 디자인 자체가 온갖 복잡한 기호를 좋아하는 오덕스러운 형태인 등, 태생적으로 난독화에 유리하다. 게다가 도저히 C 코드라고 볼 수 없을 정도로 코드의 형태와 의미를 완전히 엉뚱하게 뒤바꿔 버리는 게 가능한 매크로라는 비장의 무기까지 있다!

심지어는 C++보다도 C가 유리하다. 함수를 선언할 때 리턴 타입을 생략하고 함수 정의에서는 리턴 문을 생략할 수 있다. 가리키는 대상 타입이 다른 포인터를 형변환 없이 바로 대입할 수 있으며, 또한 인클루드를 생략하고 표준 함수를 바로 사용할 수도 있다. C++이었다면 바로 에러크리이지만, C에서는 그냥 경고만 먹고 끝이니 말이다. C의 지저분한 면모가 결국 더 짧고 알아보기 힘든 코드를 만드는 데 유리하다는 뜻 되겠다.

현업에서는 거의 언제나 C++만 써 와서 잘 실감을 못 했을 뿐이지, C는 우리가 생각하는 것보다 저 정도로 꽤 유연(?)한 언어이긴 하다. IOCCC 참가자의 입장에서 C++이 C보다 언어 구조적으로 더 유리한 건, 아무데서나 변수 선언을 자유롭게 할 수 있다는 것 정도일 것이다.

그러나 겨우 그 정도로는 불리한 점이 여전히 유리한 점보다 더 많은 것 같다. 생성자와 소멸자, 오버로딩, 템플릿 등으로 더 알아보기 힘든 함축적인 코드를 만드는 건 상당한 규모가 있는 큰 프로그램에서나 위력을 발할 것이고, 긴 선언부의 노출이 불가피하여 무리일 듯.

옛날에는 대회 규정의 허를 찌른 엽기적인 꼼수 작품도 좀 있었다.
이 대회는 1984년에 처음 시작되었는데, 그때 입상작 중에는 main 함수를 함수가 아니라 기계어 명령이 들어있는 배열로 선언해 놓은 프로그램이 있었다(1984/mullender). 이건 기계 종류에 종속적일 뿐만 아니라 요즘 컴파일러에서는 링크 에러이기 때문에, 그 뒤부터는 대회 규정이 바뀌어 이식성 있는 코드만 제출 가능하게 되었다.

그리고 1994년에는 콰인이랍시고 0바이트 소스 코드가 출품되었다(1994/smr). 소스가 0바이트이니, 아무것도 출력하지 않아도 콰인 인증..;; 이건 충분히 참신한 덕분에 입상은 했지만 그 뒤부터는 역시 소스 코드는 1바이트 이상이어야 한다는 규정이 추가되었다. 빈 소스 파일을 빌드하려면 빌드 옵션도 좀 미묘하게 변경을 해야 했다고 한다.

이런 코드를 작성하기 위해서는 모든 변수와 함수를 한 글자로 표현하는 것부터 시작해서 평범한 계산식을 온갖 포인터와 비트 연산자로 배배 틀기, 숫자 테이블 대신 문자열 리터럴을 배열로 참고하기(가령, "abcd"[n]) 같은 건 기본 중의 기본 테크닉이다. 그리고 그걸 아스키 아트로 바꾸는 능력이라든가, 원래 오리지널 프로그램을 기가 막히게 짜는 기술은 별개이다. 이런 코드를 만드는 사람은 정말 코딩의 달인 중의 달인이 아닐 수 없다.

이 대회는 전통적으로 외국 해커 덕후들의 각축장이었다. 그러나 지난 2012년도 대회에서는 자랑스럽게도 한국인 입상자가 한 명 배출되었는데, 본인의 모 지인이다. 그가 출품한 프로그램은 영어로 풀어 쓴 숫자를 입력하면(가령, a hundred and four thousand and three hundred and fifty-seven) 그걸 아라비아 숫자로 바꿔 주는 프로그램(104357). 코드를 보면 저게 어딜 봐서 숫자 처리 프로그램처럼 생겼는가. -_-

코드를 대충 살펴보면, long long이 바로 등장하는 데서 알 수 있듯, 나름 32비트 범위를 벗어나는 큰 자리수까지 지원한다. 문자열 리터럴을 배열로 참고하는 것도 곧바로 쓰였음을 알 수 있다.
그리고 옛날의 C 시절에 허용되었던 관행이었다고 하는데, 함수의 인자들을 아래와 같은 꼴로 선언하는 게 이 대회 출품작에서는 종종 쓰인다고 한다.

int func(a,b) int a, char *b; { ... }

하긴, C/C++이 기괴한 면모가 자꾸 발견되는 건 어제오늘 일이 아니다.
a[2]뿐만이 아니라 2[a]도 가능하다든가,
#include 대상으로 매크로 상수도 지정 가능하다든가,
C++의 default argument로 0이나 -1 같은 것뿐만 아니라 사실은 아예 함수 호출과 변수 지정도 가능하다는 것..
switch문의 내부에 for 같은 다른 반복문이 나온 뒤에 그 안에 case가 있다던가..;;

정말 약 빨고 만든 언어에다 약 빨고 코딩한 개발자라고밖에 볼 수 없다.
나로서는 범접할 수조차 없는 이상한 프로그래밍 대회에 한동안 엄청 관심을 갖더니 결국 입상해 버린 그의 오덕력에 경의를 표한다. 그저 놀라울 뿐이다. 이 정도로 소개하고 띄워 줬으니, 그분이 이 자리에 댓글로 소환되는 걸 기대해 보겠다. 아무래도 한국인 다윈 상 수상자가 배출된 것보다는 훨씬 더 자랑스러운 일을 해낸 친구이지 않은가. ㄲㄲㄲㄲㄲㄲㄲ

뭐, 입상했다고 당장 크게 부와 명예가 뒤따르는 건 아니겠지만, 팀장이나 임원이 IOCCC에 대해서 아는 개발자 출신인 회사에 지원할 때 “나 이 대회 입상자요!”라고 이력서에다 써 넣으면 그 이력서의 메리트는 크게 올라갈 수밖에 없을 것이다. 실제로 IOCCC 같은 잉여로운 대회에 참가하는 geek 중에는 구글, MS급 회사 직원도 있고, 사실 이런 대회에 입상할 정도의 guru급 프로그래머가 일자리를 못 구해 걱정할 일은 절대 없을 테고 말이다.

이런 대회에 더 관심 있으신 분은, IOCCC의 국내 저변 확대를 위해 애쓰고 있는 저 친구의 소개 페이지를 참고하시기 바란다.

Posted by 사무엘

2013/04/10 19:20 2013/04/10 19:20
, , , ,
Response
No Trackback , 6 Comments
RSS :
http://moogi.new21.org/tc/rss/response/816

열차 좌석 배당 알고리즘

열차의 승차권을 구입하면 좌석은 어떤 식으로 배당될까?
객차 하나당 좌석은 차량에 따라 60~70개 정도가 있으며, 열차 한 편성은 일반실만 생각하더라도 최하 4량부터 시작하고 KTX의 경우 거의 15량에 가깝다. 수백 개의 좌석들은 어떤 순서와 원칙대로 승객에게 팔려 나갈까?

난 철덕후로서 그 알고리즘이 예전부터 굉장히 궁금했다. 여러분은 그렇지 않은가?

버스 정도면 그냥 아무렇게나 랜덤으로 배당해도 별 무리가 없을 것이다.
우등 고속버스는 가장 쉽다. 승차 정원부터가 30명이 채 안 되는 소규모인 데다, 좌석이 구조적으로 2개짜리와 1개짜리로 나뉘어 있으니 말이다.

단독 승객에게는 진행 방향 기준으로 오른쪽의 단독 좌석부터 먼저 배당해 주고, 그게 매진되거나 2인 승객이 있으면 2인 좌석을 준다. 상석인 맨 앞자리는 약간 나중에 팔리도록 다른 가중치를 부여하고, 반대로 최악의 자리인 맨 뒷자리는 최하위 우선순위로 팔리게 하면 될 것이다.

그러나 열차는 단순하게만 좌석을 배당해서는 대략 곤란하다.
1부터 n호차까지, 그리고 진짜 무식하게 1번부터 m호석까지 앞에서 뒤로 순서대로 꽉꽉 승객을 채워 넣어서 뒤의 객차는 텅 빈 채로 달리게 할 리는 없을 테고..

그렇다고 좌석을(특히 단독 승객) 완전 랜덤으로만 여기저기 들쭉날쭉으로 배당하면 좌석의 단편화(fragmentation)가 너무 심해진다. 그래서 승객이 얼마 타지도 않은 상태인데 이따금씩 타는 2인 이상의 다수 승객은 이어진 좌석을 못 구해서 서로 찢어져서 앉아야 하는 일이 벌어질 수 있다.

결국 본인이 추측하기로는 열차의 좌석 배당은 저 양 극단의 중간을 절충하는 방식으로 이뤄질 것 같다.
두세 개의 객차를 묶음으로 나눠서 한 묶음 안에서 좌석을 무작위로 배당한 뒤, 그 묶음의 좌석이 다 매진되면 다음 묶음으로 간다. 각 묶음은 1~3호차, 4~6호차, 7~9호차 같은 규칙으로 만들 수도 있고, 반대로 1, 4, 7호차와 2, 5, 8호차, 3, 6, 9호차 같은 규칙으로 만들 수도 있다.

그리고 각 객차 안에서는 전체의 50~60% 정도는 단독 승객이 무작위로 띄엄띄엄 앉을 수 있게 배려한다. 즉, 2개짜리 좌석이라도 한 자리에 단독 승객이 있으면 거기는 일단 건너뛰고 다른 빈 자리를 찾는다는 뜻이다. 그러나 나머지 자리는 가능한 한 2인 승객이 한꺼번에 찜할 수 있게 비워 두며, 한 객차의 좌석의 10~20% 정도는 마치 KTX 동반석처럼 4인 가족이 연속해서 앉을 수 있게, 가능한 한 1~2인 승객에게 금세 팔리지 않도록 비워 둔다.

단독 승객의 경우 창측 좌석이 내측 좌석보다 먼저 팔리게 하는 건 기본이다. 또한 열차에서는 출입문과 가까운 맨 앞이나 맨 뒤 좌석이 '안 좋은 자리'이므로 이것 역시 다른 좌석이 모두 팔린 뒤에 나중에 팔리게 해야 할 것이다.
단독 승객용 좌석과 2인 이상 승객용 좌석 영역을 정하는 것 역시 '엿장수 마음대로' 무작위로 하면 되며, 그 비율 역시 평소에 승차권이 팔리는 단위 통계를 근거로 합리적으로 정하면 될 것이다.

저런 균형적인 요소에 덧붙여 환승 동선도 고려 대상이 된다.
국내의 예를 들면 KTX 천안아산 역과 장항선 아산 역은 남쪽 끝에서 만난다. 그리고 KTX는 한 편성이 무려 400m가 약간 안 되는 매우 긴 열차이다. 그렇기 때문에 경부선 KTX를 타다가 천안아산 역에서 장항선으로 환승하는 승객은 부산 방면(하행) 열차의 경우 최대한 앞쪽 객차로 좌석이 배당되고, 서울 방면 열차는 뒤쪽 객차로 좌석이 배당된다. 지하철에서 환승을 빨리 할 수 있는 객차의 위치와 정확히 같은 개념이며, 한국 철도도 그 정도 센스는 이미 갖추고 있다.

이 정도면 내가 보기에 열차 좌석 배당 전략을 짜는 건, 마치 열차 시각표를 짜는 것에 필적하는 철도 영업 기술의 결정체가 될 수도 있을 것 같다.
현실성 있는 열차 운행 시각표를 짜기 위해서는 그 나라의 철도 인프라와 지형 특성, 차량 제원, 승객 패턴 등의 알토란 같은 영업 기밀이 총동원되어야 한다. 이런 걸 계획하는 건 인원을 더 투입한다고 신속하게 되는 게 아니며, 핵심 똘똘이 인력 한두 명이 다 도맡아 한다.

좌석 배당도 마찬가지일 거라는 말이다. 철덕이라면 반드시 정복해야 하는 분야 중 하나 되시겠다.
비행기는 무게 배분이(한쪽에만 승객 무게가 지나치게 쏠리지 않게) 좌석 배당에 감안되는 요인이라고 하는데, 철도는 무게 배분 걱정은 할 필요가 없는 대신 길다는 특성상 다른 변수가 존재하는 셈이다.

자, 여기까지만 글을 쓰려고 했는데, 빈 좌석에다 승객을 일정 규칙대로 채워 넣는 과정을 생각하자니 컴퓨터그래픽에서 중요하게 다뤄지는 알고리즘 분야가 문득 떠오르더라.
바로 디더링이다.

디더링은 적은 수의 색깔을 섞어서 더 화려한 색깔을 아쉬운 대로 표현하는 기법이다. 색을 물리적으로 섞을 수는 없으니 결국 서로 다른 색깔을 번갈아가며 늘어놔야 하는데, 한 색깔이 뭉치는 게 아니라 서로 다른 색깔들끼리 최대한 고르게 퍼지도록 픽셀을 배열해야 한다.

본인은 과거에 Windows 3.x 시절에 그림판에서 임의의 RGB 값을 주면 그 색을 16컬러만으로 디더링하여 표현하는 걸 보고 무척 신기해했었다. 가령, 흑에서 백으로 단계를 증가시킬 때, 검은색에서 흰색 점이 차츰 늘어나는 순서가 어떻게 정해지는지가 무척 궁금했다.

그 규칙을 디더링에서 threshold matrix라고 부른다. 일반적인 그래픽 프로그램에서는 8*8짜리를 사용한다. (출처는 위키백과) 저기서 1부터 16까지의 점을 순서대로 채우면 25% 음영이 그려지고, 32까지 채우면 흑백이 딱 반반씩 번갈아가며 등장하는 50% 음영이 되는 식이다.

사용자 삽입 이미지
처음에는 4픽셀 간격으로 띄엄띄엄 점을 그리고, 나중에는 그 사이의 4픽셀 간격을 채우는 식으로, 점들이 뭉치지 않고 어떤 경우에도 최대한 흩어져서 퍼져 있게 한다. 임의의 격자 크기가 주어졌을 때 threshold matrix를 생성하는 프로그램을 만들 수도 있을 법해 보이는데 그리 만만한 일은 아닌 것 같다. 마방진도 아니고 말이다.

더 나아가 임의의 색을 16컬러 디더링 패턴으로 표현해 내는 프로그램을 직접 짜 보면 어떨까? 주어진 색을 가장 가깝게 표현할 수 있는 2색 또는 3색 조합을 구한 뒤, 그 비율만큼 threshold matrix를 각각의 색으로 채우면 될 것이다. 색조합을 구하는 것은 미지수의 개수가 식의 개수보다 더 많아서 답이 하나로 딱 떨어지지 않는 부등식이 될 터이니, LP(선형 계획법) 같은 계산 기법이 동원돼야 하지 않을까 싶다.

그렇게 threshold matrix만을 정석대로 적용하면 ordered dithering이 된다. 그러나 그것만으로는 그림이 칙칙하고 보기가 안 좋기 때문에, 디더링된 색깔의 픽셀이 인접 픽셀에 시각적으로 끼치는 영향을 감안하여(error diffusion) 더 정교하게 디더링을 수행하는 알고리즘이 실생활에서 쓰인다. 더 깊게 들어가는 건 이 글의 범위를 벗어나므로 자세한 설명을 생략하겠다.

뜬금없이 디더링 얘기를 꺼낸 이유는.. 저렇게 디더링 점을 찍어 나가는 게 마치 열차 좌석을 배당하는 것과 비슷한 심상이 느껴져서이다. 열차 좌석의 점유 여부를 흑백 픽셀로 표현하고 시간이 흐름에 따라 픽셀들의 상태를 표시하는 시뮬레이션을 돌려 보면 재미있을 것 같다. 한쪽은 검은 색이 듬성듬성 있고, 한쪽은 검은 색이나 흰 색이 좀 연속해서 있겠지 아마?

철도의 좌석 배당 알고리즘과 래스터 그래픽의 디더링 알고리즘은 서로 따로 생각하고 있었던 주제인데 이렇게 한 글로 연결이 됐다. 마치 예전에 내가 열차의 급행 등급과 셸 정렬을 한데 묶어서 글을 썼듯이 말이다. 참 신기한 일이 아닐 수 없다. ㅋㅋㅋㅋ

Posted by 사무엘

2013/04/08 08:18 2013/04/08 08:18
, , , ,
Response
No Trackback , 4 Comments
RSS :
http://moogi.new21.org/tc/rss/response/815


블로그 이미지

그런즉 이제 애호박, 단호박, 늙은호박 이 셋은 항상 있으나, 그 중에 제일은 늙은호박이니라.

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2013/04   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        

Site Stats

Total hits:
3940088
Today:
756
Yesterday:
2118