第5回:pushMatrix()とpopMatrix()、3Dのアニメーション

pushMatrix()とpopMatrix()は座標移動の際(rotateやtranslateなど)に組み合わせて使用されます。普通translateやrotateなどで座標を変換すると、それ以降に描かれる図形すべてにその変換が適用されます。繰り返し移動をしていくとその変換はどんどん蓄積されていくわけです。

それに対して、pushMatrix()命令を用いたあとに座標を変換し図形を描いた後にpopMatrix()命令をすると、pushMatrix命令をした際の座標に復元されます。つまり座標変換が蓄積されていきません。

より厳密にpushMatrix()とpopMatrix()を定義すると、「pushMatrix() 機能は、今の座標をスタックに保存して、popMatrix()は前の座標を復元する」と捉えることができます。

pushMatrix()とpopMatrix()を使用した移動と、そうでない移動を比較

pushMatrix()とpopMatrix()無しの場合

float angle1 = radians(30);
float angle2 = radians(60);

void setup() {
  size(200,200);
  framerate(30);
}

void draw() {
  background(0);
  stroke(255);
  translate(width/2,height/2);
  rotate(angle1);
  line(0,0,0,-width/2);
  rotate(angle2);
  line(0,0,0,-width/2);
  angle1 +=  radians(1);
  angle2 +=  radians(1);
}

pushMatrix()とpopMatrix()有りの場合

float angle1 = radians(30);
float angle2 = radians(60);

void setup() {
  size(200,200);
  framerate(30);
}

void draw() {
  background(0);
  stroke(255);
  translate(width/2,height/2);
  pushMatrix();
  rotate(angle1);
  line(0,0,0,-width/2);
  popMatrix();
  rotate(angle2);
  line(0,0,0,-width/2);
  angle1 +=  radians(1);
  angle2 +=  radians(1);
}

移動を反復する

pushMatrix()とpopMatrix()無しの場合

float angle1 = radians(30);
float angle2 = radians(60);
float offset = radians(10);
int i;

void setup() {
  size(200,200);
  framerate(30);
}

void draw() {
  background(0);
  stroke(255);
  translate(width/2,height/2);
  for(i=0; i<36; i++){
    rotate(angle1+offset*i);
    line(0,0,0,-width*0.4);
  }
  angle1 += radians(0.1);
}

pushMatrix()とpopMatrix()有りの場合

float angle1 = radians(30);
float angle2 = radians(60);
float offset = radians(10);
int i;

void setup() {
  size(200,200);
  framerate(30);
}

void draw() {
  background(0);
  stroke(255);
  translate(width/2,height/2);
  for(i=0; i<36; i++){
    pushMatrix();
    rotate(angle1+offset*i);
    line(0,0,0,-width*0.4);
    popMatrix();
  }
  angle1 += radians(0.5);
}

3D座標をpushMatrix()&popMatrix()

float a;                          
float offset = PI/24;             
int num = 12;
                  
void setup() 
{ 
  size(320, 240, P3D);
  noStroke();  
  framerate(30);
  fill(128,128,255,64);
  lights();
} 

void draw() 
{     
  background(0, 0, 26);
  translate(width/2, height/2, -20);
  a+=0.01;
  if(a >= TWO_PI*2) { 
    a = 0.0; 
  }    
  for(int i=0; i<num; i++) {
    pushMatrix();
    rotateY(a*3+offset*i);
    rotateX(a*2+offset*i);
    translate(0,20);
    box(width/3);
    popMatrix();
  }
}

3D座標をposh()&popMatrix() + カラーグラデーション

float a; 
float offset = PI/24;
int num = 12;
color[] colors = new color[num];
color safecolor;

void setup() 
{ 
  size(320, 240, P3D);
  noStroke();  
  framerate(30);
  for(int i=0; i<num; i++) {
    colors[i] = color(255 * (i+1)/num, 255 * (num-i)/num, 128);
  }
  lights();
} 

void draw() 
{     
  background(0, 0, 26);

  translate(width/2, height/2, -20);
  a+=0.04;
  if(a >= TWO_PI*2) { 
    a = 0.0; 
  }    
  for(int i=0; i<num; i++) {
    pushMatrix();
    fill(colors[i]);
    rotateY(a+offset*i);
    rotateX(a/2+offset*i);
    rotateZ(a+offset*i);
    box(width/3);
    popMatrix();
  }
}

3D座標をposh()&popMatrix():応用

float angle1 = radians(30);
float offset = radians(8);
int i, j, num = 20;
color[][] colors = new color[num+1][num+1];

void setup() {
  size(480,480,P3D);
  framerate(30);
  noStroke();
  lights();
  for(int i=0; i<num+1; i++) { 
    for(int j=0; j<num+1; j++) { 
      colors[i][j] = color(255 * (i+1)/num, 128, 255 * (j+1)/num, 200); 
    } 
  }
}
void draw() {
  background(0);

  for(i=0; i<num+1; i++){
    for(j=0; j<num+1; j++){
      pushMatrix();
      translate(width/num*i,height/num*j,0);
      fill(colors[i][j]);   
      rotateX(angle1*0.5+offset*i);
      rotateY(angle1*0.7+offset*i);
      rect(0,0,(width/num)*0.8,(height/num)*0.8);
      popMatrix();
    }
  }
  angle1 += radians(1);
}

Comments

コメントはありません

Add Comment

このアイテムは閉鎖されました。このアイテムへのコメントの追加、投票はできません。

トップページに戻る