0

オブジェクトの回転のための単純な四元数の実装があります。同じ軸に沿ったベクトル (つまり、X、Y、または Z 軸に沿った) を中心とした回転を表す 2 つのクォータニオンを作成すると、結果は、それらの大きさの合計による単一の回転と同じになります (つまり、PI/2 で回転してから PI /2 は PI による回転と同じです)。それは良い。

回転軸が軸に揃えられていないとすぐに、連結は予想から発散します (PI/2 で回転してから再び PI/2で回転するのは、PI で回転するのと同じではありません)。それは良いことではありません。

数日間コードを調べた後、何も問題は見られませんでしたので、今質問させてください: クォータニオンがどのように機能するかを根本的に誤解しているのでしょうか? 率直に言って、私は四元数を完全には理解していないので、それらが表す軸角度回転の観点から四元数について推論しています。

そうでない場合は、私のコードを見てもらえますか? :-) すべて (Java で記述されています。Android をターゲットにしています) を GitHub にプッシュしました: https://github.com/wtracy/quaternions Quaternions ディレクトリの下に Eclipse プロジェクトがあります。(何かを読むのに Eclipse は必要ありませんが、便利です。) quaternion クラスは src/ フォルダーの下にあります。test/ フォルダーには、Quaternion クラスを実行するために必要な JUnit テストとクラスのスタブがあります。

コードとテストを簡単に理解できるように最善を尽くしました。自分のコードのバグを見つけるようにインターネットに頼むのはばかげているように感じますが、アイデアはまったくありません。:-P

4

2 に答える 2

3

クォータニオン乗算に符号エラーがあります。

public Quaternion times(Quaternion q2) {
    Quaternion q1 = this;
    float w = q1.w*q2.w - q1.x*q2.x - q1.y*q2.y - q1.z*q2.z;
    float x = q1.x*q2.w + q1.w*q2.x + q1.z*q2.y - q1.y*q2.z;
    float y = q1.w*q2.y - q1.x*q2.z + q1.y*q2.w + q1.z*q2.x;
    float z = q1.w*q2.z - q2.x*q2.y + q1.y*q2.x + q1.z*q2.w;
    return new Quaternion(w, x, y, z);
}

書き出された製品は

(w1 + x1*i + y1*j + z1*k)*(w2 + x2*i + y2*j + z2*k)
= w1*w2 - x1*x2 - y1*y2 - z1*z2
+ (w1*x2 + x1*w2 + y1*z2 - z1*y2)*i
+ (w1*y2 - x1*z2 + y1*w2 + z1*x2)*j
+ (w1*z2 + x1*y2 - y1*x2 + z1*w2)*k

以来

i*j = k    j*i = -k
j*k = i    k*j = -i
k*i = j    i*k = -j

xとの方程式にマイナスが含まれている間違った用語がありますz。2つの軸が同じである場合、1つは(省略形として)書くこともできるため、違いはありません。

(r + v)*(s + w) = r*s - <v|w> + r*w + s*v + v×w

同一線上のv×w = 0ベクトルの場合ですが、軸が異なる場合は表示されます。

さらに、の式ではz

float z = q1.w*q2.z - q2.x*q2.y + q1.y*q2.x + q1.z*q2.w;
                          ^^^^^^^^^

q2両方の要因を一度使用して、タイプミスがあります。

そのはず

public Quaternion times(Quaternion q2) {
    Quaternion q1 = this;
    float w = q1.w*q2.w - q1.x*q2.x - q1.y*q2.y - q1.z*q2.z;
    float x = q1.x*q2.w + q1.w*q2.x - q1.z*q2.y + q1.y*q2.z;
    float y = q1.w*q2.y - q1.x*q2.z + q1.y*q2.w + q1.z*q2.x;
    float z = q1.w*q2.z + q1.x*q2.y - q1.y*q2.x + q1.z*q2.w;
    return new Quaternion(w, x, y, z);
}
于 2012-12-21T00:24:28.847 に答える
0

回転軸が軸に揃えられていないとすぐに、連結は予想から発散します (PI/2 で回転してから再び PI/2 で回転するのは、PI で回転するのと同じではありません)。それは良いことではありません。

数学を正しく理解した後でも、そうではないことがわかります。一般に、3 次元空間での回転は可換ではありません。回転 A を実行してから回転 B を実行すると、通常、最初に回転 B を実行してから回転 A を実行した場合とは異なる方向になります。

于 2012-12-21T12:31:38.347 に答える