วิธีที่ดีที่สุดในการจัดการการชนพร้อมกันในเครื่องมือฟิสิกส์คืออะไร?


13

ฉันเขียนเอนจิ้นฟิสิกส์ 2d ใน javascript เพื่อให้ฉันสามารถเรียนรู้เพิ่มเติมเกี่ยวกับฟิสิกส์ในวิดีโอเกม ฉันให้มันทำงานอย่างถูกต้องสำหรับการชนกันของร่างกายที่แข็งยกเว้นถ้าร่างกายใด ๆ ชนกับร่างกายสองคนหรือมากกว่าในเวลาเดียวกัน

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

ฉันสามารถสำรวจวิธีใดเพื่อให้เครื่องยนต์ทำงานกับวัตถุ 3+ ที่ชนกัน


2
ที่เกี่ยวข้อง: gamedev.stackexchange.com/questions/15836/…และgamedev.stackexchange.com/questions/26181/และฉันแน่ใจว่ามีอีกมากฉันไม่สามารถหาได้ในขณะนี้
MichaelHouse

คำตอบ:


11

ฉันใช้วิธีการต่อไปนี้ (คล้ายกับอัลกอริทึมการแยกจำนวนมากของ Tonge http://www.richardtonge.com/ ):

  • ตรวจจับคู่ที่ชนกันทั้งหมดในฉาก / บริบทของคุณ ให้ (A, B) เป็นคู่เช่นนี้ ใช้แนวคิดแยกผี / มวล: ถ้า A อยู่ในการสัมผัสกับ M เนื้อความและ B สัมผัสกับ N วัตถุอื่นแล้วตั้งค่ามวลของ A เป็นและA ของ B เป็นการชั่วคราวm_A/Mm_B/N
  • คำนวณปฏิกิริยา / การชดเชยแรงที่เกิดขึ้นสำหรับแต่ละคู่ (A, B) และเก็บการมีส่วนร่วมเหล่านี้ในตัวสะสม A และ B ของตัวเอง
  • คำนวณความเร็วในการซ่อมแซมจากแรงกระตุ้น (ตามที่คุณระบุไว้) และเก็บไว้ในแบบเดียวกัน (ในขณะที่deltaVความเร็วตกค้างในตัวสะสมของพวกเขาสำหรับแต่ละคู่ (A, B))
  • คำนวณการกำจัดการลงโทษ (อีกครั้งสะสมการกระจัดกระจายอย่าใช้พวกเขาทันที!)
    • รีเซ็ตมวลของวัตถุทั้งหมดที่กำหนดไว้ก่อนหน้านี้เป็นฝ่ายในคู่ชน ( m_A = m_A * Mและm_B = m_B * N)

วิธีนี้คล้ายกับวิธีการทำงานซ้ำของ Jacobi กับระบบเชิงเส้นพร้อมกันของสมการ และมันก็ไม่ได้รับประกันว่าจะมาบรรจบกัน แต่ในเครื่องจำลองของฉันมันทำงานได้อย่างราบรื่นมาก .. ในแบบ 3 มิติ (ใช่มิติพิเศษเพิ่มความยากเป็นสองเท่า!)

Caveat : ตำแหน่งและความเร็วที่ถูกต้องเฉพาะหลังจากขั้นตอนการตรวจจับ / จัดการการชนของคุณจบลงแล้ว! ด้วยวิธีนี้คุณจะอัพเดตตัวแสดงการชนของคุณพร้อมกัน นอกจากนี้ยังต้องพิจารณาถึงการบังคับใช้การซ่อมแซมในครั้งต่อไปเมื่อคุณรวมตำแหน่งและความเร็ว

แก้ไข: ดีฉันเดาว่าคุณใช้วิธีการรวม Verlet ที่ถูกทารุณกรรมแล้ว ในสถานที่น่ากลัวของการจัดการและบูรณาการการปะทะกันนี้คุณอาจต้องการที่จะดูที่นี่

ปรับปรุง: ข้อมูลบางส่วนเกี่ยวกับวิธีการชน (และการชนกันของตนเองสำหรับเรื่องจริง) สามารถพบได้ในเอกสารเหล่านี้:

วิธีที่ฉันเสนอไม่ใช่การสนับสนุนที่มีมานาน แต่หลายเกมใช้มันกับผลลัพธ์ที่เป็นไปได้

จากประสบการณ์ในทางปฏิบัติกองกำลังลงโทษ (คล้ายกับน้ำพุเชิงเส้นหรือเลขชี้กำลังได้รับข้อมูลจากระยะการเจาะ) ไม่สามารถแก้ไขการแทรกซึมได้อย่างถูกต้องเมื่อกองกำลังอื่นจากร่างกายที่ปะทะกันจัดการได้มากกว่าพวกเขา นั่นเป็นเหตุผลที่ฉันเลือกที่จะรวมสามวิธี (เกือบซ้ำซ้อน): แรงปฏิกิริยาของนิวตัน (คุณดันกำแพงกำแพงพุ่งกลับ) แรงกระตุ้นที่ได้มา (ลูกสนุ๊กเกอร์ชน) และไม่ใช่ธรรมชาติ "ขยับร่างกายออกจากกันในเชิงเรขาคณิต " วิธีการแก้. ดูเหมือนว่าพวกเขาจะให้ทุกสิ่งด้วยกัน: กำจัดส่วนใหญ่วัตถุแทรกซึมน่าเกลียดวัตถุที่ปะทะกันมีแนวโน้มที่จะมีปฏิสัมพันธ์ซึ่งกันและกันในระยะยาว (เนื่องจากการชดเชยความเร็วและแรง - อย่างน้อยแรงที่มีแนวโน้มว่าจะลากศพในสถานการณ์การปะทะกันจะถูกยกเลิกและร่างกายจะเด้งออกจากกันและกัน) . สุดท้ายสำหรับการทำความเข้าใจต่อไปของแนวคิดที่เรียบง่าย แต่พบบ่อยเหล่านี้ผมขอแนะนำให้วิเคราะห์ภาพนิ่งเหล่านี้

"วิธีการที่ถูกทารุณกรรม" ฉายาของฉันที่อธิบายขั้นตอนการรวม Verlet นั้นมีเป้าหมายที่ความเชื่อทางวัฒนธรรมที่เป็นที่นิยมว่านี่คือ Holy Grail ของวิธีการรวม มันเป็นเพียงเล็กน้อยดีกว่า Symplectic Euler (หรือเรียกอีกอย่างว่าลูกพี่ลูกน้องออยเลอร์กึ่งนัย) มีวิธีการรวมที่ซับซ้อนมากขึ้น (และทุกคนมีชื่อโดยนัยในนั้น) เอ็นจิ้นเกมที่ทรงพลังใช้ประโยชน์จากมันได้ แต่นักพัฒนาอินดี้ไม่มีเวลาที่จะทดสอบกับสิ่งเหล่านั้นตั้งแต่ Verlet เมื่อปรับไปยังสถานการณ์เฉพาะ นอกจากนี้ยังไม่มีวิธีการรวมที่สามารถจัดการกับข้อ จำกัด ที่แข็งโดยไม่ต้องมีการโกงเล็ก ๆ น้อย ๆ (ไม่สามารถหาลิงค์ได้ แบบจำลองสปริงเพื่ออธิบายพฤติกรรมของผ้าแข็ง "


ขอบคุณ (+1)! 'ความเร็วการชดใช้ความเสียหาย' และ 'การกำจัดการลงโทษ' คืออะไร นอกจากนี้ทำไมคุณถึงพูดว่าการรวม verlet นั้นถูก 'ทำร้าย'? คุณคิดว่าเป็นวิธีที่ไม่ดีในการใช้งานหรือไม่?
Cam

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

1
คำตอบที่ยอดเยี่ยม! ฉันมีคำถามอื่นว่า สมมติว่าฉันสะสมความเร็วในการชดใช้พวกเขาจะไม่บวกมันเป็นจำนวนที่ไม่สมจริงใช่ไหม? หากฉันปฏิบัติต่อการชนกันของวัตถุ A แยกกันและเพิ่มเอฟเฟกต์ในแต่ละวัตถุจะไม่ A ไม่มีแรงกระตุ้นที่กระจายระหว่างวัตถุหรือไม่ แรงกระตุ้นเต็มรูปแบบจะถูกนำไปใช้กับแต่ละข้อซึ่งดูเหมือนว่าจะผิดกับฉันอย่างสังหรณ์ใจ
Cam

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

3
บางทีฉันอาจไม่เข้าใจสิ่งที่คุณอธิบายเพราะตัวอย่างต่อไปนี้ยังเกี่ยวข้องกับฉัน: พิจารณาสี่เหลี่ยมผืนผ้าที่มีความยาวแนวนอนล้มลงและสมมติว่าพื้นขรุขระ หากมีสามเหลี่ยมสามอันใช้วิธีการสะสมของคุณสี่เหลี่ยมจะเด้งกลับมาที่ n เท่าความเร็วที่ควร! สถานการณ์นั้นจะแก้ไขได้อย่างไร?
แคม

1

ฉันขอแนะนำว่าแทนที่จะเปลี่ยนความเร็วคุณเปลี่ยนแรงที่กระทำกับวัตถุ อย่า "เขยิบ" ออกไปทำอย่างราบรื่นและใช้โค้ดที่มีอยู่แล้ว โดยการทำเช่นนี้ร่างกายจะไม่เปลี่ยนแปลงทันที (และอย่างรวดเร็วฉันคิดว่า)

ตรวจสอบ Box2DJS สำหรับตัวอย่าง: http://box2d-js.sourceforge.net/index2.html


-1

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

วิธีแก้ปัญหาสำหรับการติดต่อกลุ่มนั้นไม่ยากกว่าการติดต่อเพียงครั้งเดียว น่าเสียดายที่ฉันทำกระดาษคำนวณหายไปดังนั้นจึงไม่สามารถแชร์ได้ที่นี่

แก้ไข: อาจเป็นไปได้ว่าฉันได้รับสิ่งนี้/physics/296767/multiple-colliding-balls

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