Chuyển động đạn - Mũi tên


13

Trong một trò chơi 2D, tôi chỉ đơn giản muốn vẽ quỹ đạo của một mũi tên đang bay. Với mã bên dưới, quỹ đạo (parabola) trông có vẻ đúng, nhưng góc (hoặc xoay) hoặc mũi tên thì không.

float g = -9.8f;
float x = (launchVelocity * time);
float y = (launchVelocity * time) + (0.5f * g * (float)Math.Pow(time, 2));
float angle = (float)Math.Tanh(y / x);

Tôi đang thiếu gì? Cảm ơn.


3
Một ảnh chụp màn hình có thể giúp
doppelgreener

Câu trả lời:


10

Arctanhcung cấp cho bạn tiếp tuyến cho đường cong hyperbolic! Theo như tôi biết thì parabola của bạn không phải là hyperbola.

Nhưng chúng tôi có một tin tốt: việc tìm tiếp tuyến cho parabola của bạn dễ dàng hơn. Phương trình là

x = s · t => t = x / s; y = s · t + g / 2 · t² => y = x + g / 2 · x² / s²

Trong đó s là của bạn launchVelocity. Bây giờ độ dốc của mũi tên của bạn là:

∂y / y = g / (2s²) · x + 1

Bạn có thể sử dụng an toàn Arctanngay bây giờ nếu bạn muốn.

Một số thông tin bổ sung về vật lý:

Quỹ đạo gần đúng mà bạn đang mô phỏng áp dụng cho tâm khối lượng của mũi tên của bạn. Khi bạn nói "vị trí" (x, y), bạn đang nói về vị trí trung tâm của khối lượng. Trung tâm khối lượng của một mũi tên hơi hướng về phía trước từ điểm giữa và bạn nên tính đến điều đó nếu bạn định vẽ mũi tên.

Hãy nhớ rằng bạn không xem xét động lượng quán tính của mũi tên (có thể thay đổi rất nhiều nếu bạn bắn một viên đạn bi khổng lồ) và bạn không xem xét động lực học của mũi tên: chuyến bay mũi tên sẽ không đi theo con đường parabol!


Cảm ơn bạn Fxlll. Bất cứ ý tưởng nơi tôi có thể nhận được các công thức áp dụng cho vật lý của một mũi tên?
Martin

Tôi nghĩ bạn có nghĩa là :! [& Part; y / & part; x = g / (2s & sup2;) & middot; x + 1] [2] nhưng trong mọi trường hợp tôi nghĩ tôi khuyên bạn nên sử dụng cách tiếp cận tốt hơn bên dưới. Đối với một điều, bạn đã không giải thích về việc tách các thành phần x và y, do đó, điều này được mã hóa thành một góc 45 độ tùy ý, với launchVelocity không thực sự là launchVelocity, nhưng thành phần trong cả x và y
Dov

Người ta có thể tính toán những khoảnh khắc quán tính một cách dễ dàng. Đây là hai cho các thanh, một cho xoay quanh tâm khối lượng của nó và một cho xoay quanh trục của thanh. Nguyên tắc chồng chất áp dụng cho những khoảnh khắc quán tính để mũi tên có thể được chia thành ba phần: lông, cơ thể và đầu.
FxIII

1
Vấn đề là động lượng duy nhất dễ tính toán là do biến thiên góc (bạn có thể thấy rằng việc lấy hai lần một parabol chỉ là một số hạng không đổi). Nguyên nhân khác là do sự quay tròn do lông lưng. Ở đây kéo lông và ma sát có liên quan đến cả việc chuyển đổi động năng thành kéo sợi, làm chậm mũi tên nhưng thêm hiệu ứng con quay. Điều này ảnh hưởng đến quỹ đạo và khá khó để mô hình hóa
FxIII

Dù sao, nếu bạn có thể liên hệ động lượng với tốc độ được thiết lập bằng lông vũ, tất cả đều có thể được tính toán tích hợp triệt để nhưng tôi không chắc bạn có thể có dạng đóng cho các phương trình chuyển động (nghĩa là bạn có thể có thuật toán tích hợp nhưng không phải là tham số phương trình).
FxIII

4

Bạn muốn góc của mũi tên tại bất kỳ thời điểm nào. Bạn nhớ rằng để tính một góc, có một tiếp tuyến. Nhưng đây là nơi suy nghĩ của bạn bắt đầu sai:

  1. Những gì bạn muốn là delta y / delta x, vì độ dốc là tốc độ thay đổi (được đề cập trong một trong những câu trả lời khác). Lưu ý rằng x chỉ là vị trí bạn đang ở bất kỳ thời điểm nào, không phải dx.

Ok, vì vậy nếu bạn bỏ qua ma sát không khí, thì vận tốc x của mũi tên là một hằng số.

Đầu tiên, phân hủy vận tốc thành các thành phần x và y. Bạn có thể chụp ở góc 45 độ hoặc 60 độ. Vì vậy, bạn cần launchVelocity và một góc, nó không phải là vô hướng.

Thứ hai, tính toán mọi thứ như gấp đôi, không nổi. Bạn không đủ tinh vi về số lượng để biết khi nào lỗi vòng sẽ không giết bạn, vì vậy đừng thử. Nó không phải là một trình tiết kiệm thời gian tuyệt vời trong mọi trường hợp.

Thứ ba, không sử dụng Math.pow, nó chậm và không chính xác như nhân cho các số nguyên. Ngoài ra, bạn có thể tiết kiệm rất nhiều thời gian bằng cách sử dụng biểu mẫu của Horner (xem bên dưới)

final double DEG2RAD = Math.PI/180;
double ang = launchAngle * DEG2RAD;
double v0x = launchVelocity * cos(ang); // initial velocity in x
double v0y = launchVelocity * sin(ang); // initial velocity in y

double x = (v0x * time);
// double y = (v0y * time) + (0.5 * g * (float)Math.Pow(time, 2));
double y = (0.5 * g * time + v0y) * time

Nếu bạn đang tuyệt vọng về hiệu suất, bạn thậm chí có thể tính trước 0,5 * g, nhưng đoạn mã trên sẽ đưa bạn 90% quãng đường tới đó mà không làm điều gì quá điên rồ. Điểm chuẩn thực hiện điều này 10 triệu lần nếu bạn thích, phải thừa nhận rằng nó không phải là một lượng thời gian khổng lồ mà là phần trăm thông minh, nó khá lớn - các thư viện rất chậm trong Java

Vì vậy, nếu bạn muốn góc mà mũi tên sẽ đi, điều bạn muốn là

atan(dy/dx)

Và trong trường hợp này, điều đó sẽ làm việc vì dx là một hằng số. Nhưng nói chung, dx có thể bằng 0, vì vậy bạn thường muốn sử dụng:

atan2(dy, dx)

đó là một chức năng được thiết kế đặc biệt cho công việc này.

Nhưng như tôi đã nói, các hàm thư viện trong Java rất chậm và trong trường hợp này có cách làm tốt hơn mà không bị @FxIII ám chỉ ở trên.

Nếu vận tốc ngang luôn là v0x và vận tốc dọc là:

double vy = v0y - 0.5 * g * time;

thì đồng bằng của bạn là: vx, vy

Bạn không cần góc. Nếu bạn muốn vẽ một mũi tên, hãy sử dụng một cái gì đó trên danh nghĩa như:

cốt truyện (x, y, x + vx, y + vy);

Tôi không biết bạn đang vẽ gì, vì vậy nếu bạn cần góc để xoay nó (như bạn đang sử dụng JOGL) thì chắc chắn, hãy sử dụng góc.

Đừng quên nếu bạn đang sử dụng opengl để biến góc trở lại độ, vì ATAN2 trả về radian:

final double RAD2DEG = 180 / Math.PI;
double ang = Math.atan2(vy,vx); // don't forget, vy first!!!
double deg = ang * RAD2DEG;

2

Tanh () ( tiếp tuyến hyperbol ) lấy một góc làm tham số, nhưng bạn đã cho nó tỷ lệ của các cạnh.

Những gì bạn thực sự muốn là sử dụng arctangent hyperbol , lấy tỷ lệ của các bên làm tham số và trả về góc. (Đặt tên cho cái này có thể là "atanh", "atanh2", "arctanh" hoặc một cái gì đó tương tự; dường như thay đổi rất nhiều giữa các thư viện toán học khác nhau)


Không, bạn không muốn hyperbolic bất cứ điều gì
Dov

Gah, bạn hoàn toàn đúng. Tôi đã ngay lập tức nhận ra lỗi "sử dụng lượng giác cơ bản" và bỏ lỡ rằng hàm anh ta đang sử dụng là hoàn toàn không chính xác cho phần còn lại của phương pháp.
Trevor Powell

Tân () có một góc. Atan có tỷ lệ cạnh tam giác (sin / cos).
3Dave
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.