ฝ่ายอักษะในแนวแกน: แบ่งพื้นที่ออกเป็นสี่เหลี่ยมผืนผ้าสุ่ม?


11

ฉันต้องการวิธีการแบ่งพื้นที่ 3 มิติเป็นรูปร่างกล่องที่จัดแนวแกนแบบสุ่ม ตอนนี้ฉันกำลังแบ่งพื้นที่ 2d สำหรับการทดสอบ วิธีที่ฉับพลันที่สุดที่ฉันคิดขึ้นมาคือการกำหนดขนาดสี่เหลี่ยมผืนผ้า (1, 1) แล้วแบ่งสี่เหลี่ยมที่มีอยู่ทั้งหมดกลับเป็นรูปสี่เหลี่ยมผืนผ้าไม่สม่ำเสมอสองอันสลับกันระหว่างแกน X และ Y

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

ปัญหาที่นี่ชัดเจน วิธีการนี้ส่งผลให้เส้นยืดยาว (ทำเครื่องหมายด้วยสีแดง)

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

สิ่งที่ฉันต้องการคือสิ่งที่ดูเป็นธรรมชาติมากขึ้น (ฉันรวมตัวอย่าง)

ดูไม่มีเส้นตรงยาวจากบนลงล่างหรือจากซ้ายไปขวา

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

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

ดังนั้นขั้นตอนวิธีควรเป็นไปตามข้อ จำกัด ทั้งสามดังต่อไปนี้:

  1. รูปสี่เหลี่ยมผืนผ้ามีขนาดเล็กไม่เล็ก
  2. ขนาดของรูปสี่เหลี่ยมไม่ได้เป็นการคูณแบบแยกขนาดที่เล็กที่สุด เช่นถ้า rect ที่เล็กที่สุดคือ 3 square unit มากกว่า rects ที่ใหญ่กว่าจะไม่ถูก จำกัด ให้เป็น 6, 9, 12 และอื่น ๆ square square และแทนที่จะเป็น 3.2 หรือ 4.7 สำหรับเรื่องนั้น)
  3. อัลกอริทึมทำงานในเวลาพหุนาม (ต้องคำนวณเร็ว)

คำตอบ:


12

วิธีการที่คุณร่างนั้นง่ายและมีประโยชน์ แต่ทนทุกข์ทรมานจากสิ่งประดิษฐ์ที่น่ากลัวดังที่แสดง หลีกเลี่ยงมัน. คุณต้องใช้อัลกอริธึมการเติบโตแบบขนาน สำหรับโมเดลแบบเธรดเดี่ยววิธีการแบบวนรอบจะเป็นดังนี้:

  1. วางจุดต่าง ๆ ในพื้นที่แผนที่ของคุณแบบสุ่ม ปกติการกระจายของพวกเขา (หลีกเลี่ยงการจัดกลุ่มที่น่าเกลียด) โดยใช้การกระจายเสียนหรือโดยการใช้ขั้นตอนวิธีการผ่อนคลายซ้ำที่จะย้ายจุดวางสุ่มห่างจากอีกคนหนึ่งตามลอยด์ผ่อนคลายสำหรับแผนภาพโวโรนอย คะแนนเหล่านี้แสดงถึง centroids ของห้องของคุณ
  2. (ขนาน / วนรอบโรบินซ้ำสำหรับทุกห้อง) จากจุดแต่ละจุดให้ขยายออกไปด้านบน 4 จุด (ห้องสี่เหลี่ยม) ย้ายจากจุดกึ่งกลางต่อการวนซ้ำทั่วโลก (คุณสามารถเติบโตห้องที่แตกต่างกันในอัตราที่แตกต่างกันในแต่ละแกน ทั้งหมดและดูว่าสิ่งนี้เกิดขึ้นได้อย่างไรอาจเป็นไปได้ที่จะได้ผลลัพธ์ที่เป็นอินทรีย์ / หลากหลายมากขึ้น) เมื่อถึงจุดหนึ่งสี่เหลี่ยมบางรูปของคุณจะเริ่มกดกัน เมื่อถึงจุดนั้น จำกัด การเติบโตในแกนนั้นให้แน่ใจว่าขอบของห้องทั้งสองนั้นสัมผัสกันอย่างแน่นอนแล้วเดินหน้าต่อไป
  3. ทำซ้ำขั้นตอนที่ 2 เพิ่มขึ้นทุกห้องทีละส่วนจนกว่าการเติบโตทั้งหมดจะถูก จำกัด โดยห้องพักที่อยู่ติดกันหรือขอบเขตของแผนที่
  4. นี่จะยังคงเว้นว่างไว้บ้าง ปัญหานี้กลายเป็นหนึ่งในการค้นหาและทำให้ห้องพักไม่มีที่ว่าง ในความเป็นจริงถ้าพื้นที่พื้นฐานของคุณเป็นตาราง (จำนวนเต็มดัชนี) (และทุกการทำซ้ำการเจริญเติบโตยึดกับตารางนั้น) แล้วมันจะง่ายต่อการจัดการเพราะคุณสามารถรักษารายการของตารางเซลล์ว่างและไม่ว่าง: เมื่อคุณ ' วางและขยายห้องทุกห้องค้นหารายการที่ว่างสำหรับช่องว่างที่ไม่ต่อเนื่องซึ่งประกอบด้วยกลุ่มของเซลล์ที่อยู่ติดกัน เนื่องจากช่องว่างที่ไม่ได้ใช้งานจำนวนมากจะมีรูปทรงที่ไม่ใช่รูปสี่เหลี่ยมผืนผ้าคุณจะต้องเลือกเซลล์โดยการสุ่มจากภายในพื้นที่ที่ไม่ใช่รูปสี่เหลี่ยมผืนผ้านั้นและขยายให้มีขนาดสูงสุดเท่าที่คุณทำกับห้องในขั้นตอนที่ 2 - เว้นช่องสี่เหลี่ยมจนเต็ม
  5. ทำซ้ำขั้นตอนที่ 4 จนกระทั่งแผนที่ของคุณถูกครอบครอง 100%

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

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

คุณถูก! ฉันคิดว่าฉันเขียนส่วนนั้น แต่ฉันไม่ได้ ฉันขอโทษสำหรับความผิดพลาดนี้ ใช่ฉันรู้ขนาดกริดแล้ว ห้องสามารถมีขนาดเล็กเท่าที่กริดอนุญาต
AturSams

ตกลง - หวังว่าคุณจะพบทางออกที่เหมาะสม BTW ฉันหมายถึง "ปรับเส้นกริด" ไม่ใช่ "ปรับแกน"
วิศวกร

1
จริงๆแล้วฉันกำลังทำอะไรบางอย่างเหมือนกับที่อยู่บนพื้นฐานของแนวคิดที่คุณคิดว่าฉัน ฉันจะโพสต์ผลลัพธ์ที่นี่เช่นกัน
AturSams

2

อย่างที่คุณเห็นฉันพยายามกำจัดโลกของสิ่งประดิษฐ์เหล่านี้ ความคิดคล้ายกันมาก

  1. แบ่งช่องว่าง 2d เป็นกริดที่ไม่สม่ำเสมอ หากสองบรรทัดใกล้เกินไปให้ลบออกหนึ่งบรรทัด
  2. เลือกสี่เหลี่ยมผืนผ้าโดยการสุ่มตรวจสอบว่ามีการปรับเปลี่ยนข้ามแกน -y (สูง) หรือไม่และมีการแก้ไขเพื่อนบ้านโดยตรงในแกน -y หรือไม่ ฉันทั้งสองไม่ได้ถูกแก้ไขให้พวกเขาเจรจาต่อรองส่วนระหว่างพวกเขา (หนึ่งจะบริจาคพื้นที่บางส่วนไปยังอีก)
  3. ทำเช่นเดียวกับในขั้นตอนที่ 2 เฉพาะเวลานี้บนแกนอื่น ๆ
  4. ทำซ้ำจนกว่าคุณจะแก้ไขมากที่สุด

ตารางไม่สม่ำเสมอ (1):

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

เจรจาต่อรองบนแกน x (2):

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

การเจรจาต่อรองบนแกน y (3):

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

ผล (4):

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

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


สิ่งนี้ได้รับแรงบันดาลใจมาจากข้อมูลเชิงลึกจาก @Nick Wiggill
AturSams

2
หนึ่งสามารถปรับปรุงเพิ่มเติมเกี่ยวกับเรื่องนี้โดยการสุ่มกลุ่มแรกของเซลล์ที่อยู่ติดกัน n * m เป็นสี่เหลี่ยมเดียว มาสก์นี้จะซ่อนกริดพื้นฐานที่สามารถมองเห็นได้ในผลลัพธ์ด้านบน การเจรจากับสี่เหลี่ยมที่ใหญ่กว่านี้ต้องทำงานกับเซลล์ทั้งหมดตามขอบด้านใดด้านหนึ่ง
DMGregory

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

@ DMGregory ฉันพิจารณาสิ่งนี้ แต่ฉันต้องการอัตราส่วนระหว่าง rects ขนาดเล็กและ rects ขนาดใหญ่ให้สอดคล้องกันบ้าง ถ้านี่เป็นพื้นผิวหรือระดับฉันจะทำแน่นอน (จริง ๆ แล้วมีตัวอย่างก่อนหน้านี้ที่ทำอย่างนั้น)
AturSams

@NickWiggill ฉันสามารถกำจัดเส้นโคลิเนียร์ได้อย่างสมบูรณ์ มันเป็นเพียงเรื่องของการปรับแต่งอัลกอริทึม จะต้องมีวิธีการปรับปรุงเพิ่มเติม (อัปเดตด้วยรูปแบบที่เปลี่ยนแปลงล่าสุด)
AturSams
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.