2

ビー玉の回転に問題があります。
で試してみましたが、いくつか問題がMatrix.CreateFromYawPitchRollありました。ジンバルロック効果Matrix.CreateRotationによるものだと思います。

そのため、代わりにクォータニオンを使用してみましたが、何も変わりませんでした。
軸のみで移動する場合は問題なく動作しますが、回転が 2 つの異なる軸で発生すると、ビー玉は依然として間違った軸で回転します。

これが私のコードです:

// declarations
Vector3 Position = Vector3.Zero;
Vector3 Rotation = Vector3.Zero;
Quaternion qRotation = Quaternion.Identity;

AbsoluteBoneTransforms = new Matrix[Model.Bones.Count]; 
Model.CopyAbsoluteBoneTransformsTo(AbsoluteBoneTransforms); 

Updateメソッド内:

Position += speed;
Rotation = speed * MathHelper.ToRadians(-1.5f);

Quaternion rot = Quaternion.CreateFromAxisAngle(Vector3.Right, Rotation.Z) *
                Quaternion.CreateFromAxisAngle(Vector3.Backward, Rotation.X);

qRotation *= rot;

そしてDrawメソッドで:

effect.World = AbsoluteBoneTransforms[mesh.ParentBone.Index] * 
  Matrix.CreateFromQuaternion(qRotation) * Matrix.CreateTranslation(Position);

どうしたの?Quaternion.CreateFromAxisAngle複数の軸で使用するのは間違っていますか?

編集

複数の軸の組み合わせを使用する代わりに、大理石の回転軸を直接計算しようとしました:

angle += speed.Length() * angularVelocity;
qRotation = Quaternion.CreateFromAxisAngle(Vector3.Cross(speed, Vector3.Up), angle);
qRotation.Normalize();

angle現在の動きを追跡するフロートです。この解決策はジンバル ロック
を作成しないようですが、大理石の回転は正しくありません。回転速度は一定ではないようですが、時間の経過とともに速くなったり遅くなったりしました。理由はわかりません。

クォータニオンを「連結」すると、次を使用してすべてのフレームを取得します

qRotation *= Quaternion.CreateFromAxisAngle(Vector3.Cross(speed, Vector3.Up), angle)

ジンバル ロック効果はまだ表示されます。

4

1 に答える 1

2

これが私がそれに取り組んだ方法です:

speedはボールが転がる方向を表すベクトルであり、その大きさはその方向に移動する速度を表すと仮定しています。

Vector3 axis = Vector3.Cross(speed, Vector3.Up);
float angle = speed.Length();//factor by delta time if neccesary

Quaternion rotationThisFrame = Quaternion.CreateFromAxisAngle(axis, angle * (1/radiusOfBall));

次に、それを qRotation に連結できます。また、連結後にクォータニオンを正規化する必要がある場合があります。

更新: この質問/スレッドに対する正しい答えは、クォータニオンが連結される順序を逆にすることでした。XNA に関しては、行列は左から右に結合され、クォータニオンは右から左に結合されます。

于 2013-10-04T11:54:54.370 に答える