9

既存のクォータニオンにオイラー角を追加したい。これが私が得たものです:

Quaternion oldTransform = transform.Rotation;

float YawRotation = mouseDiff.x *  RotationSpeed;
Quaternion YawRotationQuaternion = new Quaternion();
YawRotationQuaternion.CreateFromAxisAngle (0, 1, 0, YawRotation);

float PitchRotation = mouseDiff.y * RotationSpeed;
Quaternion PitchRotationQuaternion = new Quaternion();
PitchRotationQuaternion.CreateFromAxisAngle ( 1, 0, 0, PitchRotation);

Quaternion result = oldTransform * YawRotationQuaternion * PitchRotationQuaternion;
transform.Rotation = result;

ヨーとピッチの回転のみが必要です。古い変換にはこのプロパティがあります。それに追加するオイラー角も、ピッチとヨーの回転のみです。それを乗算するとどうなるかというと、oldTransform が記述する回転がロール回転を導入するということです。

それから私は試しました:

Quaternion result = YawRotationQuaternion * oldTransform * PitchRotationQuaternion;

これにより、ロールの回転は発生しません。このオプションは、oldTransform がヨー軸をピッチ軸に回転させるときにジンバル ロックがあるため、さらに悪化します。

ここで想像できるのは、oldTransform から古いヨーとピッチの回転を取得し、ヨーとピッチの軸を変更して、それらが (0,1,0) と (1,0,0) ではなくなるようにすることです。ここでの問題は、クォータニオンからオイラー角を抽出すると、ジンバル ロックも得られることです。

では、特定の軸のオイラー角をクォータニオンに追加するにはどうすればよいでしょうか?

4

1 に答える 1

5

解決:

変換の順序を変更します。

Quaternion result = PitchRotationQuaternion * oldTransform * YawRotationQuaternion;

説明:

ローカル参照フレームを持つオブジェクトがあります。オブジェクトに対して、+x_oはオブジェクトの右方向、-z_oは「前方」、+y_oは「上」を指します。オブジェクトは、ワールドの参照フレームに存在します。ワールドには独自の軸(x_w,y_w,z_w)があり、+y_wがワールドのアップです。オブジェクトの向きが変わると、ピッチ( x_o を中心に回転)ヨー( y_wを中心に回転) が必要になります。

コードでは、2 つのクォータニオンを作成します。それらを適用する方法は、 x_w と y_w の周りの回転表します変換に既にヨーが適用されている場合、x_oは x_w整列しなくなります。その結果、ロールが得られます。幸いなことに、適用している変換では、ジンバル ロックは問題になりません。ジンバル ロックは、ピッチを 90 度にすると、ヨーロールが同じになるという事実から明らかです。しかし、ロールを使用していません。だから関係ない。

変換は、常にx_wを中心とした回転とそれに続くy_wを中心とした回転として表すことができます。新しい「ピッチ クォータニオン」を古い変換の左側に置くと、それが他の蓄積されたピッチに追加されます。右側の「ヨー クォータニオン」を維持すると、蓄積されたヨーに追加されます。したがって、最後の四元数を束または乗算として表現する場合、 x_w を中心とした純粋な回転の文字列と、それに続くy_wを中心とした回転の文字列になります。オブジェクトがx_wに平行なx_oで始まる限り、これはあなたが望むことを行います。

于 2013-06-27T15:17:50.043 に答える