Phương pháp mô phỏng vật lý cho thời gian đồng bằng lớn?


9

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?


1
Nó phần lớn phụ thuộc vào khu vực mục tiêu của bạn. Khó có thể nói bất cứ điều gì mà không biết thêm về bạn những mục tiêu thực sự ở đó. Quá rộng.
Kromster

Câu hỏi này có liên quan.
Anko

Về nguyên tắc, thời gian thích hợp phụ thuộc vào những gì người chơi trải nghiệm. Bạn có muốn nó chính xác theo thời gian vài tuần để người chơi tương tác với nó trong thời gian thực không? Điều đó khó hơn nhiều so với việc làm cho nó hoạt động theo thời gian vài tuần mà người chơi trải nghiệm nhiều lần trong thời gian thực ( tức là một giây trải nghiệm của người chơi là một tuần thời gian thực).
mklingen

nếu bạn đang mô phỏng các chuyển động của đám mây, hoặc các biến nhiệt động trong các ô rộng hàng trăm mét, với thời gian 10 phút thì hợp lý. nhưng cơ thể cứng nhắc ở quy mô thông thường, không quá nhiều. ứng dụng này là gì
v.oddou

Ứng dụng này là một cơ chế "bắt kịp" trong đó mô phỏng kể từ lần tải cuối cùng (của một phần của thế giới) được chạy, logic trò chơi là tất cả dựa trên cuộc gọi lại trong đó cuộc gọi lại là bộ đếm thời gian hoặc cuộc gọi lại va chạm, tôi muốn có thể chạy vật lý tiếp theo gọi lại hẹn giờ hiệu quả, và có thỏa thuận mô phỏng vật lý với gọi lại các cuộc gọi lại va chạm. Va chạm là tương đối khó xảy ra, nhưng tôi muốn các cuộc gọi lại va chạm để có trạng thái trò chơi (vật lý) có sẵn tại thời điểm va chạm.
fread2281

Câu trả lời:


5

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 v0s0cá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.


va chạm thì sao?
fread2281

Tôi đã cập nhật câu trả lời để bao gồm các chiến lược xử lý va chạm.
MichaelHouse

điều này là sai. Tích hợp Euler được biết là lệch cho tích hợp không đổi, trong khi Verlet (hoặc RK2, RK4) thì không.
v.oddou

@ v.oddou Xem xét các mô phỏng này là dành cho các trò chơi, tôi không nghĩ độ chính xác mà bạn yêu cầu là cần thiết. Sự phức tạp và khó khăn thêm của việc thêm các va chạm cho Verlet làm cho tích hợp Euler trở thành một lựa chọn ưu việt.
MichaelHouse

2

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 dtcà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 dtquá 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 dtmô phỏng của bạn có thể xử lý để có kết quả đủ tốt. Và nếu dtcá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 dtmà 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ý.


1

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 ...

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.