Câu trả lời:
Có, bạn có thể thêm một vectơ trong trường hợp dịch. Lý do sử dụng ma trận giúp có một cách thống nhất để xử lý các phép biến đổi kết hợp khác nhau.
Ví dụ: xoay thường được thực hiện bằng cách sử dụng ma trận (kiểm tra bình luận @MickLH để biết các cách khác để xử lý các phép quay), do đó, để xử lý nhiều biến đổi (xoay / dịch / chia tỷ lệ / chiếu ... vv) theo cách thống nhất, bạn cần mã hóa chúng trong một ma trận.
Vâng, nói nhiều về mặt kỹ thuật; một phép biến đổi đang ánh xạ một điểm / vectơ sang một điểm / vectơ khác.
p` = T(p);
Trong đó p` là điểm biến đổi và T (p) là hàm biến đổi.
Vì chúng ta không sử dụng ma trận, chúng ta cần thực hiện điều này để kết hợp nhiều phép biến đổi:
p1 = T (p);
p cuối cùng = M (p1);
Không chỉ một ma trận có thể kết hợp nhiều loại biến đổi thành một ma trận đơn (ví dụ: affine, tuyến tính, chiếu).
Sử dụng một ma trận cho chúng ta cơ hội để kết hợp các chuỗi biến đổi và sau đó nhân hàng loạt chúng. Điều này giúp chúng tôi tiết kiệm rất nhiều chu kỳ thường bằng GPU (cảm ơn @ChristianRau vì đã chỉ ra nó).
T cuối cùng = T * R * P; // dịch dự án xoay
p chung kết = T cuối cùng * p;
Cũng tốt khi chỉ ra rằng GPU và thậm chí một số CPU được tối ưu hóa cho các hoạt động của vectơ; CPU sử dụng SIMD và GPU là bộ xử lý song song điều khiển dữ liệu theo thiết kế, do đó sử dụng ma trận phù hợp hoàn hảo với khả năng tăng tốc phần cứng (thực tế, GPU được thiết kế để phù hợp với hoạt động của ma trận / vectơ).
Nếu tất cả những gì bạn sẽ làm là di chuyển dọc theo một trục duy nhất và không bao giờ áp dụng bất kỳ chuyển đổi nào khác thì những gì bạn đang đề xuất là ổn.
Sức mạnh thực sự của việc sử dụng ma trận là bạn có thể dễ dàng ghép một chuỗi các hoạt động phức tạp lại với nhau và áp dụng cùng một chuỗi các hoạt động cho nhiều đối tượng.
Hầu hết các trường hợp không đơn giản và nếu bạn xoay đối tượng trước, và muốn chuyển đổi dọc theo trục cục bộ của nó thay vì trục thế giới, bạn sẽ thấy mình không thể thêm 10 vào một trong các số và giải quyết chính xác .
Để trả lời ngắn gọn câu hỏi "tại sao", đó là bởi vì ma trận 4 x 4 có thể mô tả tất cả các thao tác xoay, dịch và chia tỷ lệ cùng một lúc. Có thể mô tả bất kỳ trong số này một cách nhất quán đơn giản hóa rất nhiều thứ.
Các loại biến đổi khác nhau có thể được biểu diễn đơn giản hơn với một phép toán khác nhau. Như bạn lưu ý, dịch thuật có thể được thực hiện chỉ bằng cách thêm. Chia tỷ lệ đồng nhất bằng cách nhân với một vô hướng. Nhưng một ma trận 4x4 được chế tạo phù hợp có thể làm bất cứ điều gì. Vì vậy, việc sử dụng liên tục 4 x 4 giúp mã và giao diện đơn giản hơn nhiều. Bạn phải trả một số phức tạp để hiểu những chiếc xe 4 x 4 này, nhưng sau đó rất nhiều thứ trở nên dễ dàng và nhanh hơn vì nó.
lý do để sử dụng ma trận 4 x 4 là để hoạt động là một phép biến đổi tuyến tính . đây là một ví dụ về tọa độ đồng nhất . Điều tương tự được thực hiện trong trường hợp 2d (sử dụng ma trận 3x3). Lý do sử dụng tọa độ đồng nhất là để có thể thực hiện cả 3 phép biến đổi hình học bằng một thao tác; nếu không, người ta sẽ cần phải thực hiện phép nhân ma trận 3x3 và phép cộng ma trận 3x3 (đối với bản dịch). liên kết này từ cegprakash là hữu ích.
Bản dịch không thể được biểu diễn bằng ma trận 3D
Một đối số đơn giản là bản dịch có thể lấy vectơ gốc:
0
0
0
tránh xa nguồn gốc, nói với x = 1
:
1
0
0
Nhưng điều đó sẽ đòi hỏi một ma trận sao cho:
| a b c | |0| |1|
| d e f | * |0| = |0|
| g h i | |0| |0|
Nhưng điều đó là không thể.
Một đối số khác là định lý Phân rã giá trị số ít , nói rằng mọi ma trận có thể được tạo thành với hai phép quay và một phép chia tỷ lệ. Không có bản dịch ở đó.
Tại sao ma trận có thể được sử dụng?
Nhiều vật thể được mô hình hóa (ví dụ khung xe ô tô) hoặc một phần của các vật thể được mô hình hóa (ví dụ lốp xe hơi, bánh xe lái xe) là chất rắn: khoảng cách giữa các đỉnh không bao giờ thay đổi.
Các phép biến đổi duy nhất mà chúng ta muốn thực hiện đối với chúng là phép quay và bản dịch.
Phép nhân ma trận có thể mã hóa cả phép quay và bản dịch.
Ma trận xoay có các công thức rõ ràng, ví dụ: ma trận xoay 2D cho góc a
có dạng:
cos(a) -sin(a)
sin(a) cos(a)
Có các công thức tương tự cho 3D , nhưng lưu ý rằng các phép quay 3D có 3 tham số thay vì chỉ 1 .
Các bản dịch ít tầm thường hơn và sẽ được thảo luận sau. Chúng là lý do chúng ta cần ma trận 4D.
Tại sao nó là mát mẻ để sử dụng ma trận?
Bởi vì thành phần của nhiều ma trận có thể được tính toán trước bằng cách nhân ma trận .
Ví dụ: nếu chúng ta sẽ dịch một nghìn vectơ v
của khung xe ô tô của mình bằng ma trận T
và sau đó xoay bằng ma trận R
, thay vì thực hiện:
v2 = T * v
và sau đó:
v3 = R * v2
đối với mỗi vector, chúng ta có thể tính toán trước:
RT = R * T
và sau đó thực hiện chỉ một phép nhân cho mỗi đỉnh:
v3 = RT * v
Thậm chí tốt hơn: nếu sau đó chúng ta muốn đặt các đỉnh của lốp xe và bánh xe lái so với xe hơi, chúng ta chỉ cần nhân ma trận trước đó RT
với ma trận so với chính chiếc xe.
Điều này tự nhiên dẫn đến việc duy trì một chồng ma trận:
Cách thêm một chiều giải quyết vấn đề
Chúng ta hãy xem xét trường hợp từ 1D đến 2D để dễ hình dung hơn.
Một ma trận trong 1D chỉ là một số và như chúng ta đã thấy trong 3D, nó không thể dịch, chỉ là một tỷ lệ ..
Nhưng nếu chúng ta thêm kích thước phụ như:
| 1 dx | * |x| = | x + dx |
| 0 1 | |1| | 1 |
và sau đó chúng ta quên đi chiều không gian mới, chúng ta nhận được:
x + dx
như chúng tôi muốn
Phép biến đổi 2D này quan trọng đến mức nó có một tên: phép biến đổi cắt .
Thật tuyệt khi hình dung sự chuyển đổi này:
Lưu ý cách mọi đường ngang (cố định y
) chỉ được dịch.
Chúng tôi chỉ tình cờ lấy dòng y = 1
là dòng 1D mới của mình và dịch nó với ma trận 2D.
Mọi thứ tương tự như 3D, với ma trận cắt 4D có dạng:
| 1 0 0 dx | | x | | x + dx |
| 0 1 0 dy | * | y | = | y + dy |
| 0 0 1 dz | | z | | z + dz |
| 0 0 0 1 | | 1 | | 1 |
Và xoay / thu nhỏ 3D cũ của chúng tôi bây giờ có dạng:
| a b c 0 |
| d e f 0 |
| g h i 0 |
| 0 0 0 1 |
Video hướng dẫn này của Jamie King cũng đáng xem.
Không gian affine
Không gian affine là không gian được tạo bởi tất cả các phép biến đổi tuyến tính 3D của chúng tôi (phép nhân ma trận) cùng với phép cắt 4D (bản dịch 3D).
Nếu chúng ta nhân một ma trận cắt và biến đổi tuyến tính 3D, chúng ta luôn nhận được một cái gì đó có dạng:
| a b c dx |
| d e f dy |
| g h i dz |
| 0 0 0 1 |
Đây là phép biến đổi affine tổng quát nhất có thể, thực hiện xoay / chia tỷ lệ 3D và dịch.
Một thuộc tính quan trọng là nếu chúng ta nhân 2 ma trận affine:
| a b c dx | | a2 b2 c2 dx2 |
| d e f dy | * | d2 e2 f2 dy2 |
| g h i dz | | g2 h2 i2 dz2 |
| 0 0 0 1 | | 0 0 0 1 |
chúng tôi luôn nhận được một ma trận affine khác của hình thức:
| a3 b3 c3 (dx + dx2) |
| d3 e3 f3 (dy + dy2) |
| g3 h3 i3 (dz + dz2) |
| 0 0 0 1 |
Các nhà toán học gọi đóng cửa thuộc tính này và được yêu cầu xác định một khoảng trắng.
Đối với chúng tôi, điều đó có nghĩa là chúng tôi có thể tiếp tục thực hiện các phép nhân ma trận để tính toán các phép biến đổi cuối cùng một cách vui vẻ, đó là lý do tại sao sử dụng ma trận đã sử dụng ở vị trí đầu tiên, mà không bao giờ nhận được các phép biến đổi tuyến tính 4D tổng quát không liên quan.
Frustum chiếu
Nhưng chờ đã, có một biến đổi quan trọng hơn mà chúng ta thực hiện mọi lúc : glFrustum
, làm cho một đối tượng gấp 2 lần, xuất hiện nhỏ hơn gấp 2 lần.
Trước tiên hãy lấy một số trực giác về glOrtho
vs glFrustum
tại: https://stackoverflow.com/questions/2571402/explain-the-usage-of-glortho/36046924#36046924
glOrtho
có thể được thực hiện chỉ với bản dịch + chia tỷ lệ, nhưng làm thế nào chúng ta có thể thực hiện glFrustum
với ma trận?
Giả sử rằng:
z = -1
đó là một hình vuông có chiều dài 2z = -2
Nếu chỉ chúng ta cho phép 4 vectơ tổng quát loại:
(x, y, z, w)
với w != 0
, và ngoài ra, chúng tôi xác định mọi (x, y, z, w)
với (x/w, y/w, z/w, 1)
, sau đó một phép biến đổi với ma trận sẽ là:
| 1 0 0 0 | | x | | x | | x / -z |
| 0 1 0 0 | * | y | = | y | identified to | y / -z |
| 0 0 1 0 | | z | | z | | -1 |
| 0 0 -1 0 | | w | | -z | | 0 |
Nếu chúng ta vứt đi z
và w
cuối cùng, chúng ta sẽ nhận được:
x_proj = x / -z
y_proj = y / -z
đó chính xác là những gì chúng tôi muốn! Chúng tôi có thể xác minh rằng đối với một số giá trị, ví dụ:
z == -1
, chính xác trên máy bay chúng ta đang chiếu x_proj == x
và y_proj == y
.z == -2
, then x_proj = x/2
: các đối tượng có kích thước bằng một nửa.Lưu ý cách glFrustum
biến đổi không phải là dạng affine: nó không thể được thực hiện chỉ với phép quay và dịch.
"Thủ thuật" toán học của việc thêm w
và chia cho nó được gọi là tọa độ đồng nhất
Xem thêm: câu hỏi về Stack Overflow liên quan: https://stackoverflow.com/questions/2465116/under Hiểu-opl -matrices
Xem video này để hiểu các khái niệm về mô hình, xem và chiếu.
Ma trận 4 x 4 không chỉ được sử dụng để dịch một đối tượng 3D. Nhưng cũng cho các mục đích khác nhau.
Xem điều này để hiểu cách các đỉnh trên thế giới được biểu diễn dưới dạng Ma trận 4D và cách chúng được biến đổi.