読者です 読者をやめる 読者になる 読者になる

ひっきぃのメモ帳

趣味で作るプラモデル製作の過程と作品、日々の資格取得へ向けての活動、Apple中心のIT関連ネタを書いています。

enchant.js を使って変形した画像をスプライトに描画する

enchant.js を使ったプログラミングを引き続き研究中です。


画像の変形ができるかどうか調査しました。
enchant.jsのスプライト機能では、回転ぐらいはできますが、変形は出来るようになっていないようです。
自由に作図が出来るサーフェス機能を使ってアフィン変換を用いた画像の変形を実装してみました。


完成したサンプルはこちら。

アフィン変換した画像をスプライトにのせるテスト(4分割) - jsdo.it - share JavaScript, HTML5 and CSS


プログラムの構造
詳しくはソースコードを見てもらうとして、以下のような感じのプログラムです。

  • 画面サイズと同サイズのスプライト生成して、同サイズのサーフェスをイメージにセット
  • ゲームのルートシーンにスプライトを配置
  • 表示する画像を三角形4つに分割して、サーフェスにアフィン変換した画像を描画
  • 5カ所のハンドル毎にイベント処理で画像を更新
  • フレームイベント毎に画像を更新

アフィン変換の理論
メモしておかないと、あとで忘れそうなので。
プログラムのコメント代わりに、自分用のメモ。


高校数学が分かる人向け。

a,b を アフィン変換して A,B に移動すると考える。
アフィン変換の行列次のように決める。
\begin{pmatrix}m_{11} && m_{12} \\ m_{21} && m_{22} \end{pmatrix}

それぞれの座標はアフィン変換で以下のように移動することになる。
\begin{pmatrix} m_{11} && m_{12} \\ m_{21} && m_{22} \end{pmatrix}\begin{pmatrix} a_x\\ a_y \end{pmatrix} = \begin{pmatrix} A_x\\ A_y \end{pmatrix}
\begin{pmatrix}m_{11} && m_{12} \\ m_{21} && m_{22} \end{pmatrix}\begin{pmatrix} b_x\\ b_y \end{pmatrix} = \begin{pmatrix} B_x\\ B_y \end{pmatrix}

これを、合わせて2×2行列の積の形にすると、

\begin{pmatrix}m_{11} && m_{12} \\ m_{21} && m_{22} \end{pmatrix}\begin{pmatrix} a_x && b_x\\ a_y && b_y \end{pmatrix} = \begin{pmatrix} A_x && B_x \\ A_y &&  B_y \end{pmatrix}

アフィン行列のパラメータを求めるために、両辺に右からa,bを合わせた行列の逆行列を掛ける。
\begin{pmatrix}m_{11} && m_{12} \\ m_{21} && m_{22} \end{pmatrix} = \begin{pmatrix} A_x && B_x \\ A_y &&  B_y \end{pmatrix} \begin{pmatrix} a_x && b_x\\ a_y && b_y \end{pmatrix}^{-1}
これが、求めるアフィン変換行列のパラメータになる。
ただし、平行移動の事を考えていない。

実際には、p1を軸にして変形した形なので、p1'の位置へ平行移動すると求めたい位置に表示することができる。


また、アフィン変換では元の画像を平行四辺形(図の点線部分)に変形することしかできないので、三角形の部分だけを描画するためにクリップ領域を設定する。


上の三角形と左の三角形はp1を原点とするので、平行移動の量は直接 p1'の座標にする。


下の三角形と右の三角形はp4を原点とするので、平行移動の量の計算がちょっと面倒だった。
(もっと良い方法があるのかもしれない。)

右下を原点したベクトルを考えて、赤矢印の変形を同様に行う。
実際には画像の左上を軸に変形した形になる。
平行移動するべき量は、矩形画像の左上の点が移動する量(p1→p4'')。
紫のベクトルを加算すると、移動すべき平行移動の量を求める事ができる。

p4''が求める平行移動する量。
p5からp4''のベクトルは、p4'からp5のベクトルと同じであるからp1が移動元の座標として、
p5+(p5-p4')
が平行移動する座標の位置となる。


数式ははてなtex機能を使いました。
卒論以来だな。なつかしい。