仕事で,JavaScriptで画像処理を行う機会があったのですが, その中で,setTransform関数で画像の回転を扱いました. それに関してなかなか明快な説明をしているサイトが探せなかったので, この関数について,説明してみようと思います. 取りあえずは,こちらの 画像回転のデモ をご覧ください.
HTMLにおいては,座標は左から右にx軸があり,上から下にy軸があります. つまり,左手系なのです.(図1参照)
さて,setTransform関数は次のような引数を取ります.
setTransform(a,b,c,d,e,f);
このa〜fは行列の成分を意味します. 以下の様な行列です.
つまり,アフィン変換です. ここで,canvas上の座標 を で変換した後の座標を とすると,
となります.
ここで,能動的回転を考えましょう. だけ反時計回りに回転するとき,
となります. この際,左手系であることが混乱を招きます.
しかし,高校数学の複素数平面をご存知の方は,こう考えるといいでしょう. 計算の世界では普通の複素数平面で, の回転は反時計回りの回転を考えます. 回転後に,canvasの世界に合わせる為,x軸で折り返して,左手系にするのです.(図2参照)
だから,式 は複素数平面の世界では反時計回りで, canvasの世界になった時,時計回りの回転を表します.
なお, に関しては,canvasの原点 を中心に で回転した後, 原点自体が へ並進すると考えればよいでしょう.
若しくは, を中心に の回転を行ったのだ. と考えても良いです.
さて,以上を踏まえて,最初のデモファイルでは画像クラスの中で,
ctx.setTransform(Math.cos(rad),Math.sin(rad),-Math.sin(rad),Math.cos(rad),e,f);
ctx.drawImage(img, -img.width/2, -img.height/2);
という順番でコマンドを書いています. これはつまり,setTransformで画像を書き込む前に座標系を を原点にし, その原点中心として時計回りに 回転させた座標系に取り直します.
次のdrawImage(img,width,height)ですが,これは本来,座標点 を左上の隅として,そこから右下領域に画像を書き込むコマンドです.setTransformで原点は になって,x,y基底ベクトルも 回転していますから, 長方形の画像の横幅 img.width ,縦幅 img.height として,drawImage(img, -img.width/2, -img.height/2) とすることで, に画像の中心をおき, の回転を行った画像が張られます.つまり,これを一定時間間隔でangleを変えながら表示することで,画像を中心を原点として時計回りに回転し続けるプログラムになっています.
今日はここまで,お疲れさまでした!