Game Và Đại Số Tuyến Tính: You Just Got Vectored
Đây sẽ là một bài hướng dẫn và giới thiệu về toán học đại số mang tính thực tiễn bằng cách áp dụng nó trong việc phát triển trò chơi điện tử. Đại số tuyến tính là một môn nghiên cứu về vector và tính ứng dụng của chúng. Vector có rất nhiều ứng dụng trong cả phát triển trò chơi 2D và 3D, vì thế việc có những hiểu biết nhất định là thực sự cần thiết
Việc học tốt toán vector cũng là một nhân tố quan trọng trong việc phát triển sự nghiệp trò chơi điện tử của chính bạn
Hướng dẫn lần này không phải là một khoá học chính thức về toán đại số. Chúng ta sẽ chỉ nhìn vào khía cạnh làm thế nào để áp dụng nó vào phát triển trò chơi điện tử. Để có một cái nhìn toàn diện hơn về môn toán đại số tuyến tính, hãy tham khảo khoá học linear algebra
Hệ toạ độ(2D)
Trong không gian 2D, toạ độ được định nghĩa bằng việc sử dụng trục hoành(x
) và trục tung(y
). Toạ độ cụ thể trong không gian 2D được thể hiện dưới dạng một cặp giá trị (4,3)
Nếu như bạn là người mới tìm hiểu về đồ hoạ máy tính, thì trông sẽ khá là kì quặc khi chiều dương của trục tung
y
lại chỉ xuống dưới thay vì chỉ lên trên, chẳng hề giống như bạn vật lộn với toán vector trên lớp đại học :<. Tuy nhiên, đây lại là tiêu chuẩn trong hầu hết các ứng dụng đồ hoạ máy tính
Bất kì vị trí nào trên mặt phẳng 2D đều có thể được xác định bởi cặp một cặp số bằng cách này. Tuy nhiên, chúng ta cũng có thể nghĩ rằng vị trí (4,3)
giống như một phép bù khỏi toạ độ (0,0)
, hay gốc toạ độ. Hãy vẽ một mũi tên từ gốc toạ độ đến điểm được xác định như sau:
Đây chính là vector. Một vector có thể thể hiện rất nhiều thông tin giá trị, cũng như cho chúng ta biết được toạ độ xác định ở (4,3)
, hoặc chúng ta có thể nghĩ đến nó như một góc θ
hay độ lớn(magnitude) m
nào đó. Trong trường hợp này, mũi tên chính là vector vị trí - nó biểu thị một vị trí trong không gian, tương quan với gốc toạ độ.
Một điểm vô cùng quan trọng khi nghĩ đến các vector chính là việc nó chỉ biểu diễn hướng và độ lớn một cách tương đối. Không hề có khái niệm nào trong toán học biểu thị vị trí vector. Và hai vector sau là tương đương nhau:
Cả hai vector đều biểu diễn một điểm hướng 4 đơn vị về bên phải và 3 đơn vị xuống bên dưới tính từ điểm bắt đầu. Nó chả quan tâm bạn vẽ cái vector đó ở đâu trên mặt phẳng, nó sẽ luôn đại diện cho một hướng tương đối và độ lớn của chính vector đó.
Các phép tính toán vector
Phép cộng vector
Khi chúng ta cộng hoặc trừ hai vector, thì phép tính sau sẽ được thực thi
Ví dụ
Cho hai vector a = (2,5) và b = (3,1). Vector c là tổng của hai vector a và b sẽ có giá trị là:
c = a + b = (2, 5) + (3, 1) = (5, 6)
Ở hình minh hoạ dưới đây ta có thể thấy rằng phép cộng được thực hiện bằng cách thêm vector thứ hai vào phần cuối của vector thứ nhất:
Việc thực hiện phép cộng
a + b
sẽ có cùng giá trị vớib + a
Nhân chia vector
Các vector đều được biểu diễn bằng cả hướng và độ lớn. Còn một giá trị mà chỉ biểu diễn mỗi độ lớn sẽ được gọi là giá trị vô hướng(scalar)
Một vector có thể được nhân hoặc chia bởi một giá trị vô hướng:
c = a * 2 = (2, 5) * 2 = (4, 10)
d= b / 3 = (3, 6) / 3 = (1, 2)
Việc thực hiện phép nhân giữa một vector và một giá trị vô hướng sẽ không làm thay đổi hướng của nó, mà chỉ thay đổi độ lớn. Đây chính là cách bạn làm lớn-thu nhỏ(scale) một vector
Các ứng dụng thực tiễn
Hãy nhìn vào các ứng dụng căn bản của phép cộng và trừ vector dưới đây
Chuyển động
Một vector có thể biểu diễn bất kì giá trị định lượng nào với độ lớn và hướng. Các ví dụ thông thường sẽ là: vị trí, vector vận tốc, gia tốc và trọng lực. Trong hình dưới đây, chiếc phi thuyền ở bước 1 có một vector vị trí (1,3)
và một vector vận tốc (2,1)
. Vector vận tốc ở đây sẽ đại diện cho khoảng cách chiếc tàu di chuyển mỗi bước. Chúng ta có thể tìm thấy vị trí của bước 2 bằng cách thêm vào vector vận tốc vào vị trí hiện tại của tàu
pos2: vị trí tàu ở bước hai
pos: vị trí hiện tại(tức bước 1)
vel: vecto vận tốc đưa tàu từ vị trí 1 sang vị trí 2
Vector vận tốc tính toán sự thay đổi vị trí trên từng đơn vị theo thời gian. Vị trí mới được thể hiện bằng cách cộng vector vận tốc vào vị trí trước đó
Chỉ điểm về phía một mục tiêu
Trong khung cảnh giả định này, bạn có một chiếc xe tăng đang muốn hướng cái nòng đạn của nó vào con robot. Việc sử dụng phép trừ vị trí của chiếc xe tăng với vị trí của con robot sẽ tạo ra một vector chỉ thẳng từ chiếc xe tăng đến con robot
Để tìm một vector chỉ từ
A
đếnB
hãy dùngB - A
Vector đơn vị
Một vector có độ lớn bằng 1 sẽ được gọi là vecto đơn vị. Chúng cũng thường xuyên được gọi bởi một vài cái tên khác như là vector định hướng hay vector chuẩn hoá. Các vector đơn vị sẽ vô cùng hữu ích khi bạn cần phải theo dõi các nhân tố về định hướng.
Chuẩn hoá
Việc chuẩn hoá một vector chính là việc giảm độ dài của nó về 1 trong khi giữ nguyên hướng hiện tại của nó. Nó được thực thi bằng cách chia mỗi phần của vector cho chính độ dài của nó.
Ví dụ:
Chuẩn hoá vector a = (3,4)?
Với a = (3,4) tương đương với x
= 3 và y
= 4
Độ lớn vector a tính toán được là:
||a|| = √(32+42)= 5
Trong đó || a || chính là độ lớn m
của vector a
Từ đó ta có vecto achuẩn hoá = (3/5, 4/5)
Bởi vì việc chuẩn hoá vector liên quan đến phép chia cho độ dài vector, bạn không thể chuẩn hoá một vector có độ dài là
0
. Việc cố tình thực hiện điều đó sẽ khiến cho kết quả của bạn bị lỗi
Phép chiếu
Một trọng những ứng dụng căn bản của vector đơn vị là để biểu thị các vector chuẩn hoá. Các vector này thường là các vector đơn vị được chiếu thẳng hàng vuông góc với bề mặt mà nó bắt đầu, nhằm thể hiện hướng của nó. Nó thường được dùng trong việc thể hiện ánh sáng, các va chạm và các phép toán liên quan tới các bề mặt.
Trong ví dụ sau đây, hãy tưởng tượng bạn có một quả bóng chuyển động mà chúng ta muốn nó nảy khỏi bức tường hoặc một vật thể khác:
remaining motion: Hướng chuyển động hiện tại
normal: vector chuẩn hoá
reflect: phép chiếu của nó
Vecto chuẩn hoá của bề mặt hiện tại có giá trị là (0,-1)
bởi vì đây là mặt phẳng nằm ngang. Khi quả bóng va chạm, thì chúng ta sẽ lấy vector chuyển động dư của quả bóng(giá trị còn lại sau khi nó va vào mặt phẳng) sau đó phản xạ nó bằng cách dùng vector chuẩn hoá. Để tham khảo thêm về bài toán phản xạ này, mọi người có thể tham khảo tại đường link dưới đây:
How to get a reflection vector?
Tích vô hướng (dot product)
Tích vô hướng chính là một trong những chủ đề quan trọng trong toán vector, nhưng lại thường xuyên bị hiểu sai. Tích vector là một phép toán trên hai vector mà trả về một giá trị vô hướng. Không giống như vector, đại lượng mà bao gồm trong nó cả độ lớn và hướng, một giá trị vô hướng chỉ bao gồm trong đó là độ lớn
Công thức tính toán tích vô hướng có thể được thể hiện bằng 2 cách:
A · B = || A || || B || cosθ
và
A · B = AxBx+AyBy
Việc tính toán tích vô hướng sẽ hữu dụng nhất khi sử dụng các vector đơn vị, khiến cho công thức đầu tiên có thể được rút còn chỉ mỗi cosθ
. Điều này có nghĩa là chúng ta có thể sử dụng tích vô hướng để cho chúng ta biết một vài điều gì đó về góc giữa hai vector:
Ở đây
a.dot(b)
chính là tượng chưng về mặt code cho phép tích vô hướng của hai vector a và b
Khi ta sử dụng các vector đơn vị, thì kết quả trả về sẽ luôn luôn ở giữa -1
(180°) và 1
(0°).
Đối mặt
Chúng ta có thể sử dụng chính vector vô hướng đó để xác định liệu rằng một vật thể có đang đối mặt với một vật thể khác. Trong hình minh hoạ dưới dây, người chơi P
đang cố gắng tránh khỏi con zombie A
và B
. Giả sử rằng khu vực có thể nhìn thấy của zombie là 180°, liệu rằng nó có thể nhìn thấy người chơi?
Những mũi tên màu xanh fA
và fB
đều là các vector đơn vị đại diện cho hướng đối mặt của zombie và cái khu nửa hình tròn màu xanh kia đại diện cho tầm nhìn của nó. Với zombie A
, chúng ta sẽ đi tìm vector hướng AP
chỉ về phía người chơi bằng cách sử dụng P - A
và rồi chuẩn hoá nó. Nếu như góc giữa vector này và vector đối mặt nhỏ hơn 90°, thì con zombie sẽ thấy người chơi.
Tích vector(cross product)
Giống như tích vô hướng, thì tích vector là một phép tính trên 2 vector. Tuy nhiên, kết quả của phép tích vector là một vector với hướng là một vector vuông góc với cả hai vector còn lại. Độ lớn của nó sẽ phụ thuộc vào góc tương ứng. Nếu như 2 vector song song với nhau, thì kết quả của tích vector sẽ là một vector lỗi(null vector)
|| a x b || = || a || || b || |sin(a,b)|
Giá trị của tích vector sẽ được tính toán như sau
Với vector c là tích của hai vector a và b ta có:
cx = (ay * bz) - (az * by)
cy = (az * bx) - (ax * bz)
cz = (ax * by) - (ay * bz)
Trong tích vector, thì thứ tự lại là một yếu tố quan trọng. Việc
||a x b||
hay||b x a||
sẽ không có cùng kết quả với nhau. Mà theo đó các vector kết quả đều sẽ chỉ theo các hướng ngược nhau.
Tính toán các vector chuẩn hoá
Một ứng dụng cơ bản của việc tính tích vector chính là để tìm mặt phẳng chuẩn hoá của một mặt cắt hay mặt phẳng trong không gian 3D. Nếu như chúng ta có tam giác ABC
chúng ta có thể sử dụng phép hiệu vector để tìm 2 cạnh AB
và AC
. Sử dụng phép nhân vector, AB x AC
sẽ cho ra một vector vuông góc với cả hai: mặt phẳng chuẩn hoá.
Chỉ định đến một mục tiêu
Ở phần tích vô hướng ở trên, chúng ta có thể thấy cách nó được sử dụng để tìm góc giữa 2 vector. Tuy nhiên, trong 3D, thì từng đó là chưa đủ thông tin. Chúng ta còn cần phải biết trục nào để xoay quanh nữa. Chúng ta có thể tìm nó bằng cách tính toán tích vector của hướng đối mặt hiện thời và hướng mục tiêu. Cái vector vuông góc kết quả đó sẽ chính là trục xoay.
Tham khảo
Đây là bản dịch không chuyên tiếp theo được lấy từ phần docs của godot, để tìm hiểu thêm về bản gốc và engine godot hãy tham khảo đường link sau:
Vector math - Godot Engine (stable) documentation in English