Xoay một vectơ


8

Tôi muốn máy ảnh của người thứ nhất của tôi thay đổi trơn tru hướng nhìn từ hướng d1 sang hướng d2. Hướng thứ hai được chỉ định bởi vị trí mục tiêu t2.

Cho đến nay tôi đã thực hiện một vòng quay hoạt động tốt nhưng tốc độ của vòng quay chậm lại càng gần hướng hiện tại đến hướng mong muốn. Đây là những gì tôi muốn tránh.

Đây là hai phương pháp rất đơn giản mà tôi đã viết cho đến nay:

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

Một lần nữa, xoay hoạt động tốt; máy ảnh đạt đến hướng mong muốn của nó. Nhưng tốc độ không bằng quá trình di chuyển -> nó chậm lại.

Làm thế nào để đạt được một vòng quay với tốc độ không đổi?

Câu trả lời:


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

Khi Direction& _desiredDirectionthay đổi để chỉ theo cùng một hướng (khi chúng hội tụ), độ lớn của _rotationAxisnó sẽ càng nhỏ. Nó vẫn sẽ được chỉ theo hướng thích hợp là trục nhưng sẽ có chiều dài ngắn hơn. Đó là bản chất của tính toán chéo.

Các can đảm của CreateFromAxisAnglephương pháp sử dụng độ dài của trục làm hệ số cho số vòng quay mà nó tạo ra. Khi trục có độ dài bằng 1, nó sẽ dẫn đến số lượng xoay chính xác.

Vì vậy, nếu bạn bình thường hóa _rotationAxisgiữa hai dòng tôi đã trích dẫn ở trên, bạn sẽ có được tốc độ quay không đổi.


6

Tôi đề nghị để khung làm tất cả công việc cho bạn. Bắt đầu bằng cách tính toán một ma trận xoay cho các hướng bắt đầu và kết thúc của bạn, và chuyển đổi cả hai thành bậc bốn. Bạn chỉ làm điều này một lần khi bắt đầu chuyển động và lưu trữ các giá trị.

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

Bây giờ nội suy giữa hai định hướng này bằng cách sử dụng phép nội suy tuyến tính hình cầu. Có một phương pháp cho nó để bạn không phải tự mình thực hiện bất cứ điều gì:

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

Cuối cùng tính toán lại hướng của bạn bằng cách sử dụng bậc bốn ở trên hoặc chuyển đổi nó trở lại thành ma trận xoay. Một cái gì đó như thế này chẳng hạn:

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

Cảm ơn bạn rất nhiều vì lời khuyên chi tiết của bạn! Tôi sẽ thử điều đó sau bữa trưa;)
marc wellman

Quaternion.SlerpCó phải chỉ có tôi, hoặc nó nghe giống như một cái tên trong một cuốn tiểu thuyết giả tưởng thực sự xấu hoặc thực sự tốt? Trừ dấu chấm, tất nhiên.
Vụ kiện của Quỹ Monica
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.