Upload
takeshi-arabiki
View
7.534
Download
5
Embed Size (px)
DESCRIPTION
SWF 研究会#2 の LT 資料です
Citation preview
HTML5 Canvas で学ぶアフィン変換
2012/09/25 SWF 研究会#2
@a_bicky
自己紹介• Takeshi Arabiki
‣ 社会人2年目の底辺 Web エンジニア
‣ Twitter & はてな: @a_bicky & id:a_bicky
• お仕事JSX や JavaScript でコードを書いたり
• 興味など機械学習、自然言語処理、R
• ブログあらびき日記 http://d.hatena.ne.jp/a_bicky/
アフィン変換とは?
こういう変換とか
※アニメーションです
こういう変換とか
※アニメーションです
アフィン変換
0
@x
0
y
0
1
1
A =
0
@a c t
x
b d t
y
0 0 1
1
A
0
@x
y
1
1
A
✓x
0
y
0
◆=
✓a c
b d
◆✓x
y
◆+
✓t
x
t
y
◆
ざっくりした意味 平行移動を伴う線形変換
線形変換 平行移動
同次座標系 1つの行列で線形変換と平行移動を表すために次元を1つ増やす
Canvas によるアフィン変換
var canvas = document.getElementById("canvas");var ctx = canvas.getContext("2d");ctx.transform(a, b, c, d, tx, ty);ctx.drawImage(img, 0, 0);
0
@x
0
y
0
1
1
A =
0
@a c t
x
b d t
y
0 0 1
1
A
0
@x
y
1
1
A
拡大・縮小
var canvas = document.getElementById("canvas");var ctx = canvas.getContext("2d");ctx.scale(sx, sy);ctx.drawImage(img, 0, 0);
ww0
sx
= w0/w
hh0
sy = h0/h
x
y
元の画像
0
@x
0
y
0
1
1
A =
0
@s
x
0 00 s
y
00 0 1
1
A
0
@x
y
1
1
A
=
0
@s
x
x
s
y
y
1
1
A
回転
var canvas = document.getElementById("canvas");var ctx = canvas.getContext("2d");ctx.rotate(theta);ctx.drawImage(img, 0, 0);
✓
0
@x0
y0
1
1
A=
0
@cos � � sin � 0
sin � cos � 0
0 0 1
1
A
0
@xy1
1
A
=
0
@x cos � � y sin �x sin � + y cos �
1
1
A
元の画像
x
y
平行移動
var canvas = document.getElementById("canvas");var ctx = canvas.getContext("2d");ctx.translate(tx, ty);ctx.drawImage(img, 0, 0);
x
y
tx
ty
0
@x
0
y
0
1
1
A =
0
@1 0 t
x
0 1 t
y
0 0 1
1
A
0
@x
y
1
1
A
=
0
@x+ t
x
y + t
y
1
1
A
元の画像
0
@x0
y0
1
1
A =
0
@1 tan⇥ 0
tan� 1 00 0 1
1
A
0
@xy1
1
A
=
0
@x+ y tan⇥x tan�+ y
1
1
A
剪断
var canvas = document.getElementById("canvas");var ctx = canvas.getContext("2d");ctx.transform(1, Math.tan(alpha), Math.tan(beta), 1 0, 0);ctx.drawImage(img, 0, 0);
x
y
↵
�
元の画像
デモアフィン変換 デモ
http://abicky.net/swf_study/2/
インタラクティブに変換してみたい人は是非お試しください!
時間がないのでやりません!
自作 Flash Player
あるある
特定のシェイプが表示されない><
画像を正しく
パースできて
ない?
変換行列がおかしい?
描画順序がおかしい?透過度の問題?
画像を正しく
パースできて
ない?
変換行列がおかしい?
描画順序がおかしい?透過度の問題?
Canvas では現在の変換行列を
取得できない... orz
作った!HTML5 の Canvas で getTransform が使えるようにしてみた - あらびき日記
http://d.hatena.ne.jp/a_bicky/20120724/1343084686
← ロードすると getTransform が使える
ここで問題
Canvas でx, y 軸方向に2倍する変換行列を適用してからx, y 軸方向に1移動する変換行列を適用すると
どうなるか?
1
1
1
1
2
2
1
1
正しいのはどっち?
1
1
1
1
2
2
1
1
正しいのはどっち?
○
正しいのはどっち?
○正しいのはどっち?
最初 getTransform は逆になってた><
1
1
1
1
1
2
簡単な解説1
1
スケールを2倍する スケールを2倍した座標系で1移動する(元の座標系では2移動することになる)
1
11
2元の座標系での値 スケール2倍の座標系での値
まず1移動する
スケールを2倍する(移動した上での2倍なので移動量も2倍になる)
まとめ
まとめ• アフィン変換は平行移動伴う線形変換
• Canvas で変換行列の状態を取得する getTransform を作った
• 複数の変換行列を適用する場合は最初に適用するものが最左にくる
参考• アフィン変換とは - 大人になってからの再学習
• にゃあプロジェクト - ウェブログ - Matrixって何だお? (1)
• アフィン変換 画像処理ソリューション
• 無職のプログラミング [HTML5 Canvas]変形メソッド
scale(),rotate(),translate() の実行順序