Phát hiện va chạm: một loạt các trường hợp đặc biệt?


8

Tôi đang viết một công cụ vật lý đơn giản trong 2D. Mục tiêu đầu tiên của tôi là để phát hiện va chạm làm việc. Tôi biết rằng các đối tượng của tôi cuối cùng sẽ được tạo thành từ các hình dạng nguyên thủy, nhưng tôi đã tự hỏi - một thư viện phát hiện va chạm sẽ bao gồm một loạt các hàm trường hợp đặc biệt, như "rayAndLine", "hình chữ nhật", "hình chữ nhật", v.v. Có một khung chung, cơ bản để phát hiện va chạm hoạt động bất kể nguyên thủy nào được sử dụng để tạo hình?


Bạn hỏi về một khung cơ bản, nhưng cụ thể là bạn muốn tự mình xây dựng phần này. Bạn có thể làm rõ câu cuối cùng nơi câu hỏi thực sự của bạn diễn ra, để tách biệt cụ thể hơn mối quan tâm của bạn về việc tự xây dựng nó, khỏi việc sử dụng khuôn khổ của người khác mà họ đã xây dựng. Tôi cũng sẽ cung cấp một câu trả lời.
Joshua Hedges

Điểm công bằng. Tôi có nghĩa là lý thuyết cơ bản mà tất cả các phát hiện va chạm bắt nguồn. Nói cách khác, nếu tôi đang viết một hệ thống con phát hiện va chạm, tôi có cần phải viết một hàm cho từng loại va chạm nguyên thủy / nguyên thủy hay có một chức năng chung duy nhất hoạt động cho dù nguyên thủy là gì?
Michael Stachowsky

Sắp xếp Tôi chỉ trả lời nó. Có một số giải pháp tổng quát hóa thực sự tốt, như SAT hoạt động cho bất kỳ đa giác lồi nào, và bất kỳ đa giác lõm nào cũng có thể được chia thành đa giác lồi, giúp nó hoạt động cho mọi đa giác với một số công việc. Sau đó, bạn phải chuyên chống lại các đường cong, hình cầu và hình bầu dục. Tôi đã phác thảo nó dưới đây. Đây là một chủ đề lớn để đề cập quá lâu. Hãy cho tôi biết nếu bạn có bất kỳ câu hỏi nào về chi tiết cụ thể hoặc bất cứ điều gì khác
Joshua Hedges


1
Mã chia sẻ càng nhiều thì càng tốt. Nếu bạn thấy mình sử dụng bản sao và dán, hãy nghiêm túc kiểm tra chính mình!
corsiKa

Câu trả lời:


9

Làm việc phát hiện va chạm là mục tiêu đầu tiên tuyệt vời cho động cơ vật lý 2D của bạn. Thật tốt khi bạn đã quyết định rằng bây giờ bạn đặc biệt làm việc trong 2D, vì không phải mọi quy tắc trong 2D đều hoạt động ở chế độ 3D, mặc dù số lượng thuật toán liên quan đến n chiều, đôi khi bạn phải chuyên môn hóa chúng (làm nhiều hơn biến thể cụ thể như cách sản phẩm chéo chỉ thỏa mãn bản sắc Jacobi trong 3D).

Câu hỏi của bạn vốn dĩ là về kiến ​​trúc và thiết kế khung chứ không phải về vật lý 2D, vì vậy mối quan tâm về việc tòa nhà của bạn nên tách biệt trong tâm trí của bạn về cách sử dụng những mảnh đó. Về cơ bản, bạn cần tách biệt tâm lý xây dựng công cụ / thư viện / khung với việc sử dụng nó trong một dự án khác.

Kiến trúc giải quyết các công cụ: Với bất kỳ công cụ toán học nào, về cơ bản chúng tôi muốn đưa các giá trị vào một số hàm và chúng tôi hy vọng các giá trị xuất hiện sẽ hữu ích để tạo ra một mô phỏng thú vị.

Các yếu tố cốt lõi của quá trình này phải càng trừu tượng càng tốt trong khi các yếu tố nguyên tử (phần dữ liệu / phương pháp hữu ích nhỏ nhất) phải cụ thể cho các mục đích riêng lẻ và hữu ích để kết hợp với nhau. Trong trường hợp của chúng tôi, gần như nguyên tử hữu ích duy nhất là một vectơ 2D, là một lớp đối tượng duy nhất cho phép biểu hiện cấu trúc (x, y) và có các phương thức cho tất cả các phép toán cơ bản hữu ích cho việc tính toán vectơ trong 2D. Phép cộng, phép trừ, chuẩn hóa, bình thường (vuông góc), sản phẩm chéo, sản phẩm chấm, cường độ / chiều dài và bất cứ điều gì khác mà bạn gặp phải đặc biệt vốn có của vectơ -> phép toán vectơ hoặc vectơ -> phép toán số thực. Nếu bạn đang sử dụng một ngôn ngữ dựa trên lớp, một đơn giản class Vectorvới mỗi ngôn ngữ này là chức năng thành viên hoặc quá tải toán tử sẽ làm rất tốt.

Sau khi tất cả các loại nguyên tử được xây dựng, sau đó bạn sẽ kết hợp các thuật toán của chúng thành một lớp khác trên đầu loại nguyên tử của chúng tôi Vector. Đi của tôi sẽ là một Linevà một Curve. Chúng tôi sẽ quyết định ở đây rằng một Curvephạm vi cho điều này và đòi hỏi nhiều chuyên môn hóa (khái niệm bạn đề cập ở trên là tạo ra nhiều chức năng trường hợp đặc biệt). Từ Vectortôi cũng sẽ sáng tác Rectanglenhư một 4 Vectornguyên thủy, sáng tác Circletừ vectơ bằng cách sử dụng a Vectorvà a radius, và sau đó tôi cũng sẽ soạn một Polygontừ Vector. Polygonnên được tạo từ Vectorvà không Lineở đây vì mỗi dòng sẽ chia sẻ một điểm trùng lặp với dòng cuối cùng trong đa giác.

Bây giờ bạn có hình dạng, nhưng chúng tôi không biết phải làm gì với chúng.

Phát hiện va chạm Phát hiện va chạm không phải là một khoa học chính xác và không có một thuật toán hoàn hảo duy nhất (hoặc bất kỳ). Có nhiều phương pháp có thể được sử dụng để đạt được nhiều hiệu ứng chất lượng hoặc thậm chí có độ chính xác cao hơn các phương pháp khác. Về cơ bản, nó có thể được tách thành một vài mức độ quan tâm khác nhau và do đó một vài quy trình khác nhau.

Phát hiện va chạm pha rộng là hành động phân chia các khu vực nơi chúng tôi quan tâm đến những gì có thể / có thể / không va chạm và tách chúng ra cho quy trình pha hẹp. Trong 2D tôi thường khuyên bạn nên sử dụng cây quad cho việc này. Vì vậy, chúng tôi sẽ cần chúng Rectangletôi xây dựng trước đó và để cung cấp cho nó một phát hiện va chạm AABB. Chữ này là viết tắt của Hộp liên kết trục và chúng tôi sẽ sử dụng nó để xác định rằng đối với hộp không xoay Amà không có phần nào của hộp Btồn tại bên trong A. Nó xuất phát từ giả định rằng không có phần nào Bcó thể tồn tại trong Ađó một vụ va chạm tồn tại nếu chúng giao nhau.

Cây tứ giác là một quá trình đệ quy trong đó bạn xác định độ sâu tối đa hoặc cho phép số lượng đối tượng của bạn để ngăn chặn độ sâu đệ quy vô hạn thay thế. Nó nhóm các cơ thể vật lý thành 4 vùng (do đó là tên) và sẽ cho phép bạn truy cập từng nhóm riêng biệt. Sau đó, bạn sẽ tham gia vào bốn hình tứ giác đó và thực hiện cùng một quy trình mà tôi sẽ không phác thảo ở đây để cho ngắn gọn nhưng có sẵn ở đây: https://gamedevelopment.tutsplus.com/tutorials/quick-tip-use-quadtrees- phát hiện-có khả năng va chạm-trong-không gian 2d - gamedev-374

Va chạm pha hẹplà quá trình đi qua các nhóm hình dạng của bạn mà chúng tôi đã xác định sẽ / có thể / thực hiện va chạm và thực hiện kiểm tra va chạm rời rạc hơn, tại thời điểm này, chúng tôi bắt đầu quan tâm xem các vật thể có quay hay không (tôi đã thắng ' Bao gồm điều này, khi bạn vượt qua các pha va chạm này, hãy nhìn vào việc phát hiện va chạm với động lượng góc) và hình dạng cơ thể va chạm của chúng thực sự là gì. Để thực hiện phần xung đột này, bạn sẽ chuyên môn hóa các phương thức của mình như bạn đã mô tả ở trên (tạo các hàm cụ thể cho AABBvsCircle, OBBvsCircle, CirclevsCircle, PolygonvsPoint, PolygonvsCircle, PointvsCircle, v.v.) Tuy nhiên, các phương thức này cũng có thể được thực hiện theo cách thức. như trên.

Kiểm tra tách nguyên thủy của mình là rời rạc, phương pháp phát hiện va chạm chuyên hoặc những người chung chung như SAT tùy thuộc vào trường hợp sử dụng và nên tất cả chỉ đơn giản là trở về hoặc là một giá trị đúng / sai, hoặc trả lại một đối tượng quan hệ như một Manifold, Joint, CollisionObjectvv mà sẽ có một kết nối với hai hình dạng được tìm thấy đang va chạm và bất kỳ thông tin nào về chúng cần thiết để giải quyết va chạm, như mức độ va chạm của chúng hoặc ở tốc độ nào (dữ liệu bạn cần trong đa tạp tùy thuộc vào phương pháp giải quyết nào bạn sử dụng). Đối tượng mà bạn sau đó chuyển đến một Solverthứ sẽ trừu tượng hóa sự khác biệt giữa tất cả các hình dạng khác nhau có thể va chạm, bằng cách chỉ chấp nhận Manifoldvà không chấp nhận bất kỳ thông tin cụ thể nào về hình dạng.

Tóm tắt Việc Solverlấy sẽ Manifoldđược tạo ra bằng cách va chạm một số nguyên thủy Avới một số nguyên thủy B, sử dụng nhóm pha rộng đầu tiên (tất cả so với thế giới) và sau đó phát hiện pha hẹp (A vs B) và nếu các hình dạng không phải là đa giác thì phải Solvertạo ra một hình mới Vectors cho các vị trí va chạm hình dạng và vận tốc, hoặc một đối tượng mà PhysicsEnvironmenthoặc Worldsau đó có thể sử dụng để quyết va chạm đối với trẻ em của nó, sau đó cuối cùng đã cập nhật QuadTreevà lặp lại quá trình này trên frame kế tiếp. Nếu cả hai hình dạng va chạm đều là đa giác thì việc chuyên môn hóa chỉ nên được thực hiện với mối quan tâm đến hiệu suất tăng, nếu không, chỉ cần sử dụng Định lý trục tách


1
Câu trả lời tuyệt vời, cảm ơn. Mặc dù vậy, tôi tò mò: Ban đầu tôi đã xem xét căn cứ vào đối tượng nguyên thủy nhất của mình, sau đó xây dựng một vectơ từ đó. Tôi thấy từ câu trả lời của bạn rằng đây không hẳn là sự lựa chọn tốt nhất. Tại sao vậy?
Michael Stachowsky

1
Lý do cho điều đó là bởi vì trong 2 chiều, một vectơ và một điểm thực sự có cùng định nghĩa. a Vector direction,Magnitudecó thể được thực hiện như là Point x,ynếu bạn chỉ cần bỏ qua một số hoạt động mà nó Vectorcung cấp. Phần tốt nhất để làm điều này, chỉ là vì bạn có thể bỏ qua các hoạt động đó ngay bây giờ, khi bạn muốn xác định những thứ như động lượng góc bạn không thay đổi loại đối tượng. Đó gần như là một vấn đề của hương vị, bởi vì những gì các nhà phát triển trò chơi gọi là nhà toán học "Điểm" thực sự gọi là "Vector". Vì vậy, gọi nó là những gì bạn muốn, điều quan trọng là những gì nó cung cấp.
Joshua Hedges

1
Trong ngôn ngữ kiểu C, nếu tôi muốn sử dụng định nghĩa "Điểm" để dễ đọc thì thực tế tôi chỉ đơn giản là typedeftừ Vector hoặc bí danh thuật ngữ "Điểm" có nghĩa tương tự như "Vector".
Joshua Hedges
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.