본문으로 바로가기

오랜만에 Processing을 다시 만나[바로가기] 약간 즐거웠나 봅니다. 오늘은 살짝 제가 헤매던 pushMatrix()popMatrix()의 개념을 이해하는 것이 주 목적입니다. 그 도구로 modelX, modelY, modelZ 명령을 사용할 거구요. 그리고 뭐 자연스럽게 translate()rotateX() 이야기도 하게 될 듯 합니다.^^ 일단

void setup() {
  size(500, 500, P3D);
  noFill();
}

void draw() {
  background(0);
  
  float x = modelX(0, 0, 0);
  float y = modelY(0, 0, 0);
  float z = modelZ(0, 0, 0);
  
  println("x : " + x + ", y : " + y + ", z : " + z);
}

위 코드를 한 번 보죠~ 그냥 아무것도 없이 modelX, modelY, modelZ 명령으로 받은 값을 console 화면에 뿌리도록 했습니다. 이 modelX/Y/Z 명령은 좌표 원점(0,0,0)에서 여러 변환(translate, rotate)으로 옮겨진 원점의 절대좌표를 알려줍니다. 그러면 위 코드의 결과는 당연하지만...

(0,0,0)일 겁니다.^^

void setup() {
  size(500, 500, P3D);
  noFill();
}

void draw() {
  background(0);
  
  translate(50, 100, 50);
  
  float x = modelX(0, 0, 0);
  float y = modelY(0, 0, 0);
  float z = modelZ(0, 0, 0);
  
  println("x : " + x + ", y : " + y + ", z : " + z);
}

이제 첫 코드에서 translate(50,100,50)을 넣었습니다. 그러면 translate은 좌표 원점의 단순 평행이동이므로 

위와 같이 translate된 결과인 (50,100,50)이 그대로 나타나게 될 것입니다.

void setup() {
  size(500, 500, P3D);
  noFill();
}

void draw() {
  background(0);
  
  translate(50, 100, 50);
  rotateX(PI);
  translate(1, 2, 3);
  
  float x = modelX(0, 0, 0);
  float y = modelY(0, 0, 0);
  float z = modelZ(0, 0, 0);
  
  println("x : " + x + ", y : " + y + ", z : " + z);
}

이제 위 코드를 보면 X축 중심의 회전인 rotateX를 180도(PI)만큼 수행하였습니다. 그러면 x축 방향만 그대로이고, y, z축은 방향이 반대가 되기 때문에 그 후 translate 명령으로 (1,2,3)만큼 이동하라는 명령을 원점의 절대 좌표에서 보면,

x축은 1더해서 51만큼 가지만, 나머지는 2, 3만큼 빼야합니다. 권총을 쏘는 동작으로 x,y,z축을 손으로 만들고 상상해 보면 됩니다.^^. 여기서 또 하나 알게 된것은 한 iteration의 draw()함수 안에서는 translate과 rotate는 누적이라는 것입니다. 그러므로

void setup() {
  size(500, 500, P3D);
  noFill();
}

void draw() {
  background(0);
  
  translate(50, 100, 50);
  rotateX(PI);
  translate(1, 2, 3);
  
  translate(10,10,10);
  
  float x = modelX(0, 0, 0);
  float y = modelY(0, 0, 0);
  float z = modelZ(0, 0, 0);
  
  println("x : " + x + ", y : " + y + ", z : " + z);
}

위 코드처럼 translate(10,10,10)을 추가하면 앞선 변환 후에 누적으로 더 해지게 됩니다.

위 결과처럼 말이죠^^ 그런데 만약 어느 순간 각 종 변환이 너무 많아져 쉽지 않은 상황이거나 혹은, 다양한 도형을 각 각 따로 좌표 원점에서 계산해야 한다면 난감하겠죠... 그 때 사용하는 것이 pushMatrix()popMatrix()입니다.

void setup() {
  size(500, 500, P3D);
  noFill();
}

void draw() {
  background(0);
  
  pushMatrix();
    translate(50, 100, 50);
    rotateX(PI);
    translate(1, 2, 3);
  popMatrix();
  
  translate(10,10,10);
  
  float x = modelX(0, 0, 0);
  float y = modelY(0, 0, 0);
  float z = modelZ(0, 0, 0);
  
  println("x : " + x + ", y : " + y + ", z : " + z);
}

저렇게 마지막 translate를 뺴고 나머지를 pushMatrix()popMatrix()로 둘러싸면 이 후 변환은 다시 좌표 원점에서 시작되는 것입니다.

위 결과 처럼 말이죠~~~^^ 즉 popMatrix()를 만나면 pushMatrix()에서 시작된 변환(translate, rotate)는 모두 clear되는 것입니다^^

신고