Tìm hiểu về Quaternion trong Unity

Posted by Giap Nguyen on 2020-03-22

Đối với nhiều lập trình viên thì khái niệm Quaternion khá xa lạ, tuy nhiên trong Unity3D thì đây là một khái niệm cực kì quan trọng.

Khái niệm

Quaternion là một loại dữ liệu được sử dụng để biểu diễn vị trí và hướng của các đối tượng trong không gian ba chiều (3D) trong Unity. Điều này giúp đối tượng di chuyển và xoay một cách linh hoạt và chính xác hơn so với sử dụng các giá trị hướng và vị trí thông thường.

Trong Unity, Quaternion được sử dụng để biểu diễn hướng quay của đối tượng. Quaternion bao gồm bốn giá trị số thực: w, x, y, z. Giá trị w là phần thực của Quaternion và các giá trị x, y, z là phần ảo của Quaternion. Giá trị w luôn phải là giá trị dương để Quaternion được chính xác.

Các phép toán quay của Quaternion được thực hiện bằng cách sử dụng các hàm và toán tử trong Unity. Ví dụ, để quay một đối tượng trong Unity, chúng ta có thể sử dụng hàm Quaternion.Euler, hàm này trả về một Quaternion mới từ các giá trị Euler (góc quay) của đối tượng. Để lấy vị trí và hướng của một đối tượng trong không gian, chúng ta có thể sử dụng các thuộc tính Transform.positionTransform.rotation của đối tượng.

Quaternion cũng có thể được sử dụng để lưu trữ các góc quay của các đối tượng, giúp cho các đối tượng được di chuyển và xoay linh hoạt hơn trong không gian 3D. Tuy nhiên, việc sử dụng Quaternion cũng có thể phức tạp hơn so với sử dụng các giá trị vị trí và hướng thông thường, vì nó liên quan đến toán học 4 chiều.

Tóm lại, Quaternion là một loại dữ liệu quan trọng trong Unity để biểu diễn vị trí và hướng của các đối tượng trong không gian 3D. Chúng được sử dụng để thực hiện các phép toán quay của đối tượng, giúp cho các đối tượng có thể di chuyển và xoay linh hoạt hơn.

Chúng ta có thể biểu diễn phép quay Quaternion bằng công thức sau:

1
Q = m + ax + by + cz

với m, a, b, c là các số thực và x, y, z thể hiện đơn vị cơ bản của 3 trục toạ độ xyz.
Trong Unity gần như bạn không bao giờ thay đổi gía trị (a, b, c, m) một cách độc lập mà thường sẽ khởi tạo một phép quay mới từ đối tượng đã tồn tại (ví dụ từ Transform của một GameObject). Những tính năng của class Quaternion được sử dụng thường xuyên nhất (chắc đến 99% các trường hợp sử dụng) là:  Quaternion.LookRotation, Quaternion.Angle, Quaternion.Euler, Quaternion.Slerp, Quaternion.FromToRotation, and Quaternion.identity. Tôi sẽ nói về cách sử dụng cụ thể của từng function này ở phía dưới. (~_~)

Các thuộc tính, phương thức cơ bản

Static Properties

identity: trả về object với ý nghĩa no rotation so với the world of parent axis (thực sự không biết dịch sang tiếng Việt như thế nào)

Properties

eulerAngles: Returns or sets the euler angle representation of the rotation.

normalized: Returns this quaternion with a magnitude of 1 (Read Only).

this[int]: Access the x, y, z, w components using [0], [1], [2], [3] respectively.

Static Methods

LookRotation

Hàm LookRotation sẽ tạo ra một phép quay với hướng xác định, giá trị trả về là một Quaternion. Định nghĩa hàm như sau:

1
public static Quaternion LookRotation(Vector3 forward, Vector3 upwards = Vector3.up);

Trong đó forward là một Vector3 được sử dụng để xác định hướng quay của đối tượng. Trục z của đối tượng sẽ trùng với hướng quay. Tham số upwards nhận giá trị mặc định là Vector3.up, nghĩa là trục y của đối tượng sẽ hướng lên trên so với forward.

Angle

Trả về một góc tính bằng độ (degree) là góc giữa hai Quaternion. Công thức tính này khá phức tạp và dựa trên cơ sở toán học, nếu bạn quan tâm thì có thể tham khảo thuật toán này ở https://en.wikipedia.org/wiki/Quaternion

Định nghĩa của hàm như sau

1
public static float Angle(Quaternion q1, Quaternion q2);

Euler

Thao tác với Quaternion qua 4 thuộc tính x, y, z, m là một việc cực kì khó, khó ở chỗ chúng ta không tưởng tượng được điều gì xảy ra khi thay đổi chúng. Do đó Unity cung cấp cho chúng ta một hàm giúp ta thao tác và điều chỉnh góc quay của đối tượng thông qua chính ba trục toạ độ của đối tượng đó. Cú pháp của hàm này như sau

1
public static Quaternion Euler(float x, float y, float z);

Trong đó x, y, z là ba góc quay tương ứng với ba trục toạ độ của đối tượng. Đơn vị của các góc quay là độ (degree)

Lerp - Slerp

LerpSlerp là hai hàm nội suy phép quay giữa hai Quaternion và hiển thị việc quay ra màn hình theo thời gian. Cách sử dụng và chức năng của hai hàm là tương tự nhau:

1
2
public static Quaternion Slerp(Quaternion from, Quaternion to, float t);
public static Quaternion Lerp(Quaternion from, Quaternion to, float t);

Với các phép quay lớn, góc quay rộng thì hàm Lerp sẽ cho chất lượng hiển thị kém hơn Slerrp, hay một từ gần gũi hơn là mượt hơn :)) . Nhưng bù lại thì Lerp sẽ nhanh hơn do không thực hiện phép nội suy một cách phức tạp. Các bạn có thể tự tạo demo với 2 hàm trên để cảm nhận nhé.

Với các phép quay lớn, góc quay rộng thì hàm Lerp sẽ cho chất lượng hiển thị kém hơn Slerrp, hay một từ gần gũi hơn là mượt hơn :)) . Nhưng bù lại thì Lerp sẽ nhanh hơn do không thực hiện phép nội suy một cách phức tạp. Các bạn có thể tự tạo demo với 2 hàm trên để cảm nhận nhé.

Áp dụng

Để sử dụng Quaternion trong Unity 3D, bạn có thể làm theo các bước sau:

  1. Khởi tạo một Quaternion: Bạn có thể khởi tạo một Quaternion bằng cách sử dụng hàm Quaternion() để tạo ra một Quaternion rỗng hoặc sử dụng hàm Quaternion.identity để tạo ra một Quaternion với giá trị mặc định là (0, 0, 0, 1).
1
Quaternion rotation = new Quaternion();
  1. Sử dụng hàm Quaternion.Euler để tạo một Quaternion từ các giá trị Euler (góc quay) của đối tượng:
1
Quaternion rotation = Quaternion.Euler(x, y, z);
  1. Đặt hướng quay cho một đối tượng bằng cách sử dụng thuộc tính transform.rotation:
1
transform.rotation = rotation;
  1. Thực hiện các phép toán quay với Quaternion:
  • Hàm Quaternion.AngleAxis: tạo một Quaternion từ một góc và một trục quay:
1
Quaternion rotation = Quaternion.AngleAxis(angle, axis);
  • Hàm Quaternion.LookRotation: tạo một Quaternion từ vị trí và hướng nhìn của đối tượng:
1
Quaternion rotation = Quaternion.LookRotation(direction, up);
  • Các phép toán nhân và chia của Quaternion:
1
2
Quaternion result = quaternion1 * quaternion2;
Quaternion inverse = Quaternion.Inverse(quaternion);
  1. Sử dụng các thuộc tính của Quaternion để lấy thông tin về vị trí và hướng của đối tượng:
1
2
3
4
float x = transform.rotation.x;
float y = transform.rotation.y;
float z = transform.rotation.z;
float w = transform.rotation.w;

Quaternion là một công cụ rất hữu ích trong Unity 3D để thực hiện các phép toán quay và lưu trữ vị trí và hướng của các đối tượng trong không gian 3 chiều.

Tài liệu tham khảo

Đây là một số tài liệu tham khảo về Quaternion trong Unity:

  1. Unity Documentation: https://docs.unity3d.com/ScriptReference/Quaternion.html

  2. Quaternion Explained: https://www.youtube.com/watch?v=SCbpxiCN0U0

  3. Quaternions and rotation sequences: https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm

  4. Unity Quaternion and Rotation Basics: https://www.youtube.com/watch?v=6wS5bZDiVlY

  5. Unity Quaternion Tutorial: https://www.youtube.com/watch?v=jOzP6n8Uapw

  6. Understanding Quaternions: A Visual Explanation with Code: https://www.youtube.com/watch?v=mHVwd8gYLnI

Các tài liệu này cung cấp cho bạn các kiến thức cơ bản và nâng cao về Quaternion trong Unity, từ cách tạo ra Quaternion cho đến cách sử dụng nó để thực hiện các phép toán quay và lưu trữ vị trí và hướng của các đối tượng trong không gian 3 chiều.