Làm cách nào để sử dụng dấu chấm để có góc giữa hai vectơ?


16

Tôi đang học cách sử dụng các vectơ chuẩn hóa trong các trò chơi của mình.

Tôi đã học được rằng để biết góc giữa hai vectơ, tôi có thể sử dụng sản phẩm chấm. Điều này mang lại cho tôi một giá trị giữa -1 và 1, trong đó

  • 1 có nghĩa là các vectơ song song và cùng hướng (góc là 180 độ).
  • -1 có nghĩa là chúng song song và hướng ngược nhau (vẫn 180 độ).
  • 0 có nghĩa là góc giữa chúng là 90 độ.

Tôi muốn biết làm thế nào để chuyển đổi sản phẩm chấm của hai vectơ, thành một góc thực tế theo độ. Ví dụ: nếu tích của hai vectơ là 0.28góc tương ứng, giữa 0 và 360 độ là gì?


1
Lưu ý rằng mục đích sử dụng sản phẩm chấm của bạn chỉ hoạt động khi các vectơ ban đầu là vectơ đơn vị.
sam hocevar

@SamHocevar Vâng, đó là những gì tôi muốn nói.
dùng3150201


1
@ user3150201 Câu trả lời của Alex là chính xác, nhưng bạn cũng nên xem xét liệu bạn có cần lấy góc thực tế theo độ không. Trường hợp duy nhất mà tôi có thể nghĩ ra khi điều này thực sự cần thiết là hiển thị thứ gì đó theo độ trên UI. Mặt khác, có thể có một vài ứng dụng mà bạn không thể làm việc trực tiếp với sin và cosin.
TravisG

Câu trả lời:


22

dot(A,B) = |A| * |B| * cos(angle)
có thể được sắp xếp lại
angle = arccos(dot(A,B) / (|A|* |B|)).

Với công thức này, bạn có thể tìm góc nhỏ nhất giữa hai vectơ, sẽ nằm trong khoảng từ 0 đến 180 độ. Nếu bạn cần nó trong khoảng từ 0 đến 360 độ , câu hỏi này có thể giúp bạn.


Nhân tiện, góc giữa hai vectơ song song cùng hướng phải là 0 độ chứ không phải 180.


+1 cho "Nhân tiện, góc giữa hai vectơ song song cùng hướng phải là 0 độ, không phải 180."
Tara

8

Tôi sẽ mở rộng một chút về nhận xét của TravisG và đưa ra một câu trả lời khác, sử dụng thực tế là câu hỏi của bạn có thẻ "2D".

Bạn có thể lấy góc giữa hai vectơ bằng cách sử dụng sản phẩm chấm, nhưng bạn không thể lấy góc đã ký giữa hai vectơ bằng cách sử dụng nó. Nói cách khác, nếu bạn muốn biến một nhân vật theo thời gian về một điểm, sản phẩm chấm sẽ giúp bạn có bao nhiêu để rẽ nhưng không phải là hướng nào. Có một công thức đơn giản khác, tuy nhiên, rất hữu ích khi kết hợp với sản phẩm chấm. Bạn không chỉ có

dot(A,B) = |A| * |B| * cos(angle)

Bạn cũng có thể có một công thức khác (tên mà tôi đã tạo nên cho chính xác):

pseudoCross(A,B) = |A| * |B| * sin(angle)

trong đó nếu A = (a, b), B = (x, y), thì pseudoCross (A, B) được xác định là thành phần thứ ba của sản phẩm chéo (a, b, 0) x (x, y, 0 ). Nói cách khác:

a*x+b*y = |A| * |B| * cos(angle)

-b*x+a*y = |A| * |B| * sin(angle)

Góc được ký đầy đủ là sau đó angle=atanfull(-b*x+a*y,a*x+b*y)(các hàm atanfull hoặc atan2 tha thứ cho bạn nếu bạn chuyển các giá trị không chuẩn hóa). Nếu A và B được chuẩn hóa, nghĩa là, nếu |A|=|B|=1, đây đơn giản là:

a*x+b*y = cos(angle)

-b*x+a*y = sin(angle)


Để giải thích sâu hơn, lưu ý rằng các phương trình trên có thể được biểu thị bằng phương trình ma trận:

[ a,b]   [x]   [cos(angle)]
[-b,a] * [y] = [sin(angle)]

Nhưng a và b có thể được diễn tả như a=cos(ang1), b=sin(ang1), đối với một số giá trị ang1(không angle). Do đó, ma trận bên trái là ma trận xoay làm cho vectơ (x, y) theo số lượng -ang1. Điều này tương đương với việc chuyển sang một khung tham chiếu trong đó vectơ đơn vị "A" được coi là vectơ / trục (1,0)! Vì vậy, chỉ bằng cách vẽ vòng tròn đơn vị / tam giác vuông trong khung này, bạn có thể thấy tại sao vectơ kết quả của sản phẩm đó là (cos (angle), sin (angle)).

Nếu bạn viết (a, b) và (x, y) ở dạng cực, và áp dụng các công thức sai lệch góc cos(l)*cos(m)+sin(l)*sin(m)=cos(l-m)sin(l)*cos(m)-cos(l)*sin(m)=sin(l-m), bạn thể hiện lại rằng các sin / cosin được đưa ra bởi sản phẩm này, vì (lm) = angle. Ngoài ra, những nhận dạng đó có thể được sử dụng để xem lý do tại sao sản phẩm tuyến tính được đưa ra ở trên xoay một vectơ.

Tất cả những đặc điểm này có nghĩa là bạn hiếm khi cần góc. Bởi vì các góc có thể kỳ lạ - radian / độ, quy ước cho sin / cosine nghịch đảo, thực tế là chúng lặp lại sau mỗi 2 * pi - điều này thực sự có thể hữu ích hơn và tiết kiệm cho bạn một loạt logic "if (ang <180)".

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.