「instantNeRFで遊ぶ Advent Calendar 2022」の16日目です。
今日はCOLMAPやBlenderの入力を検討するために必要だったクォータニオンの計算について書きます。
今回使ったのはscipy.spatial.transformのRotationです。
from_~でRotationを入力 / as_~でRotationの変換結果を出力
from scipy.spatial.transform import Rotation as R
r = R.from_euler('X', [10], degrees=True)
print(r.as_quat())
[[0.08715574 0. 0. 0.9961947 ]]
計算結果をBlenderと比較しました。
scipy.spatial.transformのクォータニオンの出力はX, Y, Z, Wの順番でした。
as_eulerのときの注意
- 大文字と小文字で意味が違う
大文字は内因性、小文字は外因性になります。 - 出力の順番は軸設定の順番と同じ
常にXYZではなく、例えばZXYとしたら出力もZXYになりました。
from scipy.spatial.transform import Rotation as R
r2 = R.from_euler("ZXY", [10, 20, 30], degrees=True)
e2=r2.as_euler("ZXY", degrees=True)
e2[0], e2[1], e2[2]
(9.99999999999999, 19.99999999999998, 29.999999999999964)
BlenderのEulerモードの順番との対応
BlenderのEulerモードの表記順番は座標を回す軸の順番と逆になっていました。
from scipy.spatial.transform import Rotation as R
r1 = R.from_euler("X", [10], degrees=True)
r2 = R.from_euler("Y", [20], degrees=True)
r3 = R.from_euler("Z", [30], degrees=True)
r4 = r1 * r2 * r3
print(r4.as_quat())
[[0.12767944 0.14487813 0.26853582 0.94371436]]
r4a = R.from_euler("XYZ", [10, 20, 30], degrees=True)
print(r4a.as_quat())
[0.12767944 0.14487813 0.26853582 0.94371436]
クォータニオンに限らずオイラー角や回転行列、その掛け算は順番で意味が変わるので大変です。
参考