Atan và atan2 được sử dụng trong các trò chơi là gì?


48

Tôi gặp một số khó hiểu Math.tan()Math.atan()Math.atan2().

Tôi có kiến ​​thức cơ bản về lượng giác nhưng việc sử dụng SIN, COS và TAN, vv để phát triển trò chơi là rất mới đối với tôi.

Tôi đang đọc một số hướng dẫn và tôi thấy rằng bằng cách sử dụng tiếp tuyến, chúng ta có thể có được góc trong đó một đối tượng cần được xoay theo mức độ đối diện với một đối tượng khác, ví dụ chuột của tôi. Vậy tại sao chúng ta vẫn cần sử dụng atan hoặc atan2?


atan được sử dụng để xác định góc, hữu ích cho hàng ngàn thứ khác nhau. Bạn có một câu hỏi thực tế về việc sử dụng nó, hoặc bạn chỉ đang tìm kiếm sự giúp đỡ toán học nói chung?
BlueRaja - Daniel Pflughoeft

5
Bạn chắc chắn cần phải hiểu toán học / hình học đằng sau các chức năng đó; một khi bạn thành thạo chúng, chúng sẽ trở thành một phần trong "sự hiểu biết thế giới" của bạn, giống như ngữ pháp cơ bản bạn sử dụng hàng ngày để nói. Khi bạn có thể "nói toán học / hình học", bạn sẽ thấy các hàm đó là các công cụ mô phỏng để đạt được kết quả, sử dụng tự nhiên nhất.
FxIII

Những hướng dẫn đó là sai hoặc bạn hiểu lầm. Bạn sử dụng atan2 () để lấy góc từ vật này sang vật khác. Làm thế nào mà hoạt động được giải thích dưới đây.
jhocking

cảm ơn mọi người vì câu trả lời, bây giờ tôi đang hối hận vì đã không chú ý nhiều hơn trong lớp
sutoL

Câu trả lời:


94

Công thức tiếp tuyến là thế này:

tan(angle) = opposite/adjacent

Tham khảo bản vẽ này:

Sơ đồ của một tam giác vuông góc, với một góc theta và các cạnh đối diện và liền kề của nó được đánh dấu

Trường hợp alà cạnh bên, olà phía đối diện và thetalà góc. Tương tự, sin và cosine là sin (ang) = o / h và cos (ang) = a / h trong đó hlà cạnh dài: http://www.mathwords.com/s/sohcahtoa.htmlm

Trong khi đó atan(viết tắt của tiếp tuyến vòng cung , còn được gọi là tiếp tuyến nghịch đảo ) là mặt trái của tan, như vậy:

atan(opposite/adjacent) = angle

Do đó, nếu bạn biết các giá trị của cả hai mặt đối diện và liền kề (ví dụ: bằng cách trừ tọa độ của đối tượng khỏi tọa độ chuột), bạn có thể nhận được giá trị của góc atan.

Tuy nhiên, trong phát triển trò chơi, có thể xảy ra khá thường xuyên rằng cạnh bên bằng 0 (ví dụ tọa độ x của vectơ là 0). Hãy nhớ rằng tan(angle) = opposite/adjacentkhả năng xảy ra lỗi chia nhỏ bằng 0 có thể xảy ra. Vì vậy, rất nhiều thư viện cung cấp một hàm được gọi atan2, cho phép bạn chỉ định cả tham số xytham số, để tránh chia cho 0 cho bạn và đưa ra một góc trong góc phần tư bên phải.

sơ đồ atan2

(sơ đồ lịch sự của gareth, xin vui lòng bỏ phiếu cho câu trả lời của anh ấy quá)


Việc sử dụng lượng giác trong phát triển trò chơi là khá phổ biến, đặc biệt là với các vectơ, nhưng thông thường các thư viện ẩn công việc lượng giác cho bạn. Bạn có thể sử dụng sin / cos / tan cho nhiều tác vụ liên quan đến các thao tác hình học để tìm giá trị từ một hình tam giác. Tất cả những gì bạn cần là 3 giá trị (độ dài cạnh / giá trị góc) để tìm các giá trị khác của tam giác hình chữ nhật, vì vậy nó khá hữu ích.

Bạn thậm chí có thể sử dụng tính chất "đạp xe" của các hàm sin và cos cho các hành vi đặc biệt trong trò chơi, ví dụ: Tôi đã thấy cos / sin sử dụng rất nhiều để làm cho một vật thể quay xung quanh một vật khác.


8
Wikipedia đáng chú ý mô tả các cách sử dụng khác cho Atan2 ( không phải atan) hơn là chỉ tránh việc chia cho số không. Chẳng hạn, nó tự sửa cho góc phần tư đang được sử dụng, thông thường bạn phải tự làm tất cả.
doppelgreener

Thật vậy, lưu ý rất quan trọng ngay tại đó. Cập nhật câu trả lời của tôi.
Jesse Emond

Không phải bạn đã bị tan và atan ngược trong đoạn dài đầu tiên của bạn? Bạn sẽ sử dụng atan để lấy góc (nghĩa là đảo ngược phương trình) và tan để lấy tỷ lệ của các cạnh (nghĩa là chính xác những gì phương trình nói).
jhocking

Chà, nếu bạn biết o / a bằng với 3, thì nếu bạn muốn góc bạn làm atan (3), đó là điều tôi muốn nói: nếu bạn muốn tách góc, bạn sử dụng atan theo tỷ lệ. Nếu bạn muốn cô lập tỷ lệ, bạn sử dụng tan trên góc.
Jesse Emond

Tôi sẽ thay đổi từ ngữ của bạn sau đó, vì có vẻ như bạn đang nói ngược lại.
jhocking

64

nhập mô tả hình ảnh ở đây


1
Nó sẽ là bất lịch sự để chỉnh sửa câu trả lời hàng đầu để có sơ đồ này trong đó? Sơ đồ này là tuyệt vời và sẽ phù hợp ngay sau khi giải thích bằng văn bản của Jesse về atan2 ().
jhocking

1
Đi trước: làm khách của tôi! Tôi sẽ xóa câu trả lời này sau khi bạn hoàn thành.
Gareth Rees

7
Không không. Giữ nó lên! Nó được ghi có và mọi người vẫn nên upvote ở đây cho sơ đồ.
Jesse Emond

12

Đây là một cách nghĩ hơi khác về các hàm trig - bao gồm atan () và atan2 () - mà tôi thấy hữu ích (giải thích theo nghĩa "đối diện / liền kề" chỉ khiến tôi bối rối vì một số lý do).

x, y, r, theta

Bạn có thể nhận được từ một trong những điểm đến khác bằng cách di chuyển x đơn vị theo chiều ngang và y đơn vị theo chiều dọc (gọi là hình chữ nhật hoặc Descartes tọa độ) hoặc bằng cách di chuyển khoảng cách r ở một góc Ɵ (gọi là cực tọa độ 2D).

Giả sử chúng ta có tọa độ cực (r, Ɵ) và chúng ta muốn chuyển đổi nó thành (x, y).

cos (Ɵ) cung cấp cho bạn tỷ lệ r nằm dọc theo trục x :

  • Nếu r = 1 thì x = cos (Ɵ).
  • Nếu r = 100 thì x = 100 * cos (Ɵ).
  • Nói chung x = r * cos (Ɵ).

Tương tự như vậy sin (Ɵ) cung cấp cho bạn tỷ lệ r nằm dọc theo trục y :

  • Nếu r = 1 thì y = sin (Ɵ).
  • Nếu r = 100 thì y = 100 * sin (Ɵ).
  • Nói chung y = r * sin (Ɵ).

Làm thế nào về việc chuyển đổi tọa độ hình chữ nhật (x, y) thành tọa độ cực (r,)?

r là cạnh huyền của tam giác vuông được tạo bởi xy , do đó:

  • r = sqrt (x x + y y)

tan (Ɵ) cho độ dốc - sự gia tăng trong quá trình chạy - của đường có độ dài r . Vì thế:

  • tan (Ɵ) = y / x
  • Ɵ = atan (y / x)

Tuy nhiên, khi thực hiện y / x, tính toán 3/4 cho câu trả lời tương tự như tính toán -3 / -4. Tương tự như vậy -3/4 cho câu trả lời tương tự như 3 / -4. Vì vậy, chúng ta có atan2 (y, x) xử lý các dấu hiệu riêng lẻ một cách chính xác và ngăn ngừa lỗi chia cho 0 / vô cực.

  • Ɵ = atan2 (y, x)

4

Jesse và Sid về cơ bản là đúng, nhưng tôi nghi ngờ bạn thực sự sau khi hiểu rõ vấn đề.

Atan2 () là cần thiết vì atan () không cho bạn biết góc từ chiều ngang bạn cần vì nó không đối phó với góc phần tư.

Điều này có nghĩa là sử dụng atan cho vectơ (-2,2) và (2, -2) sẽ cho cùng một giá trị. Sau đó, bạn sẽ bật dấu hiệu của các đối số của bạn và thêm pi vào kết quả. Ngoài ra, bạn có số chia cho trường hợp đặc biệt bằng 0 để xem xét rằng Jesse đã đề cập. Ngoài ra atan2 () hoạt động tốt hơn atan khi x gần 0

Vì vậy, nếu bạn muốn góc của một vectơ giữa -pi và pi

x = -2
y = 2
angle = Math.Atan2(y, x)

hoặc là

x = -2
y = 2
angle = calculateAngle(y, x);

double CalculateAngle(double y, double x)
{
    double angle = 0;
    if (x == 0)
    {
        if (y == 0)
            angle = 0;
        else if (y > 0)
            angle = Math.PI/2;
        else
            angle = -Math.PI/2;
    }
    else
    {
        angle = Math.Atan(y/x);
        if (x < 0)
        {
            if (y > 0)
            {
                angle += Math.PI;
            }
            else if (y < 0)
            {
                angle -= Math.PI;
            }
            else
            {
                angle = Math.PI;
            }
        }
    }
    return angle;
}

1
"Điều này có nghĩa là sử dụng atan cho vectơ (-2,2) và (2,2) sẽ cho cùng một giá trị." Nếu đây là trường hợp atan của bạn bị phá vỡ một cách khó tin, bởi vì một trong số chúng phải là -π / 4 và số còn lại là π / 4. Xấu hổ cho tất cả những người bỏ phiếu rác này lên.

Mã vẫn sai. Bạn đang thử nghiệm để y==0sau đó chia xcho các chi nhánh khác.
sam hocevar

0

Tôi sẽ làm rõ một vài điều một cách súc tích. Vui lòng tham khảo hướng dẫn lượng giác trực tuyến để được giải thích chi tiết.

Hãy để một góc. Sau đó tan (a) = tan (a + 2 * pi).

atan là tan nghịch đảo, nghĩa là, cung cấp cho bạn góc cho tan. Khi bạn gọi atan (tan (a + 2 * pi)), câu trả lời sẽ là a. Điều này sẽ không đủ cho ứng dụng của bạn.

atan2 sẽ lấy 2 đối số để giúp tình huống chính xác này. atan lấy x và y, về cơ bản là cos (a) và sin (a).

atan2 (sin (a), cos (a)) = a atan2 (sin (a + 2 * pi), cos (a + 2 * pi)) = a + 2 * pi / * sin và cos có các dấu hiệu khác nhau, dẫn đến cho một câu trả lời khác * /

Xin vui lòng tìm một số hướng dẫn để giải thích tại sao đây là cách này.

Mã của bạn phải giống như thế này:

if (mouseMoved)
{
  double angle = atan2(mousey - objecty, mousex - objectx);

  object. setTransform to Rotate(angle);

  // If you want to print it
  print radian_to_degrees(angle); // Because angle is in radian 360 degrees = 2*Pi radians
}

tan(a) = - tan(-a), phương trình bạn muốn thể hiện có lẽ làtan(a) = tan(pi+a)
Ali1S232

0

Một sử dụng cho atan2tôi tìm thấy trong mã của tôi là "góc ký".

Thông thường cách bạn tìm góc giữa hai vectơ là

inline float angleWith( const Vector2f& o ) const
{
    return acosf( this->normalizedCopy().dot(o.normalizedCopy()) ) ;
}

Nhưng điều này không cho bạn biết cái nào "dẫn" (tức là "đi trước theo chiều kim đồng hồ" so với cái kia). Thông tin này có thể quan trọng để theo dõi cử chỉ.

Bạn có thể tìm góc từ trục x (1,0)cho cả hai vectơ, nhưng có một vấn đề khó hiểu về sự mơ hồ: một vectơ có góc 315 độ trả về 45 độ bằng cosphương pháp trên và góc 45 độ cũng vậy. Bạn có thể thực hiện kiểm tra dấu hiệu yđể khắc phục điều đó hoặc bạn có thể sử dụng atan2.

// Returns + if this leads o.
// more expensive than unsigned angle.
inline float signedAngleWith( const Vector2f& o ) const
{
  float aThis = atan2f( y, x );
  float aO = atan2f( o.y, o.x ) ;
  return aThis - aO ;
}

0

Xin lưu ý atan không bị hỏng. nghịch đảo arctan hoặc tan chỉ là một hàm giữa -PI / 2 và PI / 2. Nó lặp lại mô hình này nhưng sau đó nó không phải là một chức năng gây rắc rối cho máy tính vì nó không xử lý nhiều câu trả lời.

Điều này giống với asin giữa -PI / 2 và PI / 2 và acos giữa 0 và PI. Đây là các phạm vi đơn giản nhất cho một chức năng xảy ra. Đối với atan và asin, nó đi từ tiêu cực nhất đến tích cực nhất. Đối với acos, nó đi từ tích cực nhất đến tiêu cực nhất của nó. (điều này hỗ trợ trong việc nội suy các câu trả lời chính xác hơn)

vì vậy asin, acos và atan là các hàm toán học.

Tuy nhiên, atan2 hữu ích hơn nhiều cho lập trình vì nó cung cấp cuộc cách mạng hoàn chỉnh (PI tính bằng radian hoặc 360 độ hoặc 400 độ). Lưu ý rằng họ chỉ sản xuất một cho tan chứ không phải cho tội lỗi hoặc cos. Tan là người duy nhất sử dụng ngang và dọc (x, y)

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.