ค้นหาพื้นที่ปิดล้อม (พื้นผิว) จากชุดของเส้น

ฉันกำลังพยายาม "เติม" พื้นที่ทั้งหมดในโค้ดของฉันที่ล้อมรอบด้วยบรรทัด (เซ็กเมนต์) โดยอัตโนมัติ

สิ่งที่ฉันมีคือตารางที่มีขนาดคงที่ (x,y) ในพื้นที่ 2 มิติ และรายการเส้นที่กำหนดโดยจุดเริ่มต้นและจุดสิ้นสุด เส้นเหล่านี้ไม่จำเป็นต้องปิดช่องว่าง

ตัวอย่างภาพ

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

ฉันจะค้นหาพื้นที่เหล่านี้โดยใช้อัลกอริทึมได้อย่างไร


person Frank v Hoof    schedule 31.05.2018    source แหล่งที่มา
comment
อย่างไรก็ตาม ฉันได้ติดตั้งโค้ดสำหรับการค้นหาจุดตัดกัน ฯลฯ แล้ว ดังนั้นฉันจึงไม่ได้มองหาความช่วยเหลือใด ๆ ในการค้นหาสิ่งเหล่านั้น เพียงแค่พื้นที่ที่ล้อมรอบด้วยเส้นเท่านั้น   -  person Frank v Hoof    schedule 31.05.2018
comment
ในขณะที่คุณพูดถึงบรรทัดจากรูปภาพ ดูเหมือนว่าคุณกำลังอ้างถึงส่วนต่างๆ ซึ่งทำให้เป็นปัญหาที่แตกต่างไปจากเดิมอย่างสิ้นเชิง แล้วคุณหมายถึงอันไหนจริงๆ?   -  person sbeliakov    schedule 31.05.2018
comment
อันที่จริงฉันหมายถึงส่วนของเส้นตรง เส้นนั้นไม่ได้มีความยาวไม่สิ้นสุด แต่จะมีตั้งแต่จุดเริ่มต้นจนถึงจุดสิ้นสุดเท่านั้น   -  person Frank v Hoof    schedule 31.05.2018


คำตอบ (2)


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

สมมติว่าส่วนของเส้นตรงตั้งชื่อด้วยตัวอักษร (A, B, C, ...)

ฉันจะเริ่มต้นด้วยการสร้างตารางที่ให้คุณค้นหาทางแยกตามส่วนของเส้นตรง

A -> B
A -> C
A -> D
B -> A
C -> A
C -> D
D -> A

(ในตัวอย่างนี้ ACD จะสร้างพื้นที่สามเหลี่ยม และ B เป็นเพียงส่วนของเส้นตรงที่ตัดขวาง A)

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

เนื่องจาก B ไม่มีทางแยกอีกต่อไป เราจึงย้อนกลับไปดูทางแยกถัดไปของ A ซึ่งอยู่ที่ทางแยกแรกของ C C อยู่ที่ทางแยกแรกกับ A ซึ่งทำให้วงจรสมบูรณ์ แต่มีเพียงสองขั้นตอนเท่านั้น จึงไม่ใช่พื้นที่ที่ถูกต้อง แต่จุดตัดถัดไปของ C คือ D และจุดตัดแรกของ D คือ A ซึ่งทำให้วงจรสามขั้นตอนสมบูรณ์ ดังนั้นตอนนี้เรามีพื้นที่ที่ถูกต้องแล้ว โดยเฉพาะรูปสามเหลี่ยม พื้นที่ถูกกำหนดโดยจุดตัดที่เราใช้ในวงจรของเรา: Pac, Pcd, Pda

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

person Adrian McCarthy    schedule 31.05.2018
comment
หลังจากลองใช้สิ่งนี้ ผมก็เข้าใกล้แล้ว แต่ยังไม่ถึงจุดนั้น เพื่อวัตถุประสงค์ในการทดสอบ ฉันใช้ตัวอย่างต่อไปนี้: ลิงก์ ซึ่งส่งคืน 67! พบพื้นที่ สิ่งเหล่านี้บางส่วนไม่ถูกต้อง เคลื่อนข้ามบรรทัดที่ไม่มีอยู่จริง รหัสของฉัน: ลิงก์ - person Frank v Hoof; 04.06.2018
comment
ตัวอย่างพื้นที่ที่ไม่ถูกต้องที่พบคือ: ตั้งแต่ (7.0, 0.0, 8.5) ถึง (6.5, 0.0, -4.5) ตั้งแต่ (6.5, 0.0, -4.5) ถึง (0.5, 0.0, -4.5) ตั้งแต่ (0.5, 0.0, -4.5) ถึง (0.5, 0.0, 8.8) จาก (0.5, 0.0, 8.8) ถึง (-6.0, 0.0, 9.0) จาก (-6.0, 0.0, 9.0) ถึง (-6.0, 0.0, -4.5) - person Frank v Hoof; 04.06.2018
comment
หลังจากได้รับคำแนะนำจากเพื่อน (ให้พลิกกลับและดูที่ทางแยกแทนเส้น) ฉันสามารถใช้อัลกอริธึมวงจรอย่างง่ายของ Johnson สำหรับกราฟที่ไม่มีทิศทางเพื่อค้นหาวงจรทั้งหมด ขอบคุณสำหรับความช่วยเหลือ - person Frank v Hoof; 15.06.2018

มีบางสิ่งที่เรียกว่า ทฤษฎีเชือกผูกรองเท้า ถ้าฉันเข้าใจว่าคุณต้องการพื้นที่ใน ภูมิภาคที่แรเงา จะกำหนดพื้นที่ของ รูปหลายเหลี่ยม เมื่อคุณพบทางแยกที่ให้จุดต่างๆ แล้ว คุณจะพบจุดปิดล้อม พื้นที่. อีกทางหนึ่ง มี อัลกอริธึมตัวถังแบบนูน เหล่านี้ยิ่งกว่า มีประสิทธิภาพ

    # Area of Polygon using Shoelace formula
# http://en.wikipedia.org/wiki/Shoelace_formula
# FB - 20120218
# corners must be ordered in clockwise or counter-clockwise direction
def PolygonArea(corners):
    n = len(corners) # of corners
    area = 0.0
    for i in range(n):
        j = (i + 1) % n
        area += corners[i][0] * corners[j][1]
        area -= corners[j][0] * corners[i][1]
    area = abs(area) / 2.0
    return area

# examples
corners = [(2.0, 1.0), (4.0, 5.0), (7.0, 8.0)]
print PolygonArea(corners)
corners = [(3.0, 4.0), (5.0, 11.0), (12.0, 8.0), (9.0, 5.0), (5.0, 6.0)]
print PolygonArea(corners)


let N           = number of points
let points[N+1] = the array of points
swap points[1] with the point with the lowest y-coordinate
sort points by polar angle with points[1]

# We want points[0] to be a sentinel point that will stop the loop.
let points[0] = points[N]

# M will denote the number of points on the convex hull.
let M = 1
for i = 2 to N:
    # Find next valid point on convex hull.
    while ccw(points[M-1], points[M], points[i]) <= 0:
        if M > 1:
            M -= 1
            continue
        # All points are collinear
        else if i == N:
            break
        else
            i += 1

    # Update M and swap points[i] to the correct place.
    # This code is wrong as explained in the talk page. When M and i are the same, the algorithm ends up in an infinite loop.
    M += 1
    swap points[M] with points[i]
person Community    schedule 31.05.2018