Giải quyết va chạm trong trường hợp va chạm với nhiều đối tượng


15

Tôi có các đối tượng tĩnh và các đối tượng di chuyển. Các va chạm được phát hiện bằng định lý trục tách.

Ví dụ, trong tình huống này tôi có hai đối tượng tĩnh (màu đỏ):

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

và một đối tượng di chuyển giữa hai:

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

Thuật toán của tôi có thể tính toán va chạm giữa hai trong số các đối tượng này và nó cũng tạo ra một vectơ độ phân giải hoàn hảo (có nghĩa là vectơ chuyển vị tối thiểu) cho va chạm.

Vì vậy, ví dụ, khi tôi kiểm tra va chạm giữa hình chữ nhật màu xanh lá cây và hình chữ nhật màu đỏ bên phải, thuật toán sẽ tạo ra một vectơ cho tôi biết làm thế nào tôi cần di chuyển hình chữ nhật màu xanh lá cây để giải quyết va chạm:

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

Lưu ý rằng tôi đã nhanh chóng vẽ nó trong MSPaint, vì vậy trong bức ảnh đó thực sự có thể là vectơ dịch tối thiểu đẩy hình chữ nhật màu xanh lá cây lên trên cùng, nhưng tôi sẽ giả sử ở đây đẩy nó ra bên trái / đúng là thực sự ngắn hơn.

Cách chung để tiếp cận điều này sẽ là chỉ giải quyết va chạm của một vụ va chạm trên mỗi khung hình, thay vì tất cả cùng một lúc. Nhưng trong trường hợp của tôi, điều này sẽ dẫn đến lật kèo:

Đầu tiên, bộ giải phát hiện hai va chạm nhưng chỉ giải quyết va chạm giữa hình chữ nhật bên phải và hình chữ nhật màu xanh lá cây:

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

Sau đó, trong khung tiếp theo, nó chỉ phát hiện một va chạm nằm giữa hình chữ nhật màu đỏ bên trái và hình chữ nhật màu xanh lá cây và giải quyết nó:

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

Như bạn có thể thấy, điều này thực sự không giải quyết được sự va chạm (ví dụ bằng cách đẩy hình chữ nhật màu xanh lá cây lên trên cùng), và thay vào đó chỉ là lật đôi giữa hai trạng thái vô hạn.

Làm sao tôi có thể giải quyết việc này?


Bạn đang sử dụng hình chữ nhật trong ví dụ của bạn. Có phải thuật toán va chạm của bạn chỉ giải quyết va chạm trên chỉ một trục? Nếu vậy, nó có ý nghĩa rằng hành vi bạn mô tả đang xảy ra.
chaosTechnician

Không, nó có thể phân giải chúng bằng bất kỳ loại hình dạng nào trên tất cả các trục có thể (không chỉ hình chữ nhật, chúng chỉ dễ vẽ nhất bằng sơn MS: P) và nó sẽ luôn tìm thấy vectơ ngắn nhất tồn tại đẩy hai vật thể ra xa nhau .
TravisG

+1 Câu hỏi hay. Tôi đã xóa "thẻ" (2D) khỏi tiêu đề, đó là điều bạn nên tránh (xem meta ).
bummzack

Câu trả lời:


7

Tùy thuộc vào chính xác những gì bạn đang cố gắng đạt được (độ chính xác vật lý cao hoặc chỉ là một mô phỏng thời gian thực đủ gần), bạn có thể thử sử dụng các liên hệ đầu cơ.

Dưới đây là các chi tiết: http://www.wildbunny.co.uk/blog/2011/03/25/speculators-contacts-an-continupt-collision-engine-approach-part-1/

Ông mô tả trong bài viết đó những gì bạn cần biết để thực hiện nó, và nó rất đơn giản so với các phương pháp khác (như đúc hình cầu và sau đó sắp xếp các độ phân giải va chạm theo thời gian tác động).

Nếu bạn cần / muốn nhiều hơn, bạn có thể mua mã nguồn của anh ấy với giá (IIRC) $ 7.

Đây là video về quá trình triển khai của tôi ở chế độ 3D: http://www.youtube.com/watch?v=JvT2H1RmOas

Lưu ý mức độ ổn định của mô phỏng chỉ với một lần lặp duy nhất. Bạn có thể dễ dàng sử dụng nhiều lần lặp trên mỗi khung để giải quyết nhiều va chạm về trạng thái ổn định, điều này sẽ chính xác hơn.


2

Trước tiên, bạn có thể tính toán tất cả các vectơ cần thiết để giải quyết mỗi va chạm sau đó tính toán một kết quả từ chúng.

Trường hợp duy nhất khi điều này có thể byte bạn là nếu các vectơ này vô hiệu hóa lẫn nhau, giống như trong ví dụ của bạn. Trong trường hợp đó, sự va chạm không thể được giải quyết.


Thêm một vectơ ngẫu nhiên nhỏ với cường độ khoảng epsilon * 10 vào các va chạm? Số học dấu phẩy động nên làm phần còn lại.
Martin Sojka

2
Vâng, điều này có thể làm việc, tôi đoán. Nhưng nó cũng có thể tạo ra các chuyển động jitter.
Mihai Maruseac

1
Tôi hy vọng tôi vẫn có thể nhận được câu trả lời về vấn đề này: tính toán kết quả khắc phục sự cố "vòng lặp vô hạn", nhưng giới thiệu lại vấn đề "bẻ khóa", trong đó di chuyển trong khi trượt trên một bức tường làm bằng gạch có cùng kích thước khiến cơ thể có được mắc kẹt giữa các "vết nứt" của gạch. Có cách nào để giải quyết cả hai vấn đề này không?
Vittorio Romeo

Đồng ý ... không có "câu trả lời đúng" tốt nhất để giải quyết một vụ va chạm cơ thể cứng nhắc không thể như thế. Hoặc nó bị giật, hoặc bạn cho phép một số "độ nhão" trong một hoặc nhiều đối tượng.
david van brink

0

Nếu bạn nhìn kỹ vào nó, trạng thái của các đối tượng là (hoặc nên) không thể thực hiện được ..

Đặt hình màu đỏ ngoài cùng bên trái là hình R1 và hình màu đỏ ngoài cùng bên phải là hình R2. Đặt hình dạng màu xanh lá cây là G.

tức là Cho kích thước và hình dạng của cả ba đối tượng và cho rằng tất cả các đối tượng không thể xuyên qua:

 (1) G could not have been just directly to the left of R2, since R1 has been there 
     already. Consequently, the translation of G from left to right, penetrating R2
     could not have occurred.
 (2) G could not have been just directly to the right of R1 since R2 has been there 
     already. Consquence of which is the same as that from (1).
 (3) Had G come from the top, the movement will be blocked by both R1 and R2, given
     that their geometry and Y coordinate is the same.

Bây giờ, hãy giải thích nó, nếu thuật toán của bạn truy vấn từng đối tượng của bạn, thì đó là vấn đề đồng thời, nghĩa là, thuật toán được cho là kiểm tra TẤT CẢ các đối tượng cùng một lúc, nhưng thuật toán giới hạn bạn phải làm các đối tượng và xử lý chúng cùng một lúc ...

Nếu G được kiểm tra so với R1 sau khi được kiểm tra so với R2, thì G sẽ xuất hiện ở bên phải của R1 (nếu G nói tiếp cận R1 với hướng của vectơ <-1, -1> với độ lớn tùy ý (hoặc khoảng cách) ), bởi vì việc kiểm tra giữa R1 và G cho phép và quên đi việc kiểm tra giữa R2 và G đã được thực hiện trước đó.

Một giải pháp bạn có thể làm là thu thập tất cả các vectơ dịch chuyển tối thiểu vào một mảng hoặc bất kỳ cấu trúc dữ liệu nào bạn muốn và chọn một vectơ chứng minh hợp pháp cho TẤT CẢ các Đối tượng.

Lưu ý rằng tại một khung nhất định, đối tượng (ví dụ G) chỉ có thể có MỘT hướng. (ồ, nghe giống như boyband ...)

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.