8

Tôi đang bắt đầu trên Molehill và đang gặp rất nhiều vấn đề khi nắm bắt Matrix3D. Vấn đề đầu tiên của tôi là làm thế nào để quản lý một Matrix3D mô tả định hướng của một mô hình duy nhất.Làm thế nào để bạn kết hợp các phép quay X, Y và Z trong không gian cục bộ của mô hình (không phải toàn cục)?

Tôi sử dụng Matrix3D.appendRotation() để thực hiện việc này. Nhưng tùy thuộc vào thứ tự tôi gắn thêm vào tôi nhận được một kết quả khác nhau (rõ ràng, vì tôi đang luân phiên một lần trong không gian toàn cầu). Tôi biết đây là một vấn đề phổ biến, tôi đã chạy vào nó với mô hình phần mềm 3D. Nhưng lần này, tôi phải sửa nó theo chương trình. Đây là nơi tôi cần giúp đỡ.

Trước tiên, trong trường hợp có bất kỳ sự nhầm lẫn nào, đây là sự cố trong ảnh:

Bước 1: Tôi vẽ mô hình.

Start position

Bước 2a: Tôi xoay nó trên trục X. Có vẻ chính xác!

X-axis rotation

Bước 2b: Tôi xoay nó trên trục Z. Có vẻ chính xác!

Z-axis rotation

Vì vậy, ... nếu tôi xoay trên trục X và Z của mô hình tôi muốn này:

desired XZ rotation

Nhưng, sadface, tôi có được điều này:

enter image description here

Tôi có thể xem sự cố. Tôi đang nối từng vòng một vào không gian toàn cầu. Tôi cần phải xoay trong không gian địa phương của đối tượng. Tôi KHÔNG có ý tưởng làm thế nào để làm điều này hoặc những gì tôi thậm chí nên tìm kiếm (thuật ngữ, vv). Mã này là đơn giản (và sai):

modelLocalMatrix.identity(); 
modelLocalMatrix.appendRotation(modelZRot, Vector3D.Z_AXIS); 
modelLocalMatrix.appendRotation(modelXRot, Vector3D.X_AXIS); 
//eventually y-axis rotation as well... 
renderMatrix.append(modelLocalMatrix); 

Tôi đoán rằng thay vì sử dụng các hằng số trục Vector3D, tôi muốn sử dụng một số vector bình thường và một số ... uh, điều ... ở vị trí của modelZRot , modelXRot và cuối cùng là modelYRot. Bất cứ ai có thể cho tôi biết giải pháp thực hành tốt nhất là áp dụng loại xoay vòng mong muốn ở trên?

CẬP NHẬT: Đã dành cả ngày đánh "sách" (aka KhanAcademy trên YouTube) và bắt đầu bản trình bày này tại đây: The Mathematics of the 3d Rotation Matrix Tôi đã tình cờ gặp một loại phương pháp "nhìn vào" rất gần với giải pháp mong muốn của tôi. Thật không may, tôi chỉ có 50% hiểu nó. Tôi vẫn hy vọng ai đó có thể làm sáng tỏ chủ đề này!

var angleOfRotation:Number = Math.PI/2; //90 degrees... 
var axisOfRotation:Vector3D = new Vector3D(0, 1, 0); //some point to look at... 
//normalize the vector! 
axisOfRotation.normalize(); 
var x:Number = axisOfRotation.x; 
var y:Number = axisOfRotation.y; 
var z:Number = axisOfRotation.z; 
var c:Number = Math.cos(angleOfRotation); 
var s:Number = Math.sin(angleOfRotation); 
var t:Number = 1 - c; 

//Graphics Gems (Glassner, Academic Press, 1990). 
modelLocalMatrix = new Matrix3D(new <Number>[ 
    t * (x * x) + c, t * x * y - s * z, t * x * z + s * y, 0, 
    t * x * y + s * z, t * (y * y) + c, t * y * z - s * x, 0, 
    t * x * z - s * y, t * y * z + s * x, t * (z * z) + c, 0, 
    0,   0,   0,   1 
]); 

Thing là, điều này có vẻ khá phức tạp. Đặc biệt là vì góc quay cho một Vector3D nên là giá trị thứ tư (w). Quan trọng hơn, Matrix3D đã xuất hiện để có một phương thức lookAt(). Tôi chưa hiểu ... hãy nhờ ai đó cứu tôi khỏi những giờ thử và lỗi!

Trả lời

2

Ok, về cơ bản tôi đã tìm ra cách để thực hiện việc này. Nó là MUCH đơn giản hơn tôi đã làm cho nó. Nó cũng giúp đánh giá API Matrix3D (nó đã có một số chức năng tuyệt vời!).

Thứ nhất, mã nguồn tôi đã sử dụng để xoay mô hình của tôi trên trục địa phương của nó:

var raw:Vector.<Number> = modelLocalMatrix.rawData; 
var right:Vector3D = new Vector3D(raw[0], raw[1], raw[2]); 
var up:Vector3D = new Vector3D(raw[4], raw[5], raw[6]); 
var out:Vector3D = new Vector3D(raw[8], raw[9], raw[10]); 

modelLocalMatrix.appendRotation(modelXRot, right); 
modelLocalMatrix.appendRotation(modelYRot, up); 
modelLocalMatrix.appendRotation(modelZRot, out); 

Các "lên", "đúng" và "out" vectơ bình thường được thảo luận trong các liên kết trong ban đầu của tôi bài đăng. Về cơ bản chúng là các trục sân, yaw và cuộn của mô hình. Đủ để nói rằng khi bạn khởi tạo đối tượng của mình, các vectơ này giống hệt với Vector3D.X_AXIS, Y_AXIS và Z_AXIS. Tôi đã trích xuất chúng bằng cách sử dụng tài sản Matrix3D.rawData mặc dù có thể có một cách tốt hơn.

Bây giờ, bạn có thể xoay dọc theo bất kỳ trục nào trong số các trục này khi bạn chọn, nhưng ngay lập tức bạn thực hiện, hướng hai trục khác sẽ thay đổi ngay lập tức. Điều này thật ý nghĩa. Mô hình của bạn đã xoay và "đúng", "lên" và "chuyển tiếp" của nó giờ đây khác! Vì vậy, nếu bạn bắt đầu bằng cách xoay trên trục "đúng" của mô hình (hãy nhớ, điều này bắt đầu giống như X_AXIS toàn cầu) và sau đó bạn muốn cuộn mô hình của mình trên trục "ngoài", bạn cần lấy nó từ địa phương của mô hình ma trận. Rõ ràng, nó không còn giống với Z_AXIS toàn cầu nữa. Lưu ý rằng tôi không gọi Matrix3D.identity(). Nếu tôi đã làm điều đó, thì trục của mô hình của tôi sẽ được đặt lại! Điều này là ok cho vòng lặp render của tôi, mặc dù tôi đã phải thay đổi mã của tôi (và cách suy nghĩ) một chút vì tôi đã thiết lập lại tất cả các ma trận của mình trước khi áp dụng phép biến đổi và phép quay. Lưu ý rằng modelXRot, modelYRot và modelZRot lưu trữ giá trị xoay theo độ.

Tôi chắc chắn hy vọng điều này sẽ giúp ai đó. Tôi không thể tin rằng một vấn đề phổ biến như vậy với một giải pháp đơn giản như vậy là hư không được tìm thấy. Dù sao, nó chắc chắn có vẻ là làm những gì tôi muốn nó.

Các vấn đề liên quan