ベクトルを回転させる


8

一人称視点のカメラで、視線方向をd1からd2にスムーズに変更したい。後者の方向は、目標位置t2によって示される。

これまでのところ、正常に機能する回転を実装しましたが、回転の速度は、現在の方向が目的の方向に近づくほど遅くなります。これは避けたいものです。

これまでに作成した2つの非常に単純なメソッドを次に示します。

// this method initiates the direction change and sets the parameter
public void LookAt(Vector3 target) {

        _desiredDirection = target - _cameraPosition;
        _desiredDirection.Normalize();

        _rotation = new Matrix();

        _rotationAxis = Vector3.Cross(Direction, _desiredDirection);

        _isLooking = true;
    }


// this method gets execute by the Update()-method if _isLooking flag is up.
private void _lookingAt() {

        dist = Vector3.Distance(Direction, _desiredDirection);

        // check whether the current direction has reached the desired one.
        if (dist >= 0.00001f) {

            _rotationAxis = Vector3.Cross(Direction, _desiredDirection);
            _rotation = Matrix.CreateFromAxisAngle(_rotationAxis, MathHelper.ToRadians(1));


            Direction = Vector3.TransformNormal(Direction, _rotation);
        } else {

            _onDirectionReached();
            _isLooking = false;
        }
    }

繰り返しになりますが、回転は正常に機能します。カメラが目的の方向に到達します。しかし、速度は移動の過程で等しくありません->速度が低下します。

一定速度で回転させるには?

回答:


3
_rotationAxis = Vector3.Cross(Direction, _desiredDirection);
_rotation = Matrix.CreateFromAxisAngle(_rotationAxis, MathHelper.ToRadians(1));

ようDirection_desiredDirection(それらが収束するように)変化はほぼ同じ方向を指しする、小さいの大きさ_rotationAxisであろう。軸になるように正しい方向を向いていますが、長さは短くなります。それが相互計算の性質です。

CreateFromAxisAngleメソッドの根性は、結果として生じる回転量の要素として軸の長さを使用します。軸の長さが1の場合、正しい回転量が得られます。

したがって、_rotationAxis上記で引用した2つの線の間で正規化すると、回転速度は一定になります。


6

フレームワークにすべての作業を任せることをお勧めします。まず、開始方向と終了方向の回転行列を計算し、両方を四元数に変換します。これは、移動の開始時に一度だけ実行し、値を保存します。

Matrix start = /* calculate current rotation matrix */;
Matrix end = /* calculate desired rotation matrix */;
Quaternion startQ = Quaternion.CreateFromRotationMatrix(start);
Quaternion endQ = Quaternion.CreateFromRotationMatrix(end);

次に、球面線形補間を使用して、これら2つの方向の間を補間します。そのためのメソッドがあるので、自分で何かを実装する必要はありません。

// Animate the progress parameter between 0 and 1
Quaternion currentQ = Quaternion.Slerp(startQ, endQ, progress);

最後に、上記のクォータニオンを使用して方向を再計算するか、回転マトリックスに変換し直します。たとえば、次のようなもの:

Vector3 direction = Vector3.Transform(Vector3.Forward, currentQ);

細かいアドバイスありがとうございます!私は昼食後にそれを試すつもりです;)
マーク・ウェルマン

Quaternion.Slerpそれは私だけですか、それとも本当に悪いまたは本当に良いファンタジー小説の名前のように聞こえますか?もちろんマイナスドット。
モニカの訴訟に資金を提供
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.