Circle Circle Intersection ด้วย Sweep Line Algorithm


15

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

แบบฝึกหัดต่อไปนี้ที่ฉันพบในบันทึกการบรรยายของการแยกส่วนบรรทัดโดยเจฟฟ์เอริกผู้มีอำนาจทุกอย่าง

การออกกำลังกาย 2.อธิบายและวิเคราะห์อัลกอริทึม sweepline การกำหนดให้วงกลมในระนาบไม่ว่าจะเป็นที่สองตัดในO ( n log n )เวลา แต่ละวงกลมเอ็ดระบุไว้โดยศูนย์และรัศมีของมันเพื่อให้การป้อนข้อมูลที่ประกอบด้วยสามอาร์เรย์X [ 1 .. n ] , Y [ 1 .. n ]และR [ 1 .. n ] ใช้ความระมัดระวังอย่างถูกต้องใช้ดั้งเดิมในระดับต่ำnO(nlogn)X[1..n],Y[1..n]R[1..n]

ลองทำสิ่งที่ซับซ้อนให้ง่ายขึ้น เรารู้อะไรเกี่ยวกับจุดตัดของวงกลม อะนาล็อกที่สามารถพบได้ด้วยการตัดกันของเส้น เส้นสองเส้นอาจตัดกันหากพวกมันอยู่ติดกันซึ่งสองวงควรมีคุณสมบัติใดเพื่อตัดกัน ให้เป็นระยะทางระหว่างศูนย์กลางของวงกลมr 0และr 1ศูนย์กลางของวงกลม พิจารณาบางกรณี:dr0r1

  • กรณีที่ 1: ถ้าว่าไม่มีวิธีแก้ปัญหาวงกลมจะแยกกันd>r0+r1

  • กรณีที่ 2: ถ้าดังนั้นจึงไม่มีวิธีแก้ปัญหาเนื่องจากมีวงกลมหนึ่งวงอยู่ในอีกวงหนึ่งd<|r0r1|

  • กรณีที่ 3: ถ้าและr 0 = r 1ดังนั้นวงกลมจะเกิดขึ้นพร้อมกันและมีวิธีแก้ปัญหาจำนวนไม่ จำกัดd=0r0=r1

ดังนั้นดูเหมือนว่าเงื่อนไขการแยกพร้อมแน่นอนว่าอาจเป็นเงื่อนไขที่ผิด โปรดแก้ไขหากเป็นเช่นนั้น

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

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

ภาคผนวก :

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


4
มีอำนาจทุกอย่าง [อ้างอิงที่จำเป็น]
JeffE

@com คุณหมายถึง "วงกลมก่อนหน้าที่ใกล้ที่สุด"
Joe

1
ฉันสันนิษฐานว่าstatusรักษาวงกลมที่ตัดกับเส้นกวาดอยู่หรือไม่? สมมติว่าคุณมี 100 แวดวงในขณะนี้statusและคุณประมวลผลเหตุการณ์การแทรกและแทรกวงกลมที่ 101 คุณเปรียบเทียบกับแวดวงจำนวนเท่าใดเพื่อตรวจหาจุดตัด คุณเลือกแวดวงที่จะเปรียบเทียบอย่างไร
Joe

@ โจนี่คือสิ่งที่ฉันต้องการอย่างเช่นในอัลกอริธึมบรรทัดการกวาดแบบคลาสสิกโดยที่ "จุดตัดของสองบรรทัดแสดงถึงการใช้คำหยาบคายของสองบรรทัดนี้ในบางจุด" ฉันต้องหาอะนาล็อกที่คล้ายกันกับวงกลม สิ่งที่ง่ายฉันมาพร้อมกับเป็นต่ำสุดประสานงานและYสูงสุดประสานงานของวงกลมถ้าวงกลมตัดประมาณการของพวกเขาในช่วงเวลาจากต่ำสุดYไปสูงสุดYควรตัดไป ดังนั้นบางทีตอนนี้ฉันใกล้ชิดกับความคิดของคุณครึ่งวงกลม semicircles ดังกล่าวข้างต้นมีสูงสุดY , และด้านล่างมีต่ำสุดปี YYYYYY
com

คำตอบ:


5

คุณอยู่ในเส้นทางที่ถูกต้องแน่นอน คำถามใหญ่คือเมื่อคุณแทรกวงกลมคุณจะตรวจสอบว่ามีวงเวียนใดอีกวงหนึ่ง คุณจะตรวจสอบนี้ได้อย่างไร

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

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

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

ลองแทนวงกลมเป็นวงกลมสองวง แต่ละเหตุการณ์แทรกเป็นสองเหตุการณ์จริง ๆ : แทรกครึ่งบนและแทรกครึ่งล่าง


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

@com คุณต้องมีจุดกึ่งกลางและรัศมีเพื่อกำหนดว่าวงกลมสองวงตัดกันหรือไม่ตามที่คุณได้ทำในการตรวจสอบทางแยกของคุณเอง เพียงพิกัด y และรัศมีเพียงอย่างเดียวไม่ได้ระบุขอบเขตของวงกลมอย่างเต็มที่ ดูเหมือนจะมีบางสิ่งพื้นฐานเกี่ยวกับอัลกอริทึมการกวาดบรรทัดที่คุณไม่เข้าใจ แต่มันยากสำหรับฉันที่จะบอกว่ามันคืออะไร
โจ

0

ฉันคิดว่าวิธีนี้คล้ายกับการกวาดล้าง Bentley Ottmann ที่ทำงานในเวลา O ((n + k) logn)

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

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

เนื่องจากปัญหาการตัดกันของเส้นสามารถแก้ไขได้ในเวลา O ((n + k)) การเข้าเล่มเดียวกันจึงตามมาสำหรับการตัดกันวงกลมเช่นกัน

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

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