Làm thế nào bạn có thể trích xuất định hướng từ một ma trận biến đổi?


10

Tôi có một ma trận biến đổi 4x4 M và tôi muốn tìm ra hình dạng của một hình cầu khi được biến đổi bởi M. (Hình cầu nằm ở gốc tọa độ và có bán kính 1.)

Tôi biết tôi có thể tìm trung tâm bằng cách nhân M với (0,0,0,1).

Tuy nhiên, bán kính trở thành một vấn đề vì M có thể đè bẹp và xoay quả cầu. Làm thế nào tôi có thể tìm ra (các) bán kính mới của ellipsoid kết quả? Có cách nào để tìm ra định hướng?

Cụ thể hơn, tôi cần biết kích thước của quả cầu giới hạn sẽ bao quanh quả cầu biến đổi. Nói cách khác, mức tối đa của | M * V - M * (0,0,0,1) |, trong đó V là một vectơ đơn vị (một điểm trên hình cầu ban đầu).


1
Bạn có thể tính chiều dài của các vectơ trục biến đổi không? (3 cột của phần xoay của ma trận của bạn) Hình cầu giới hạn sẽ có bán kính bằng chiều dài của vectơ dài nhất.
Bart

Không, tôi không nghĩ đó là chính xác. Hướng dài nhất có thể không được căn chỉnh trục. (Hãy tưởng tượng nếu bạn đè bẹp nó, xoay nó, lại nghiền nát nó, xoay nó thêm một lần nữa, v.v.)
CaptainCodeman

Hmm, không chắc chắn rằng vấn đề. Nếu tôi có thể thuyết phục bản thân mình, tôi sẽ viết một câu trả lời sau ngày hôm nay. ;)
Bart

Vấn đề là, nếu bạn thực hiện chuyển đổi SCALE, các vectơ cơ sở của ma trận M không phải giữ ORTHOGONAL cho nhau.
GPUquant

Câu trả lời:


6

Về mặt toán học, số lượng bạn hỏi về được gọi là định mức toán tử . Thật không may, không có công thức đơn giản cho nó. Nếu đó là một phép biến đổi affine hoàn toàn tổng quát - ví dụ, nếu nó có thể có sự kết hợp tùy ý giữa các phép quay và tỷ lệ không hình thành, theo bất kỳ thứ tự nào - thì tôi sợ rằng không có gì cho nó ngoài việc sử dụng phân tách giá trị số ít . Nếu bạn áp dụng SVD cho ma trận của mình thì giá trị số đơn lớn nhất sẽ là bán kính tối đa của ellipsoid kết quả. Các giá trị số ít khác cũng sẽ là hai bán kính khác của nó và quy trình SVD cũng có thể trích xuất hướng của các trục cho bạn.

Việc thực hiện SVD không dành cho người yếu tim, vì nó liên quan đến việc tìm kiếm giá trị bản địa. Nếu tất cả những gì bạn muốn là chính các giá trị số ít, chúng là căn bậc hai của giá trị riêng của M ^ T * M. Vì vậy, nếu bạn có một bộ giải eigenvalue 3x3 tiện dụng, hoặc bạn không phiền khi viết nó, bạn có thể sử dụng nó. Nếu bạn cũng muốn trích xuất các hướng của các trục, thì nó sẽ được tham gia nhiều hơn vì bạn cũng phải tìm các hàm riêng. Trên bài viết Wikipedia đó có một danh sách các liên kết đến các thư viện để thực hiện SVD, một trong số đó bạn có thể sử dụng trong dự án của mình.

Nếu dạng ma trận của bạn bị hạn chế theo cách mà tỷ lệ không hình thành xảy ra nhiều nhất một lần và là biến đổi đầu tiên được áp dụng, tức là đúng nhất khi bạn sử dụng vectơ cột, thì bạn có thể đơn giản hóa điều này để chỉ nhìn vào độ dài của vectơ trục biến đổi. Trong trường hợp đó một mình - tức là một thang đo không hình dạng duy nhất theo sau bởi bất kỳ chuỗi xoay, phản xạ và tỷ lệ đồng nhất - chỉ nhìn vào các vectơ trục sẽ cho bạn câu trả lời đúng.


Cảm ơn, tôi đánh giá cao phản ứng chi tiết. Trường hợp phân tách được cung cấp trong câu trả lời khác không hoạt động?
CaptainCodeman

2
@CaptainCodeman Câu trả lời khác chỉ là nhìn vào các vectơ trục biến đổi (tức là các cột của ma trận), giống như những gì tôi đã mô tả trong đoạn thứ ba của mình. Nó không thành công trong trường hợp có thang đo không đồng nhất sau một vòng quay, kể từ đó tỷ lệ không áp dụng dọc theo các trục ban đầu.
Nathan Reed

2

Có thể trích xuất các yếu tố tỷ lệ từ ma trận và sau đó sử dụng giá trị tối đa của các thành phần của nó. Sử dụng ma trận SRT (Xoay-Xoay-Dịch) bạn có thể làm như thế này:

glm::mat4 m = ...;
// Extract col vectors of the matrix
glm::vec3 col1(m[0][0], m[0][1], m[0][2]);
glm::vec3 col2(m[1][0], m[1][1], m[1][2]);
glm::vec3 col3(m[2][0], m[2][1], m[2][2]);
//Extract the scaling factors
glm::vec3 scaling;
scaling.x = glm::length(col1);
scaling.y = glm::length(col2);
scaling.z = glm::length(col3);

float scaleFactor = MAX(scaling.x, MAX(scaling.y, scaling.z));

(dựa trên http://wklej.org/id/950061/ - tên là decomposeTRS và không decomposeSRT vì tôi sử dụng các tên được đặt theo thứ tự ma trận được nhân trong OpenGL).

Bây giờ bạn có thể nhân bán kính hình cầu ban đầu bằng scaleFactor và bạn có hình cầu giới hạn của mình.

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.