-Blenderそのほか-

4. 銀径銀緯と赤径赤緯 (回転行列や座標変換あれこれ)

背景に貼り付けるテクスチャのように、全天を覆う球にテクスチャを貼り付ける場合があります。

*) sample file from DOSCH DESIGN

その際、テクスチャの向きが欲しい方向を向いていればよいのですが、角度が付いているとちょっと面倒です。
普通は使いやすいように方向を合わせてあると思うのですが、例えば星図を貼り付けた後で、x-y面を銀河面(天の川の面)に合わせたいような場合はどう回転させれば良いのでしょう。

*) http://hoshifuru.jp/ からDLした素材を使わせていただきました

普通は手で回転させて合わせれば良いのでしょうが…
回転行列からオイラー回転への変換など、自分で後から分からなくなりそうなことのメモです。

■ 回転行列

こちらの解説によると、赤経赤緯の座標(x, y, z)⇒銀径銀緯(X, Y, Z)への変換行列はこうです。



嬉しいことに、python console 内で行列の計算が行えます。
mthutilsをインポートして、行列 matrix を定義します。

>>> import mathutils
>>> matrix = Matrix(((-0.0548755,-0.873437, -0.483835), (0.49411, -0.44483, 0.746982), (-0.86766, -0.198076, 0.455984)))

解説ページによれば、この行列は z 軸周りの回転(266.405°)、y'軸周りの回転(28.93617°)、x''軸周りの回転(58.59866°) によって得られたもの。

ZYX 順でのオイラー回転の値を得る。

>>> matrix.to_euler('ZYX')
Euler((-1.022739291191101, -0.5050315856933594, 1.633541226387024), 'ZYX')

角度はラジアンで表記されているので、

>>> matrix.to_euler('ZYX')[0] * 180 / pi
-58.598644927451424

>>> matrix.to_euler('ZYX')[1] * 180 / pi
-28.93617838102906

>>> matrix.to_euler('ZYX')[2] * 180 / pi
93.59501793260102
(93.5950°= -266.405°)

ただし、ここで正負の記号が逆になっている点に注意。(さらに、[0]は'ZYX'の回転でもXX成分を表している点も)

blenderのオブジェクトに対して 赤経赤緯⇒銀径銀緯 の (XYZ)オイラー回転をさせると、rotation_world には、上記の行列の逆行列が入っている。(その辺の関係で、回転行列からオイラー角を得るのに 'ZYX' としないと欲しいEuler角が取れないのかな?)

>>> bpy.data.objects['Suzanne'].rotation_euler
Euler((1.0227280855178833, 0.505028486251831, 4.649644374847412), 'XYZ')

>>> bpy.data.objects['Suzanne'].rotation_euler
Euler((1.0227280855178833, 0.505028486251831, 4.649644374847412), 'XYZ')

>>> bpy.data.objects['Suzanne'].rotation_euler[0] * 180 / 3.14159
58.59805238532686

>>> bpy.data.objects['Suzanne'].rotation_euler[1] * 180 / 3.14159
28.936025237325556

>>> bpy.data.objects['Suzanne'].rotation_euler[2] * 180 / 3.14159
266.40522393836693

>>> bpy.data.objects['Suzanne'].matrix_world.inverted().to_3x3()
Matrix(((-0.054875582456588745, -0.8734385967254639, -0.48383238911628723),
        (0.49411964416503906, -0.44482505321502686, 0.746978223323822),
        (-0.8676603436470032, -0.19808019697666168, 0.4559931755065918)))

■ 逆行列

回転行列に対しては、逆行列 = 転置行列 が成り立つので、逆の変換も得やすい。
逆変換に関して同じ操作をすることを考える。

matrx(matrix_worldの逆行列)を .to_euler('ZYX') すれば欲しいオイラー角が得られたので、

>>> matrix.transposed().to_euler('ZYX')[0] * 180 / pi
23.479760526706606

>>> matrix.transposed().to_euler('ZYX')[1] * 180 / pi
-60.18837828696106

>>> matrix.transposed().to_euler('ZYX')[2] * 180 / pi
-96.33726375228026

もしくは、matrixは、「to_euler('XYZ')すれば欲しいオイラー角が得られる matrix_world」 の逆行列である、ということから(ややこしい!)

>>> matrix.to_euler('XYZ')[0] * 180 / pi
-23.479758819159315

>>> matrix.to_euler('XYZ')[1] * 180 / pi
60.18835096620438

>>> matrix.to_euler('XYZ')[2] * 180 / pi
96.3372569220911

で、符号の正しいオイラー角が得られた。

結局、



のような銀河座標のマッピング(これは魚眼2つなので銀河中心が左中心)から


のような赤経赤緯上に焼直すには、

天球イメージを 'XYZ' (z, y', x''軸回転) で x:58.598°y: 28.936°z: 266.405°回転させるか

カメラ側を逆変換 'XYZ' で x:-23.479° y:60.188° z:96.3372°回転をさせる。

inserted by FC2 system