Hello mụi người, cũng hơn 40 ngày nghỉ tết thì cũng bắt đầu trở lại trường rồi, tranh thủ rảnh rỗi mấy ngày cuối giới thiệu cho mấy bạn thấy được sức mạnh của Tích Vô Hướng chứ thấy mấy bạn if else hơi cực, chưa kể if else mà sai logic thì lại hư các game.
Tích vô hướng cũng chả xa lạ gì đối với các bạn vì nó đã được dạy trong chương trình phổ thông, cụ thể là sách toán lớp 10. Cũng nhớ hồi đó lười học mà tơi chương Vector chả hiểu sao ham học nên giờ cũng còn nhớ sơ sơ :))
Đây là một bài rất nặng lý thuyết, các bạn nhớ trang bị kĩ kiến thức toán khi đọc nhé
Tích vô hướng là cái vẹo gì?
Tích vô hướng (tên tiếng Anh: dot product hoặc scalar product) là một phép toán đại số lấy hai chuỗi số có độ dài bằng nhau (thường là các vectơ tọa độ) và cho kết quả là một số. Trong hình học Euclid, tích vô hướng với tọa độ Descartes của hai vectơ thường được sử dụng. Tích vô hướng cũng thường được gọi là tích trong Euclid dù nó không phải là loại tích trong duy nhất có thể được định nghĩa trong không gian Euclid (xem thêm tại Không gian tích trong). (Theo wikipedia)
Đọc xong cái định nghĩa tắt mẹ cái blog đi ngủ cho khỏe, hù chút thôi chứ mình cũng có hiểu mẹ gì đâu, tuy nhiên phát biểu đại số của nó sẽ dễ hiểu hơn thế này
Ví dụ:
Đây là phát biểu kiểu công thức xưa mình hay dùng. Tuy nhiên đối với mình tích vô hướng là độ lớn của vector VÀ độ lớn của phép chiếu của vector còn lại lên lên nó
được phát biểu công thức dưới dạng
Ứng dụng trong Đường Tròn Lượng Giác
Ứng dụng trong lập trình game
1.Xác định vị trí vật thể
[SerializeField] Transform enemy = default; private void Update() { //DOT PRODUCT Vector2 playerToEnemy = enemy.position - this.transform.position; float dotProduct; //FRONT , BEHIND dotProduct = Vector2.Dot(transform.up, playerToEnemy); if (dotProduct > 0) Debug.Log("Front"); else if (dotProduct < 0) Debug.Log("Behind"); else Debug.Log("Middle"); //LEFT , RIGHT dotProduct = Vector2.Dot(transform.right, playerToEnemy); if (dotProduct > 0) Debug.Log("Right"); else if (dotProduct < 0) Debug.Log("Left"); else Debug.Log("Middle"); }
2.Điều chỉnh âm thanh khi va chạm
Vấn đề là khi player va chạm với một vật thể nào đó, để chân thật nhất chúng ta phải tính volume sao cho to nhỏ hợp lý với lực tác động.
Trong hình trên, hình tròn là player, di chuyển với v = 10m/s hướng xuống đất.
Nhiều bạn nhanh lẹ sẽ suy nghĩ rằng. Đặt volume = độ lớn vận tốc. Ok tạm chấp nhận được, nhưng hay xét đến trường hợp dưới đây

Trong TH2 ta thấy quả bóng gần như là chạm mặt đất nhưng vẫn di chuyển với v = 10 m/s. => Khi chạm đất volume nó sẽ ngang quả bóng thả thẳng từ trên cao xuống => sai logic
Dot Product sẽ hỗ trợ ta giải quyết chuyện này nhanh gọn, xem hình dưới đây (Lưu ý: vector hướng mình vẽ là vector vận tốc (v) đấy nhé)
Chỉ cần lấy Dot Product giữa Vector vận tốc và vector hướng lên (Vector2.Up) là xong => Dot Product = khoảng cách màu đỏ như hình vẽ (do Vector2.Up có độ lớn = 1)
Đây là cách mà mình Implement
[SerializeField] AudioSource _audio; [SerializeField] Rigidbody2D _rig; private void OnValidate() { _audio = GetComponent<AudioSource>(); _rig = GetComponent<Rigidbody2D>(); } private void OnCollisionEnter2D(Collision2D collision) { _audio.volume = Mathf.Abs(Vector2.Dot(transform.up, _rig.velocity))/ 10f; _audio.Play(); }
Tổng kết
Sức mạnh của Dot Product vẫn còn rất nhiều, đó là mình chỉ demo sơ sơ cho bạn xem thôi đó. Đại đa số các game developer tận dụng sức mạnh của Dot Product rất triệt để. Oke, bài này hơi nặng lý thuyết nhưng mong các bạn cố hiểu và nếu có gì thắc mắc nhớ để lại comment để mình giải đáp nhé.

Một trang hữu ích ad ạ. Uptade thêm vè des game online thì good
Trả lờiXóaCảm ơn bạn, tương lai chắc chắn sẽ có nhé :v
Xóa