3

オイラー角を回転行列から外すのに行き詰まりました。

私の慣習は次のとおりです。

  • 左利き(x右、z後ろ、y上)
  • YZX
  • 左利きの回転角

私の回転行列は、(私のコードから)次のようなオイラー角から構築されています。

    var xRotationMatrix = $M([
        [1,  0,   0, 0], 
        [0, cx, -sx, 0], 
        [0, sx,  cx, 0], 
        [0,  0,   0, 1]
    ]);

    var yRotationMatrix = $M([
        [ cy, 0, sy, 0], 
        [  0, 1,  0, 0], 
        [-sy, 0, cy, 0], 
        [  0, 0,  0, 1]
    ]);
    var zRotationMatrix = $M([
        [cz, -sz, 0, 0], 
        [sz,  cz, 0, 0], 
        [ 0,   0, 1, 0], 
        [ 0,   0, 0, 1]
    ]);

これにより、最終的な回転行列は次のようになります。

R(YZX) = | cy.cz, -cy.sz.cx + sy.sx,  cy.sz.sx + sy.cx, 0|
         |    sz,             cz.cx,            -cz.sx, 0|
         |-sy.cz,  sy.sz.cx + cy.sx, -sy.sz.sx + cy.cx, 0|
         |     0,                 0,                 0, 1|

このコードを使用して、この行列からオイラー角を計算しています。

this.anglesFromMatrix = function(m) {
    var y = 0, x = 0, z = 0;

    if (m.e(2, 1) > 0.999) {
        y = Math.atan2(m.e(1, 3), m.e(3, 3));
        z = Math.PI / 2;
        x = 0;
    } else if (m.e(2, 1) < -0.999) {
        y = Math.atan2(m.e(1, 3), m.e(3, 3));
        z = -Math.PI / 2;
        x = 0;
    } else {
        y = Math.atan2(-m.e(3, 1), -m.e(1, 1));
        x = Math.atan2(-m.e(2, 3), m.e(2, 2));
        z = Math.asin(m.e(2, 1));
    }
    return {theta: this.deg(x), phi: this.deg(y), psi: this.deg(z)};
};

私は数学を前後に数回行いましたが、何が悪いのかわかりません。どんな助けでも大歓迎です。

4

3 に答える 3

2

行列とオイラー角が一致していません。使用する必要があるようです

y = Math.atan2(-m.e(3, 1), m.e(1, 1));

それ以外の

y = Math.atan2(-m.e(3, 1), -m.e(1, 1));

一般的な場合 (else ブランチ)。

私が「似ている」と言ったのは、これは何語ですか? この言語のインデックスが正しいと仮定しています。atan2についてよろしいですか?atan2 には単一の規則はありません。プログラミング言語によっては、正弦項が最初の引数である場合もあれば、余弦項が最初の引数である場合もあります。

于 2011-06-28T11:55:24.043 に答える
1

関数の最後の最も重要なブランチにはanglesFromMatrix小さな符号エラーがありますが、それ以外は正しく機能します。使用する

y = Math.atan2(-m.e(3, 1), m.e(1, 1))

とのみm.e(3, 1)を反転する必要があるためです。他のブランチでエラーをチェックしていません。m.e(1, 1) = cy.czm.e(3, 1) = -sy.cz

sz = m.e(2, 1)には 2 つの解がある(x, y, z)ため、行列の作成に使用される角度は によって返されるm角度と同じではない可能性があることに注意してください。代わりに、から構築された行列が実際に等しいことをテストできます。(rx, ry, rz)anglesFromMatrix(m)rm(rx, ry, rz)m

于 2011-06-28T12:49:20.750 に答える