0

私は C# を使用しており、私のプログラムではクォータニオンでリディグボディのクォータニオンを受け取りますが、軸は使用する軸の方向に対応していないため、クォータニオンを回転させたいと考えています。これを行うには、クォータニオンをオイラー角に変換し、ピッチ、ヨー、ロールを座標系に対応するように切り替え、それをクォータニオンに戻してから、回転行列を生成して位置を変換します。

ただし、何か問題が発生します。同じ入力をクォータニオンからオイラーに変換して戻すと、別のクォータニオンが得られます...そのため、関数の1つが何か間違ったことを行い、どこにあるのかわかりません...

Quaternion q = new Quaternion(-0.4, -0.7, -0.8, 0.5);

double yaw = 0, pitch = 0, roll = 0;
toEuler(q, ref yaw, ref pitch, ref roll);

Quaternion quat = ToQ((float)(yaw), (float)(pitch), (float)(roll));





private void toEuler(Quaternion q, ref double x, ref double y, ref double z)
        {
            double test = q.X * q.Y + q.Z * q.W;
            if (test > 0.499)                            // singularity at north pole
            {
                y = 2.0F * System.Math.Atan2(q.X, q.W);
                z = Math.PI / 2.0F;
                x = 0.0F;
                return;
            }

            if (test < -0.499)                           // singularity at south pole
            {
                y = -2.0F * System.Math.Atan2(q.X, q.W);
                z = -Math.PI / 2.0F;
                x = 0.0F;
                return;
            }

            double sqx = q.X * q.X;
            double sqy = q.Y * q.Y;
            double sqz = q.Z * q.Z;
            y = System.Math.Atan2(2.0F * q.Y * q.W - 2.0 * q.X * q.Z, 1.0F - 2.0 * sqy - 2.0 * sqz);
            z = System.Math.Asin(2.0F * test);
            x = System.Math.Atan2(2.0 * q.X * q.W - 2.0 * q.Y * q.Z, 1.0F - 2.0 * sqx - 2.0 * sqz);
        }

 public Quaternion ToQ(float yaw, float pitch, float roll)
        {
            float rollOver2 = roll * 0.5f;
            float sinRollOver2 = (float)Math.Sin((double)rollOver2);
            float cosRollOver2 = (float)Math.Cos((double)rollOver2);
            float pitchOver2 = pitch * 0.5f;
            float sinPitchOver2 = (float)Math.Sin((double)pitchOver2);
            float cosPitchOver2 = (float)Math.Cos((double)pitchOver2);
            float yawOver2 = yaw * 0.5f;
            float sinYawOver2 = (float)Math.Sin((double)yawOver2);
            float cosYawOver2 = (float)Math.Cos((double)yawOver2);
            Quaternion result = new Quaternion();
            result.W = cosYawOver2 * cosPitchOver2 * cosRollOver2 + sinYawOver2 * sinPitchOver2 * sinRollOver2;
            result.X = cosYawOver2 * sinPitchOver2 * cosRollOver2 + sinYawOver2 * cosPitchOver2 * sinRollOver2;
            result.Y = sinYawOver2 * cosPitchOver2 * cosRollOver2 - cosYawOver2 * sinPitchOver2 * sinRollOver2;
            result.Z = cosYawOver2 * cosPitchOver2 * sinRollOver2 - sinYawOver2 * sinPitchOver2 * cosRollOver2;

            return result;
        }
4

3 に答える 3

2

あなたの四元数は正規化されていないようです。回転を表すクォータニオンは、ノルム 1 を持つ必要があります。

于 2015-10-09T20:01:37.983 に答える