การตรวจจับการชนกันแบบ 2D


11

สมมติว่าฉันใช้ตัวละครนี้

นก
(แหล่งที่มา: iconbug.com )

คุณจะใช้การตรวจจับการชนกันอย่างไร การใช้กล่องขอบไม่น่าจะเป็นการประมาณที่ดีเพราะรูปร่างของนกอยู่ใกล้กับสี่เหลี่ยม

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

แต่ปัญหาของฉันในแนวทางของฉันคือ:

  1. ฉันไม่ทราบวิธีการเริ่มต้นต้นไม้รูปสี่เหลี่ยม
  2. เมื่อเริ่มต้นต้นไม้รูปสี่เหลี่ยมแล้วฉันไม่แน่ใจว่าจะสำรวจและใช้งานได้อย่างไรเมื่อมีสิ่งกีดขวางภายในพิกัดของภาพ

คุณจะตรวจจับการชนกันของตัวละครที่ไม่ใช่รูปสี่เหลี่ยมได้อย่างไร?

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

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


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

ขอบคุณฉันวางแผนที่จะทำเช่นนั้น แต่ฉันไม่แน่ใจทั้งหมดว่าควรตรวจสอบแบบละเอียด :)
async

1
ไม่มีรายละเอียดที่สำคัญเพียงอย่างเดียว: คุณต้องการทำอะไรกับมัน คุณสนใจเรื่องการชนที่แน่นอนไหม? คุณมีความสุขที่จะประมาณตัวละครกับวงกลมหรือไม่? คุณต้องการให้อนุภาคฝุ่นชนกับดวงตาของตัวละครแยกจากส่วนที่เหลือหรือไม่?
Anko

@Anko คุณจะประมาณรูปร่างวงกลมได้อย่างไร ฉันสนใจเกี่ยวกับการชนกันที่แม่นยำพอสมควร - ไม่ได้ความแม่นยำของพิกเซลมาก
async

1
เช่นนี้ "ดี" และ "ธรรมชาติ" หมายถึงอะไร นี่เป็นคำถามเชิงปรัชญาหรือไม่?
Anko

คำตอบ:


12

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

อย่าซับซ้อนมากเกินไป

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


3
ใช่เพียงแค่สร้างรูปร่างเล็ก ๆ หลายรูปร่างถ้ารูปร่างเดียวไม่ครอบคลุม ตัวอย่างเช่น: i.imgur.com/Dd4yyGN.png
MichaelHouse

ขอบคุณ Jonkel & @ Byte56 การใช้รูปทรงเล็กน้อยดูเหมือนเป็นทางออกที่ถูกต้องในสถานการณ์ของฉัน ตรงไปตรงมาเพื่อใช้ถูกต้องและรวดเร็ว ไม่อยากจะเชื่อเลยว่าฉันกระโดดตรงไปที่ต้นไม้สี่ต้นโดยไม่พิจารณาสิ่งนี้! เอ่อ
async

วงกลม collider สำหรับร่างกายและสี่เหลี่ยมสำหรับจะงอยปากเพื่อความถูกต้องเป็นพิเศษ
Kroltan

14

กระบวนการตรวจสอบสองขั้นตอน

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

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

เนื่องจากภาพของคุณเป็น PNG (หรือรูปแบบไฟล์อื่น ๆ ที่มีช่องอัลฟา) จึงค่อนข้างง่าย

  1. คำนวณพื้นที่จุดตัดระหว่างวัตถุหนึ่งชิ้นในที่เกิดเหตุและนกสร้างรูปสี่เหลี่ยมผืนผ้าอย่างง่ายของจุดตัดทั้งสองภาพ
  2. ภายในจุดตัดตรวจสอบว่าแต่ละพิกเซลมีค่าอัลฟา> 0 ในภาพทั้งสอง
  3. หากมีพิกเซลดังกล่าวอยู่แสดงว่าคุณได้รับการชน ไม่เช่นนั้น

หากคุณดูที่ช่องอัลฟ่าของรูปภาพคุณสามารถดูว่ามันมีข้อมูลทั้งหมดที่คุณต้องการสำหรับการชนกันของพิกเซลอย่างสมบูรณ์แล้ว

ช่องอัลฟาจากภาพ

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

Anko แนะนำกล่อง "การปะทะกันโดยละเอียด" ที่ละเอียดยิ่งขึ้น:

กล่องขอบเขตรายละเอียดเพิ่มเติม

PS: ถ้าภาพของคุณมีรัศมี, เอฟเฟกต์หรือช่องอื่น ๆ ที่ไม่ใช่ 0 อัลฟ่ารอบ ๆ ภาพที่คุณไม่ต้องการชนกันคุณสามารถปรับขีด จำกัด อัลกอริทึมได้อย่างง่ายดายเพื่อรองรับ


1
ขอขอบคุณ! แต่ฉันไม่ต้องการความแม่นยำที่สมบูรณ์แบบของพิกเซล คำตอบที่ดีแม้ว่าจะมีประโยชน์ในภายหลัง
async

แน่นอนว่าเพื่อนร่วมกัน, การชนกันของพิกเซลที่สมบูรณ์แบบมักจะเป็น overkill เสมอยกเว้นในเกมที่ต้องการมันจริงๆ (เช่นนักสู้ 2D)
codemonkey

3

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


0

บางทีคุณสามารถใช้คอลไลเดอร์รูปหลายเหลี่ยม / ขอบบางชนิด

ไม่แน่ใจว่าสิ่งนี้จะทำงานอย่างไร แต่:

วัตถุสองชิ้น: วัตถุ 1: นก (o1), วัตถุ 2: สิ่งที่อาจตีนก (o2)

1) กำหนดรูปร่างที่มีขอบเขตซึ่งเป็นรูปหลายเหลี่ยมที่เหมาะกับวัตถุแรก (o1) ที่มีปัญหา

2) รับขอบของ o1 ที่ o2 ที่อาจชนกันได้โดยไม่ต้องกลัวที่จะทำได้น่ากลัวชนกันได้โดยไม่ต้องผ่าน o2 ผ่าน O1 หรือในทางกลับกัน

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

3) กำหนดว่าจุดใดจุดหนึ่งบนขอบของ o2 นั้นเหมือนกับจุดบนขอบใด ๆ ของ o1 ที่คุณเลือกในขั้นตอนที่ 2

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

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