画像を回転するには

◆PROCESSING 逆引きリファレンス

 カテゴリー:動画・アニメーション

画像を回転するには

【解説】

ゲームでは良くありますが、図形を回転させたい場合があります。PROCESSINGには図形を回転させる便利な命令があります。

回転は rotate() 命令で行います。指定した角度(ラジアン)だけ時計回りに回転します。回転の中心は必ず起点座標となります。

度からラジアンへの変更は radians() 命令で行えます。また起点座標の初期値は、実行結果ウィンドウの左上隅になります。

起点座標を変更するには translate() 命令を利用します。指定した座標が新たな回転の中心(起点座標)になります。

現在の座標系を記憶しておくには pushMatrix() 命令を、記憶しておいた座標系を元に戻すにはpopMatrix()  命令を利用します。

【構文】

●translate() 命令
void  translate( float  x, float  y );
void  translate( float  x, float  y, float  z );

●radians() 命令
float  ra  =   radians(  float  degrees );

●pushMatrix() 命令
void   pushMatrix() ;

●popMatrix()  命令
void  popMatrix() ;

【パラメータ】

x :起点とする横座標
y :起点とする縦座標
z :起点とする奥行き座標

zは size() 命令で 3D 座標系が指示されている場合に利用可能です。

degrees:ラジアンに変換する角度を指定
ra             :変換されたラジアン値

【注意】

●全般的な予備知識

PROCESSINGの座標系(2D)は、初期状態で以下のようになっています。

2D初期座標初期状態では、描画する起点は実行結果ウィンドウの左上隅と一致しています。縦がY方向、横がX方向です。縦(Y)は起点から下に行くほど、横(X)は起点から右に行くほど、値が大きく(正に)なります。

 

●rotate() 命令について

回転する中心座標は、必ず起点になります。起点の初期位置は画面左上隅の (0, 0)です。

回転時の起点(画像URL:illust-AC 様:acworks さん)

回転する中心座標を変更したい場合は、後述するtranslate() 命令で起点を変更する必要があります。

回転時の起点2(画像URL:illust-AC 様:acworks さん)

rotate() 命令は、現在表示中の画像を回転させるのではなく、rotate() 命令が発行された後に描画する画像を回転させます。

rotate() 命令に与える角度は「度」ではなく「ラジアン」です。ラジアンとは半径と同じ長さの円弧が作る角度の事です。(参考記事:sci-pursuit.com 様

ラジアン
ラジアンは上図の通りですので、360度=2πラジアン、180度=πラジアン、90度=1/2πラジアンになります。

素直に「度」を使ってくれれば良いのですが・・・なぜか多くのプログラミング言語では角度を扱う命令にラジアンを使います(泣)。

角度からラジアンへの変換を行うには、radians() 命令を使うと便利です。

またrotate() 命令の回転方向は「時計回り」になります。私達が学校で習う数学では、反時計回りの角度を使うことが多いと思いますので注意してください。

1/4πラジアン(45度)回転させるように指示すると、時計回りに45度回転します。反時計回りに回転させたい場合は負の値(-1/4πなど)を与える事になります。

回転方向(画像URL:illust-AC 様:acworks さん)

rotate() 命令の回転角度は、再度rotate() 命令を発行するか、draw()関数の描画処理ループが再度実行されるまで有効です。

rotate( radians(10) );
rotate( radians(10) );
とした場合、
rotate( radians(20) );
と命令したことと同じになります。

draw()関数は描画処理ループを回すごとに、回転角度を「回転無し」に初期化します。

回転角度初期化(画像URL:illust-AC 様:うーさん)

 

●translate() 命令について

translate() 命令は「起点」を変更する命令です。起点の初期値は (0, 0) 、つまり画面の左上隅になっています。これを任意の位置に変更するのが translate() 命令です。

初期起点(画像URL:illust-AC 様:acworks さん)

画像表示命令(image() やrect() など)に与える座標は、すべて起点からの相対座標になります。また、translate()命令に与える座標も、つねに起点からの相対座標です。

例えば ( 4,4 ) の地点をtranslate() 命令で新たな起点に変更すると、以下のようになります。

起点移動(画像URL:illust-AC 様:acworks さん)

上記例で、初期状態と同じ位置(画面左上隅から(4,4)の位置)に画像を表示したい場合は、 image()命令に与える座標を ( 4, 4 )ではなく ( 0, 0 ) にしなければいけません。

translate() 命令で移動した起点は、再度translate() 命令を発行するか、draw()関数の描画処理ループが再度実行されるまで有効です。

translate( 2, 2 );
translate( 2, 2 );
とした場合、
translate( 4, 4 );
と命令したことと同じになります。

ですので、translate() 命令で何度も起点を移動する際は、各translate() 命令に与える座標が、すべて直前のtranslate() 命令で移動した起点からの相対座標になる事に注意が必要です。

起点移動注意(画像URL:illust-AC 様:acworks さん、うーさん)

上図にあるように、最初に起点を(0,0)⇒(2,2)に移動したとします。次に起点を画面左上隅から見た(4,4)の位置に移動する場合は、(2,2)を指定する事になります。

draw()関数は描画処理ループを回すごとに、起点を画面左上隅に初期化します。

起点を初期化(画像URL:illust-AC 様:acworks さん)

 

●pushMatrix()命令、popMatrix()  命令について

translate() 命令で起点が移動するたびに、画像表示命令に与える座標を考えなければいけないのは面倒です。

なぜなら先にも説明したようにimage()命令などの描画系処理に与える座標は、起点からの相対座標になるからです。

このような時、pushMatrix()命令とpopMatrix()  命令を利用します。

pushMatrix()命令は命令発行時点の座標系を記憶する命令です。記憶した座標系を元に戻すには popMatrix()  命令を使用します。

例えば先ほど例示した複数回起点を移動する処理なら、pushMatrix()命令とpopMatrix()  命令を使うことで、常に画面左上隅を基準とした処理にすることが可能です。

起点移動注意2(画像URL:illust-AC 様:acworks さん、うーさん)

pushMatrix()命令は複数回利用可能です。pushMatrix()命令が発行される度に、その時の座標系をスタック状に記憶していきます。

ただし、pushMatrix()命令で記憶した座標は、同じ回数のpopMatrix()命令で取り出さなくてはいけません。pushMatrix()を3回実行したなら、popMatrix()も3回実行します。

特に draw() 関数内で使う場合は、pop回数とpush回数が異なるとエラーになるので注意してください。

【関連記事】

  • なし

サンプルプログラム

画面左上隅を中心に25°回転させる例:

Aで画面中央に飛行機の絵を描きます。その後 rotate() 命令で25度回転させた飛行機(B)を描きます。回転の中心は画面左上隅です。

<出力サンプル>

回転Sample(画像URL:illust-AC 様:acworks さん)

 

画像中央を中心に360°回転させる例:

上記を実行すると方位計が時計回りにグルグル回転します。

rotateImage() 関数は、任意の画像を好きな角度だけ回転しながら配置するための汎用的な関数です。

rotateImage() 関数の処理を図解すると下記のようになります(クリックすると拡大します)。

回転解説上記関数の主な処理は「アプリ開発と歴史の話 様」のページを参考とさせて頂きました。

<出力サンプル>

回転Sample2
(画像URL:illust-AC 様:nobunobu さん)

下記はサンプルプログラムをP5.jsで書き直したものです。動作イメージを確認できます。

 


PROCESSING逆引きリファレンス一覧 へ戻る

本ページで利用しているアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。