การแก้ปัญหาการชนในกรณีที่มีการชนกับวัตถุหลายอย่าง


15

ฉันมีวัตถุคงที่และวัตถุที่เคลื่อนย้ายได้ ตรวจพบการชนกันโดยใช้ทฤษฎีการแยกแกน -

ตัวอย่างเช่นในสถานการณ์นี้ฉันมีวัตถุสองชิ้น (สีแดง):

ป้อนคำอธิบายรูปภาพที่นี่

และวัตถุที่เคลื่อนที่ได้ระหว่างสอง:

ป้อนคำอธิบายรูปภาพที่นี่

อัลกอริทึมของฉันสามารถคำนวณการชนกันระหว่างวัตถุทั้งสองนี้และมันก็แยกเวกเตอร์ความละเอียดที่สมบูรณ์แบบออกมา (หมายถึงการกระจัดต่ำสุด - เวกเตอร์) กับการชน

ตัวอย่างเช่นเมื่อฉันตรวจสอบการชนกันระหว่างสี่เหลี่ยมสีเขียวและสี่เหลี่ยมสีแดงด้านขวาอัลกอริทึมจะแยกเวกเตอร์ที่บอกฉันว่าฉันต้องย้ายสี่เหลี่ยมสีเขียวเพื่อแก้ไขการชนกันอย่างไร:

ป้อนคำอธิบายรูปภาพที่นี่

โปรดสังเกตว่าฉันเพิ่งวาดสิ่งนี้ใน MSPaint อย่างรวดเร็วดังนั้นในภาพนั้นอาจเป็นได้ว่าการแปลขั้นต่ำ - เวกเตอร์ผลักสี่เหลี่ยมผืนผ้าสีเขียวออกด้านบน แต่ฉันจะสมมติที่นี่ที่ผลักไปทางซ้าย / จริงสั้นกว่า

วิธีการทั่วไปของการเข้าใกล้นี้จะแก้ไขการชนกันของหนึ่งการชนกันต่อหนึ่งเฟรมเท่านั้นแทนที่จะแก้ไขทั้งหมดในคราวเดียว แต่ในกรณีของฉันสิ่งนี้จะส่งผลให้การพลิกล้ม:

ขั้นแรกตัวแก้ปัญหาตรวจจับการชนกันสองครั้ง แต่จะแก้ไขการชนกันระหว่างสี่เหลี่ยมด้านขวาและสี่เหลี่ยมสีเขียวเท่านั้น:

ป้อนคำอธิบายรูปภาพที่นี่

จากนั้นในเฟรมถัดไปมันจะตรวจจับการชนเพียงครั้งเดียวซึ่งอยู่ระหว่างสี่เหลี่ยมผืนผ้าสีแดงซ้ายและสี่เหลี่ยมสีเขียวและแก้ไขมัน:

ป้อนคำอธิบายรูปภาพที่นี่

อย่างที่คุณเห็นนี่จะไม่สามารถแก้ไขการชนกันได้ (ตัวอย่างเช่นโดยการกดสี่เหลี่ยมสีเขียวออกไปด้านบน) และเพียงแค่พลิก flops ระหว่างสองสถานะแทน

ฉันจะแก้ปัญหานี้ได้อย่างไร


คุณกำลังใช้รูปสี่เหลี่ยมผืนผ้าในตัวอย่างของคุณ อัลกอริทึมการชนของคุณแก้ไขการชนกันบนแกนเดียวเท่านั้นหรือไม่ ถ้าเป็นเช่นนั้นมันก็สมเหตุสมผลที่พฤติกรรมที่คุณอธิบายนั้นกำลังเกิดขึ้น
chaosTechnician

ไม่มันสามารถแก้ปัญหาพวกมันด้วยรูปทรงใด ๆ บนแกนที่เป็นไปได้ทั้งหมด (ไม่ใช่แค่รูปสี่เหลี่ยมพวกมันเป็นวิธีที่ง่ายที่สุดในการวาดด้วยสี MS: P) และมันจะหาเวกเตอร์ที่สั้นที่สุดที่มีอยู่ .
TravisG

+1 คำถามที่ดี ฉันลบแท็ก (2D) "ออกจากชื่อเป็นสิ่งที่คุณควรหลีกเลี่ยง (ดูเมตา )
bummzack

คำตอบ:


7

ขึ้นอยู่กับสิ่งที่คุณพยายามที่จะบรรลุ (ความแม่นยำทางกายภาพสูงหรือเพียงแค่การจำลองแบบเรียลไทม์ใกล้พอ) คุณสามารถลองใช้ผู้ติดต่อเก็งกำไร

นี่คือรายละเอียด: http://www.wildbunny.co.uk/blog/2011/03/25/speculative-contacts-an-continuous-collision-engine-approach-part-1/

เขาอธิบายในบทความว่าสิ่งที่คุณจำเป็นต้องรู้ในการใช้มันและมันง่ายมากเมื่อเทียบกับวิธีการอื่น ๆ (เช่นการหล่อทรงกลมแล้วเรียงลำดับการชนกันของการชนตามเวลาที่เกิดผลกระทบ)

หากคุณต้องการ / ต้องการมากขึ้นคุณสามารถซื้อซอร์สโค้ดของเขาสำหรับ (IIRC) $ 7

นี่คือวิดีโอการใช้งานของฉันในแบบ 3 มิติ: http://www.youtube.com/watch?v=JvT2H1RmOas

สังเกตว่าการจำลองมีความเสถียรเพียงแค่วนซ้ำเพียงครั้งเดียว คุณสามารถใช้การวนซ้ำหลายครั้งต่อเฟรมเพื่อแก้ไขการชนหลายครั้งให้อยู่ในสถานะเสถียรซึ่งจะแม่นยำยิ่งขึ้น


2

คุณสามารถคำนวณเวกเตอร์ทั้งหมดที่จำเป็นในการแก้ปัญหาการชนแต่ละครั้งจากนั้นคำนวณผลลัพธ์จากพวกเขา

ในกรณีที่เมื่อคุณสามารถไบต์คุณคือถ้าเวกเตอร์เหล่านี้เป็นโมฆะกันและกันเช่นเดียวกับในตัวอย่างของคุณ ในกรณีนั้นไม่สามารถแก้ไขการชนกันได้


เพิ่มเวกเตอร์สุ่มขนาดเล็กที่มีขนาดประมาณepsilon * 10 เข้ากับการชนหรือไม่ การคำนวณเลขทศนิยมควรทำส่วนที่เหลือ
Martin Sojka

2
ใช่สิ่งนี้สามารถใช้ได้ฉันเดา แต่มันก็สามารถสร้างการเคลื่อนไหวที่กระวนกระวายใจ
หมดเวลา Maruseac

1
ฉันหวังว่าฉันจะยังคงได้รับคำตอบเกี่ยวกับสิ่งนี้: การคำนวณผลลัพธ์ช่วยแก้ไขปัญหา "infinite loop" แต่แนะนำปัญหา "crack" อีกครั้งซึ่งการเคลื่อนไหวในขณะที่เลื่อนบนผนังที่ทำจากกระเบื้องที่มีขนาดเท่ากันทำให้ร่างกายได้รับ ติดอยู่ระหว่าง "รอยแตก" ของกระเบื้อง มีวิธีใดบ้างในการแก้ไขปัญหาทั้งสองนี้
Vittorio Romeo

เห็นด้วย ... ไม่มี "คำตอบที่ถูกต้อง" ที่ดีที่สุดในการแก้ปัญหาการชนของร่างกายที่เป็นไปไม่ได้เช่นนั้น ไม่ว่ามันจะกระวนกระวายใจหรือคุณอนุญาตให้ "ความอ่อนนุ่ม" ในวัตถุอย่างน้อยหนึ่งอย่าง
david van brink

0

หากคุณมองอย่างใกล้ชิดสถานะของวัตถุนั้น (หรือควร) ไม่สามารถบรรลุได้ ..

ให้รูปร่างสีแดงซ้ายสุดเป็นรูปร่าง R1 และรูปร่างสีแดงขวาสุดเป็นรูปร่าง R2 ให้รูปร่างสีเขียวเป็น G

กล่าวคือกำหนดขนาดและรูปทรงเรขาคณิตของวัตถุทั้งสามและระบุว่าวัตถุทั้งหมดไม่สามารถแทรกซึมได้:

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

ทีนี้ถ้าหากอัลกอริทึมของคุณทำการค้นหาวัตถุของคุณทีละตัวมันก็เป็นเรื่องของการเกิดขึ้นพร้อมกันเช่นในแง่หนึ่งอัลกอริทึมควรจะตรวจสอบวัตถุทั้งหมดในเวลาเดียวกัน แต่อัลกอริทึม จำกัด ให้คุณทำ วัตถุและประมวลผลทีละรายการ ...

หาก G ถูกตรวจสอบกับ R1 หลังจากถูกตรวจสอบกับ R2 แล้ว G จะปรากฏทางด้านขวาของ R1 ตามกฎหมาย (ถ้า G พูดเข้าใกล้ R1 โดยมีทิศทางของเวกเตอร์ <-1, -1> ด้วยขนาดโดยพลการ (หรือระยะทาง) ) เนื่องจากการตรวจสอบระหว่าง R1 และ G อนุญาตและลืมเกี่ยวกับการตรวจสอบระหว่าง R2 และ G ที่เคยทำมาก่อน

วิธีแก้ปัญหาที่คุณอาจทำได้คือการรวบรวมเวกเตอร์การกระจัดต่ำสุดทั้งหมดลงในอาร์เรย์หรือโครงสร้างข้อมูลใด ๆ ที่คุณต้องการและเลือกอันที่จะพิสูจน์ได้ว่าถูกต้องตามกฎหมายกับวัตถุทั้งหมด

โปรดทราบว่าในกรอบที่กำหนดวัตถุ (G เช่น) สามารถมีทิศทางเดียวเท่านั้น (โอ้มนุษย์เสียงเหมือนบอยแบนด์ ... )

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.