Processing으로 그림 그리기

사실 필자는 예술과는 거리가 먼 삶을 살아왔다. 초등학교 때부터 프로그래머가 되겠다는 꿈을 안고 초등학교 때는 소설책과 수학, 중학교 때는 컴퓨터와 블로그 (이때 관리하던 블로그는 현재 이 글이 게시된 블로그와는 다른 블로그다. IT 뉴스와 iOS 탈옥, 안드로이드 루팅 관련 글이 주를 이루었다.), 고등학교 때는 수능에 거의 대부분의 시간을 쏟아부었다. 가까운 친구나 가족, 친척 중에서도 예술 관련 일을 하거나 관심을 두고 있는 사람도 없었기에 어쩌면 당연한 결과일지도 모른다.

하지만 초등학교 때부터 WWDC 생중계를 챙겨보고 스티브 잡스 자서전을 몇 번씩 반복해서 읽어오면서 Apple이라는 회사의 제품, 철학, 가치에 깊이 매료되었던 탓인지, 필자의 가슴 한구석에는 "아름다움"에 대한 관심이 꾸준히 자리를 차지해 왔던 것 같다. 그러한 필자의 관심이 컴퓨터 프로그래밍을 만나 구현된 것이 바로 Processing[1]을 이용한 Computer Art이다.

유감스럽게도 필자의 예술적 감각이 대단히 부족한 탓에 Processing을 어느 정도 사용할 수 있게 된 후에도 여전히 만족할 만한 작업물을 만들어내기는 어려웠다. 그러던 와중 예술적 감각보다는 수학에 가까운 방법을 이용하여 멋있는 작업물을 만들 수 있다는 것을 알게 되었는데, 그것이 바로 매개변수로 표현된 함수를 이용하는 것이다.


  1. 프로세싱(Processing)은 프로그래머가 아닌 사람들에게 교육할 목적으로 뉴 미디어 아트, 시각 디자인 공동체를 위해 개발된 오픈 소스 프로그래밍 언어이자 통합 개발 환경(IDE)이다. 2001년 MIT 미디어 연구소에서 케이시 리아스와 벤자민 프라이가 시작하였으며, General Purpose Language가 아니라 Domain Specific Language로 분류된다. ↩︎

void setup() {
  background(100);
  size(500,500);
}

float t = 0;

void draw() {
  background(100);
  strokeWeight(30);
  point(x_(t),y_(t));
  t++;
}

float x_ (float t) {
  return t;
}

float y_ (float t) {
  return t;
}

위와 같이 코드를 작성하고 실행해보면 $y = x$를 따라서 공이 움직인다.

직선을 표현하고 싶다면 점의 크기를 조금 줄이고 draw() 함수에서 background 부분을 주석 처리하면 된다.

void setup() {
  background(100);
  size(500,500);
}

float t = 0;

void draw() {
  background(100);
  translate(width/2,height/2);  // (0,0)을 중앙으로 이동
  strokeWeight(10);
  point(x_(t),y_(t));
  t++;
}

float x_ (float t) {
  return 200*cos(2*t);
}

float y_ (float t) {
  return 200*sin(2*t);
}

매개변수로 나타내는 함수 중 가장 쉽게 떠올릴 수 있는 것이 바로 원이다. 위 코드가 그것을 구현한 것이다.

위 코드는 $x=200\cos(2t)$, $y=200\cos(2t)$로 나타낸 함수와 같다.

컴퓨터로 그림을 그리는 것의 장점은 여러 가지가 있겠으나, 그중 가장 큰 것은 "동적인 결과물"을 만들기에 유리하다는 것이다. $\cos$과 $\sin$ 함수는 주기함수이므로, 반복되는 주기를 가지는 동적인 결과물을 만들기 적합하다.

$\cos$과 $\sin$ 함수를 이용하여, 필자가 만들어낸 최종 결과물은 다음과 같다.

void setup() {
  background(0,0,97);
  size(500,500);
  colorMode(HSB, 100, 100, 100); // 색 방식을 RGB(기본)에서 HSB방식으로 변경하였다.
}

float t = 0;

void draw() {
  //t가 변화함에 따라 H와 S값도 주기적으로 변한다.
  float H = 100*cos(t/80); 
  float S = 90 + 10*sin(t/80);
  float B = 10;
  
  background(255);
  stroke(250);
  strokeWeight(2.2);
  translate(width/2,height/2);  //중심으로 이동
  for(int i = 0; i<10; i++) {
    stroke(H, S-i*(100/10), B+i*((100-10)/10)); 
    //앞서 정한 HSB값을 기반으로 선 하나하나의 색을 달리한다.

    line(x_1(t+3*i),y_1(t+3*i),x_2(t+3*i),y_2(t+3*i)); //선 생성
  }
  t++;
  //saveFrame("tt,####.png"); 
  // 매 프레임을 png파일로 저장하는 코드. 그냥 실행할 때는 필요없으므로 주석처리 하였다.
}

float x_1 (float t) {
  return cos(t/13.5)*110 + sin(t/19.5)*110;
}

float y_1 (float t) {
  return -cos(t/22.5)*110;
}

float x_2 (float t) {
  return cos(t/18)*110 + sin(t/22.5)*110;
}

float y_2 (float t) {
  return cos(t/22.5)*110;
}

처음에는 단색이었는데, 서서히 색이 변하면 훨씬 멋있을 것 같아서 마지막 단계에서 추가했다. 결과적으로 아주 좋은 아이디어였던 것 같다. 코드에 포함된 다양한 상수값들은 대부분 큰 의미는 없다. 필자 마음대로 이리저리해보면서 임의로 설정한 것이다. 그 외 코드에 대해서는 주석을 달아두었다.

Prcessing을 Javascript로 포팅한 Processing.js라는 Javascript Plugin도 존재한다. 이것을 이용하여 웹페이지에 완성된 결과물을 삽입할 수 있는데, 사용하는 브라우저가 Javascript를 지원한다면 아래에 완성된 결과물을 확인할 수 있을 것이다.