Phương pháp mô phỏng vật lý nào phù hợp nhất với thời gian đồng bằng thực sự lớn (vài giờ đến vài tuần)?
Ngoài ra, tôi có phải đối mặt với bất kỳ vấn đề nào khi kết hợp các phương pháp khác nhau cho thời gian đồng bằng lớn và nhỏ không?
Phương pháp mô phỏng vật lý nào phù hợp nhất với thời gian đồng bằng thực sự lớn (vài giờ đến vài tuần)?
Ngoài ra, tôi có phải đối mặt với bất kỳ vấn đề nào khi kết hợp các phương pháp khác nhau cho thời gian đồng bằng lớn và nhỏ không?
Câu trả lời:
Bạn có thể sẽ sử dụng gia tốc liên tục cho các khoảng thời gian lớn này (có thể là gia tốc bằng không). Đạo hàm của gia tốc liên tục theo thời gian là 0. Điều đó có nghĩa là nó không thay đổi theo thời gian, vì vậy không quan trọng thời gian delta của bạn lớn đến mức nào.
Sự tích hợp nhỏ này liên quan đến thời gian cung cấp các phương trình bạn cần.
a = a
v = at + v0
s = .5at^2 + v0*t + s0
Trong đó: a = gia tốc, v = vận tốc, v0 = vận tốc ban đầu, s = vị trí, s0 = vị trí ban đầu, t = thời gian
Sử dụng chiến lược này, bạn có thể sử dụng thời gian kéo dài từ mili giây đến vài tuần nếu bạn muốn. Kết hợp chúng sẽ được quan tâm trong v0
và s0
các tham số của phương trình.
Để xử lý các va chạm, bạn sẽ phải thực hiện các chiến lược tương tự như các chiến lược được sử dụng cho các đối tượng nhỏ tốc độ cao . Đầu tiên tính toán vị trí mới bằng phương trình trên, sau đó quét giữa vị trí cũ và mới cho tất cả các đối tượng. Vì bất kỳ một trong những đối tượng đó có thể đã giao nhau (vài phút hoặc vài ngày trước đó), điều này có thể trở nên rất phức tạp. Có vẻ như vì bạn có thời gian đồng bằng lớn như vậy, hy vọng bạn sẽ có nhiều thời gian để xử lý các va chạm tiềm năng này.
Hãy lấy một ví dụ với trọng lực.
Trong hàm dưới đây, giả sử chúng ta có các biến thành viên lớp cho vị trí và vận tốc. Chúng ta cần cập nhật chúng do lực hấp dẫn mỗi dt giây.
void update( float dt )
{
acceleration = G * m / r^2;
velocity = velocity + acceleration * dt;
position = position + velocity * dt;
}
Khi dt
càng ngày càng nhỏ, mô phỏng của chúng tôi càng ngày càng chính xác (mặc dù nếu dt
quá nhỏ thì chúng tôi có thể gặp phải các lỗi chính xác khi thêm số nhỏ vào số lớn).
Về cơ bản, bạn phải quyết định tối đa dt
mô phỏng của bạn có thể xử lý để có kết quả đủ tốt. Và nếu dt
cái đi vào quá lớn, thì chỉ cần chia mô phỏng thành các bước nhỏ hơn, trong đó mỗi bước là mức tối đa dt
mà bạn cho phép.
void update( float dt )
{
acceleration = G * m / r^2;
velocity = velocity + acceleration * dt;
position = position + velocity * dt;
}
// this is the function we call. The above function is a helper to this function.
void updateLargeDt( float dt )
{
const float timeStep = 0.1;
while( dt > timeStep )
{
update( timeStep );
dt -= timeStep ;
}
update( dt ); // update with whatever dt is left over from above
}
Vì vậy, với chiến lược này, bạn có thể điều chỉnh timeStep
bất kỳ độ trung thực nào bạn cần (biến nó thành giây, phút, giờ hoặc bất cứ điều gì cần thiết để có được một đại diện chính xác của vật lý.
Hầu hết các trò chơi có xu hướng sử dụng phương pháp tích hợp thuận Euler đơn giản (nghĩa là tích hợp vận tốc vào vị trí theo thời gian và tích hợp gia tốc vào vận tốc). Thật không may, phương pháp Euler chỉ phù hợp với thời gian rất nhỏ và thời gian ngắn.
Có nhiều phương pháp phức tạp hơn, chính xác hơn theo thang thời gian rất dài. Phổ biến nhất và dễ thực hiện nhất có lẽ là Runge-Kutte-4 . RK4 xác định vị trí trong tương lai bằng cách lấy mẫu bốn vị trí và vận tốc trong quá khứ và nội suy. Nó có xu hướng chính xác hơn nhiều so với phương pháp Euler theo thang thời gian dài hơn, nhưng đắt hơn về mặt tính toán.
Chẳng hạn, nếu bạn muốn tính toán vật lý của một hành tinh quay quanh thực tế cập nhật cứ sau vài ngày theo thời gian thực, phương pháp Euler sẽ khiến hành tinh này bắn vào không gian chỉ sau một vài quỹ đạo do lỗi số. RK4 nói chung sẽ giữ hành tinh quay quanh trong hình dạng gần giống nhau hàng ngàn lần trước khi tích lũy quá nhiều lỗi.
Tuy nhiên, việc thực hiện va chạm vào RK4 có thể rất khó khăn ...