3x3行列から回転・拡大縮小・平行移動の成分を取り出す


AndroidのCanvas APIを使った描画をしていてMatrixから回転・拡大縮小・平行移動の成分を取り出したくなったので計算方法を考えてみた。

2次元の点の変換を定義するある行列から回転成分・拡大縮小成分・平行移動成分を抽出するためには、回転行列と拡大縮小・平行移動の行列の積に分割すれば良い。行列の積は順番によって結果が異なるので、回転を先に行うか拡大縮小・平行移動を先に行うかによって求める値が異なる。
求めたい回転成分を θ 、拡大縮小成分を sx, sy 、平行移動成分を dx, dy とする。

先に拡大縮小・平行移動してから回転すると考える場合

上記より

であることがわかる。
a,b,d,eをそれぞれsx,syについて解くと

また、a と d より

となるから


θがわかったので、式1、式2からsx, syを計算する。sinθとcosθのどちらか0でない方を使って計算する。
c にcosθを掛けて、f にsinθを掛けると

2つの式を足すと

sinθ≠0のとき、cより

cosθ≠0のとき、fより

先に回転してから拡大縮小・平行移動すると考える場合

成分同士の対応から、

cosθ≠0のとき、

sinθ≠0のとき、

こっちのほうが簡単ですね。

注意

書いてから気づいたけど a = 0 となる場合とか、分母が0になる可能性を考慮した処理が抜けてるな…でも普通の描画処理だったらあんま気にしなくていいのかな?気にしなきゃいけなかったら教えてください。

tan-1 はJavaでいうところの Math.atan() です。