Putar vektor

8

Saya ingin kamera orang pertama saya mengubah arah tampilan dengan lancar dari arah d1 ke arah d2. Arah terakhir ditunjukkan oleh posisi target t2.

Sejauh ini saya telah menerapkan rotasi yang berfungsi dengan baik tetapi kecepatan rotasi melambat semakin dekat ke arah saat ini ke yang diinginkan. Inilah yang ingin saya hindari.

Berikut adalah dua metode yang sangat sederhana yang saya tulis sejauh ini:

// 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;
        }
    }

Sekali lagi, rotasi berfungsi dengan baik; kamera mencapai arah yang diinginkan. Tetapi kecepatannya tidak sama selama gerakan -> itu melambat.

Bagaimana cara mencapai rotasi dengan kecepatan konstan?

marc wellman
sumber

Jawaban:

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

Saat Direction& _desiredDirectionberubah menjadi menunjuk ke arah yang hampir sama (saat mereka bertemu), semakin kecil besarnya _rotationAxisakan. Itu masih akan menunjuk ke arah yang tepat untuk menjadi sumbu tetapi akan menjadi lebih pendek. Itulah sifat perhitungan silang.

Nyali dari CreateFromAxisAnglemetode ini menggunakan panjang sumbu sebagai faktor dalam jumlah rotasi yang dihasilkannya. Ketika sumbu memiliki panjang 1, itu menghasilkan jumlah rotasi yang benar.

Jadi jika Anda menormalisasi _rotationAxisantara dua baris yang saya kutip di atas, Anda akan mendapatkan tingkat rotasi konstan.

Steve H.
sumber
6

Saya sarankan membiarkan kerangka kerja melakukan semua pekerjaan untuk Anda. Mulailah dengan menghitung matriks rotasi untuk orientasi awal dan akhir Anda, dan konversikan keduanya menjadi empat angka. Anda hanya melakukan ini sekali pada awal gerakan dan menyimpan nilai.

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

Sekarang interpolasi antara dua orientasi ini menggunakan interpolasi linear bola. Ada metode untuk itu sehingga Anda tidak perlu menerapkan apa pun sendiri:

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

Terakhir, hitung ulang arah Anda menggunakan angka empat di atas, atau ubah kembali ke matriks rotasi. Sesuatu seperti ini misalnya:

Vector3 direction = Vector3.Transform(Vector3.Forward, currentQ);
David Gouveia
sumber
Terima kasih banyak atas saran terperinci Anda! Saya akan mencobanya setelah makan siang;)
marc wellman
Quaternion.SlerpApakah hanya saya, atau apakah itu terdengar seperti nama dalam novel fantasi yang benar-benar buruk atau sangat bagus? Mengurangi titik, tentu saja.
Dana Gugatan Monica