2D การแบ่งพาร์ติชันเป็นทางเลือกสำหรับแฮชเชิงพื้นที่และควอดทรี


11

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

ขนาดระดับของฉันไม่ควร จำกัด (เฉพาะ Int32 จำกัด ) ฉันต้องการอัลกอริทึมการแบ่งพาร์ติชันที่ไม่ต้องการ "ความกว้างระดับ" และ "ระดับความสูง"

ฉันมีวัตถุทางกายภาพที่เคลื่อนไหวมากมาย ฉันต้องการอัลกอริทึมที่เร็วพอที่จะรองรับวัตถุมากกว่า 500+

ทางเลือกใด ๆ

คำตอบ:


13

ต้นไม้แบบไดนามิก

Box2Dเป็นเครื่องมือดีที่สุดการออกแบบโดยมีประสบการณ์ฟิสิกส์เกม / โปรแกรมเมอร์ เดิมที Box2D ใช้ตารางแฮชที่ต้องการความสูงและความกว้างคงที่

เมื่ออีรินอัพเกรดเป็นอัลกอริธึมการแพร่กระจายสัญญาณที่ดีขึ้นเขาไปกับ btDbvt ของ Nathanael Presson นี่คือกว้างยาวที่ใช้โดยกระสุนฟิสิกส์ Erin ปรับเปลี่ยนและเพิ่มประสิทธิภาพอัลกอริทึมสำหรับ 2d

คุณสามารถอ่านภาพระดับสูงมากในคู่มือ Box2D (§4.11หรือค้นหา Dynamic Tree)

ต่อไปนี้เป็นข้อยกเว้นจากเอกสารในรหัส (ซึ่งถือว่าดีมากเพราะไม่ได้เป็นส่วนหนึ่งของ API สาธารณะ)

ต้นไม้ AABB แบบไดนามิกช่วงกว้างได้รับแรงบันดาลใจจาก Nathanael Presson btDbvt ต้นไม้แบบไดนามิกจัดเรียงข้อมูลในต้นไม้แบบไบนารีเพื่อเร่งการสืบค้นเช่นปริมาณการค้นหาและการฉายรังสี ใบไม้เป็นพร็อกซีที่มี AABB ในทรีเราขยายพร็อกซี AABB โดย b2_fatAABBFactor เพื่อให้พร็อกซี AABB มีขนาดใหญ่กว่าวัตถุไคลเอนต์ สิ่งนี้ช่วยให้วัตถุไคลเอนต์ย้ายตามจำนวนเล็กน้อยโดยไม่ทริกเกอร์การปรับปรุงทรี

โหนดถูกรวมและเปลี่ยนตำแหน่งดังนั้นเราจึงใช้ดัชนีโหนดแทนพอยน์เตอร์

ความเข้าใจของฉันเกี่ยวกับอัลกอริทึมของ Dynamic Tree คือสิ่งนี้ ต้นไม้แบบไดนามิกเป็นไม้กางเขนระหว่างต้นไม้ไบนารี avlคลาสสิกและควอดทรี ผลสุดท้ายคือควอดทรีที่แยกแต่ละโหนดเพียงครึ่งเดียวและเส้นแบ่งไม่คงที่ (สองครึ่งไม่เท่ากับขนาดเท่าต้นไม้รูปสี่เหลี่ยม) AVL เข้ามาเพราะ quadree ที่มีการแยกแบบไดนามิกสามารถทำให้ความเร็วในการค้นหารายการลดลง (O (n)) AVL ใช้เพื่อปรับสมดุลทรีย่อยดังนั้นเพื่อให้แน่ใจว่าความเร็วในการค้นหา O lg (N)

ส่วนที่ดีที่สุดของรหัสคือ MIT ดังนั้นอย่าลังเลที่จะคัดลอก / มา / ไร้ยางอาย / ฯลฯ


ดูเหมือน ... ซับซ้อน! ฉันจะดูมัน บางคนแนะนำให้ฉันใช้เทคนิค "การกวาดและลูกพรุน" หรือ "การเรียงลำดับและการกวาด" แต่ฉันไม่พบอะไรเกี่ยวกับการใช้ C # หรือ. NET ฉันพบตัวอย่าง c ++ แต่มันเกิดความสับสนและมันใช้งานไม่ได้ (ฉันพยายามที่จะใช้มัน) คุณคิดว่า SAP จะใช้งานได้ง่ายขึ้นหรือไม่ มีการใช้. NET หรือไม่?
Vittorio Romeo

8

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

ฉันพบปัญหาที่คล้ายกันและตัดสินใจที่จะสร้างโครงสร้างของตัวเองเพื่อจัดการข้อมูล มันขึ้นอยู่กับควอดทรี แต่มีขีด จำกัด (อย่างน้อยใหญ่เท่ากับ Int) ในทุกทิศทาง มันถูกออกแบบมาเพื่อจัดการกับข้อมูลแบบกริดที่ขยายจากจุดศูนย์กลางเหมือนกับที่ Minecraft ทำตอนนี้ มันเป็นพื้นที่ที่มีประสิทธิภาพในหน่วยความจำและรวดเร็วมาก

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


1

เมื่อทำงานกับวัตถุขนาดเล็ก (<หลายพันชิ้น) ที่ค่อนข้างเล็ก (วัตถุส่วนใหญ่ไม่ใหญ่พอที่จะชนกับวัตถุอื่น ๆ ได้จำนวนมาก) ฉันพบว่ารายการ x ที่เรียงลำดับอย่างง่ายของกล่องที่จัดเรียงตามแนวแกน (AABBs) ดีใช้ได้. ฉันเพิ่งวางวัตถุในรายการจากนั้นแต่ละเฟรมหลังจากเคลื่อนย้ายวัตถุฉันเรียงลำดับรายการอย่างรวดเร็วด้วยค่า x จากนั้นทำหนึ่งผ่านการตรวจสอบรายการสำหรับความใกล้เคียง AABB สำหรับแต่ละวัตถุฉันจะตรวจสอบกับวัตถุที่อยู่ข้างหน้าของมันในรายการจนกว่าฉันจะถึงจุดสิ้นสุดของรายการหรือวัตถุที่อยู่นอกช่วง x นั่นคือค่า x ของขอบด้านซ้ายคือ> ค่า x ของขอบด้านขวาของวัตถุที่กำลังทดสอบ โดยทั่วไปแล้วจะแบ่งพื้นที่ออกเป็นส่วน ๆ ที่ทับซ้อนกันบางครั้ง AABB-x- ขนาดความกว้าง มัน'


0

บางทีอัลกอริทึม r-treeคือสิ่งที่คุณกำลังมองหา

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


ฉันลองใช้งาน C # และประสิทธิภาพแย่เกินไปเมื่อ "ลบและเพิ่มวัตถุในตำแหน่งใหม่"
Vittorio Romeo

0

ฉันตัดสินใจที่จะไปกับกริด 2D แบบคงที่

ฉันได้ทำวิดีโอสองเรื่องที่อธิบายในเชิงลึกเกี่ยวกับวิธีการใช้งานและการใช้งานปัจจุบันมีอยู่ในหน้า GitHub ของฉัน: https://github.com/SuperV1234/SSVSCollision

http://www.youtube.com/watch?v=7HY_SqqaoL4

http://www.youtube.com/watch?v=vYB37BDtHuQ

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