1. ホーム
  2. Processingの使い方
  3. 図形の移動、回転、反転2

記事「図形の移動、回転、反転」では、図形を移動させたり、回転させたり、反転させたりする方法についてまとめました。その際、図形自体を動かすのではなく、座標系ごと動かすことで移動、回転、反転を実現させました。

ただ、図形自体を動かせないのは結構不便なことだと思います。

実は、記事「任意の図形を描く」や「ベジエ曲線を描く」で紹介した方法で描いた図形はそれ自体を動かすことができます。ここでは、その方法について紹介していきます。

PShape型の変数に格納した図形の移動、回転、反転

描いた図形をPShape型の変数に格納する

まず描画キャンパスの中央に、記事「任意の図形を描く」で紹介した方法で正三角形を描いてみます。その際、PShape型の変数を用意し、その中に正三角形の情報を格納します。このプログラムコードは以下のようになります。

void setup(){
  size(500,500); // 描画キャンパスを準備
  translate(width/2.0, height/2.0); // 座標原点をキャンバス中央に移動
  noFill(); // 図形の中身は無色
  
  PShape tri = createShape(); // PShape型の変数を準備
  // 正三角形をPShape型の変数に格納する
  tri.beginShape();
  tri.vertex(100.0*cos(radians(-90.0)), 100.0*sin(radians(-90.0)));
  tri.vertex(100.0*cos(radians(30.0)), 100.0*sin(radians(30.0)));
  tri.vertex(100.0*cos(radians(150.0)), 100.0*sin(radians(150.0)));
  tri.endShape(CLOSE);

  // PShape型の変数に格納した図形を描画
  shape(tri);
}

ポイントは、PShape型の変数を用意して、

PShape tri = createShape();

とした後、記事「任意の図形を描く」で紹介した方法で正三角形を描いていくわけですが、その際、

  tri.beginShape();
  tri.vertex(100.0*cos(radians(-90.0)), 100.0*sin(radians(-90.0)));
  tri.vertex(100.0*cos(radians(30.0)), 100.0*sin(radians(30.0)));
  tri.vertex(100.0*cos(radians(150.0)), 100.0*sin(radians(150.0)));
  tri.endShape(CLOSE);

のように、頭に「tri.」を付けるところです。そして、PShape型の変数に格納した図形はshape関数でキャンパス上に描くことができます。

shape(tri);

このプログラムコードを実行させてみると、以下のような図形が描かれます。

正三角形を描く

図形を移動する

では、図形を移動させてみます。移動はtranslate関数を用いて実行することができますが、今回はPShape型の変数に格納した正三角形の図形のみを移動させますので、

tri.translate(width/4.0, height/4.0);

のように、頭に「tri.」を付けます。そのプログラムコードは以下です。

void setup(){
  size(500,500); // 描画キャンパスを準備
  translate(width/2.0, height/2.0); // 座標原点をキャンバス中央に移動
  noFill(); // 図形の中身は無色
  
  PShape tri = createShape(); // PShape型の変数を準備
  // 正三角形をPShape型の変数に格納する
  tri.beginShape();
  tri.vertex(100.0*cos(radians(-90.0)), 100.0*sin(radians(-90.0)));
  tri.vertex(100.0*cos(radians(30.0)), 100.0*sin(radians(30.0)));
  tri.vertex(100.0*cos(radians(150.0)), 100.0*sin(radians(150.0)));
  tri.endShape(CLOSE);

  // PShape型の変数に格納した図形を描画
  shape(tri);

  // PShape型の変数に格納した図形を移動
  tri.translate(width/4.0, height/4.0);
  tri.setStroke(color(255,0,0));
  shape(tri);
}

このプログラムコードを実行させてみると、以下のような図形が描かれます。

中央の正三角形(黒色)を右下(赤色)に移動

確かに、正三角形が移動しました。

図形を回転させる

次に、図形を回転させてみます。回転はrotate関数を用いて実行することができますが、今回はPShape型の変数に格納した正三角形の図形のみを回転させますので、

tri.rotate(radians(10.0));

のように、頭に「tri.」を付けます。そのプログラムコードは以下です。

void setup(){
  size(500,500); // 描画キャンパスを準備
  translate(width/2.0, height/2.0); // 座標原点をキャンバス中央に移動
  noFill(); // 図形の中身は無色
  
  PShape tri = createShape(); // PShape型の変数を準備
  // 正三角形をPShape型の変数に格納する
  tri.beginShape();
  tri.vertex(100.0*cos(radians(-90.0)), 100.0*sin(radians(-90.0)));
  tri.vertex(100.0*cos(radians(30.0)), 100.0*sin(radians(30.0)));
  tri.vertex(100.0*cos(radians(150.0)), 100.0*sin(radians(150.0)));
  tri.endShape(CLOSE);

  // PShape型の変数に格納した図形を描画
  shape(tri);
    
  // PShape型の変数に格納した図形を回転
  tri.rotate(radians(10.0));
  tri.setStroke(color(255,0,0));
  shape(tri);
}

このプログラムコードを実行させてみると、以下のような図形が描かれます。確かに、正三角形が回転しています。

正三角形を時計回りに10度回転

図形を反転させる

最後に、図形を反転させてみます。反転はscale関数を用いて実行することができますが、今回はPShape型の変数に格納した正三角形の図形のみを反転させますので、

tri.scale(1,-1);

のように、頭に「tri.」を付けます。そのプログラムコードは以下です。

void setup(){
  size(500,500); // 描画キャンパスを準備
  translate(width/2.0, height/2.0); // 座標原点をキャンバス中央に移動
  noFill(); // 図形の中身は無色
  
  PShape tri = createShape(); // PShape型の変数を準備
  // 正三角形をPShape型の変数に格納する
  tri.beginShape();
  tri.vertex(100.0*cos(radians(-90.0)), 100.0*sin(radians(-90.0)));
  tri.vertex(100.0*cos(radians(30.0)), 100.0*sin(radians(30.0)));
  tri.vertex(100.0*cos(radians(150.0)), 100.0*sin(radians(150.0)));
  tri.endShape(CLOSE);

  // PShape型の変数に格納した図形を描画
  shape(tri);
  
  // PShape型の変数に格納した図形を反転  
  tri.scale(1,-1);
  tri.setStroke(color(255,0,0));
  shape(tri);

}

このプログラムコードを実行させてみると、以下のような図形が描かれます。確かに、正三角形が上下反転しています。

正三角形を上下反転

補足

PShape型の変数に格納した図形の移動、回転、反転をリセットする

例えば、上記の正三角形をキャンパスの中央から右下に移動したものと中央から右上に移動したものを描きたいとします。このとき、プログラムを次のように書いてみます。

void setup(){
  size(500,500); // 描画キャンパスを準備
  translate(width/2.0, height/2.0); // 座標原点をキャンバス中央に移動
  noFill(); // 図形の中身は無色
  
  PShape tri = createShape(); // PShape型の変数を準備
  // 正三角形をPShape型の変数に格納する
  tri.beginShape();
  tri.vertex(100.0*cos(radians(-90.0)), 100.0*sin(radians(-90.0)));
  tri.vertex(100.0*cos(radians(30.0)), 100.0*sin(radians(30.0)));
  tri.vertex(100.0*cos(radians(150.0)), 100.0*sin(radians(150.0)));
  tri.endShape(CLOSE);

  // PShape型の変数に格納した図形を描画
  shape(tri);

  // PShape型の変数に格納した図形を右下に移動
  tri.translate(width/4.0, height/4.0);
  tri.setStroke(color(255,0,0));
  shape(tri);

  // PShape型の変数に格納した図形を右上に移動
  tri.translate(width/4.0, -height/4.0);
  tri.setStroke(color(0,0,255));
  shape(tri);  

}

このプログラムを実行すると、以下のような図形が得られます。

今回は、中央の正三角形(黒色)の右上に青色の正三角形が描かれてほしかったのですが、右下に移動した正三角形(赤色)の右上に描かれています。これは、PShape型の変数に格納した図形を移動、回転、反転すると、PShape型の変数にはその情報が格納されてしまうことが原因です。

これを解消するためには、resetMatrix関数を用います。

tri.resetMatrix();

今度は、正三角形を右下へ移動して描画した後、右上の移動を行う前にこのresetMatrix関数を呼び出してみます。

void setup(){
  size(500,500); // 描画キャンパスを準備
  translate(width/2.0, height/2.0); // 座標原点をキャンバス中央に移動
  noFill(); // 図形の中身は無色
  
  PShape tri = createShape(); // PShape型の変数を準備
  // 正三角形をPShape型の変数に格納する
  tri.beginShape();
  tri.vertex(100.0*cos(radians(-90.0)), 100.0*sin(radians(-90.0)));
  tri.vertex(100.0*cos(radians(30.0)), 100.0*sin(radians(30.0)));
  tri.vertex(100.0*cos(radians(150.0)), 100.0*sin(radians(150.0)));
  tri.endShape(CLOSE);

  // PShape型の変数に格納した図形を描画
  shape(tri);

  // PShape型の変数に格納した図形を右下に移動
  tri.translate(width/4.0, height/4.0);
  tri.setStroke(color(255,0,0));
  shape(tri);

  // PShape型の変数に格納した図形に行なった移動をリセット
  tri.resetMatrix();

  // PShape型の変数に格納した図形を右上に移動
  tri.translate(width/4.0, -height/4.0);
  tri.setStroke(color(0,0,255));
  shape(tri);  

}

今度は、中央の正三角形(黒色)の右上に青色の正三角形が描かれています。

PShape型の変数に格納した図形の色を変更する

なお、図形の色を変更するためには、stroke関数やfill関数を図形を描画する前に設定する必要がありました。ただ、PShape型の変数に格納した図形の色は、その図形を描画する関数shape関数の前にstroke関数などを呼び出しても色は変更されません。PShape型の変数に格納した図形の色を変更するためには、以下のように、setStroke関数を呼び出す必要があります。

tri.setStroke(color(255,0,0));