[ข้อสงวนสิทธิ์: ฉันคิดว่าสิ่งต่อไปนี้ควรใช้งานได้ แต่ไม่ได้เข้ารหัสด้วยตนเองจริง ๆ ]
ฉันไม่สามารถคิดถึงวิธี "เล็กน้อย" ในการสร้างคำตอบใช่ / ไม่ใช่ แต่ต่อไปนี้จะเป็นวิธีการที่สมเหตุสมผลในการแก้ปัญหาที่ใช้งานได้จริง
สมมติว่าส่วนโค้งของเราคือA (s)และB (t) ที่มีจุดควบคุม { A0, A1..An } และ { B0, .. Bm } ตามลำดับ
สำหรับผมแล้วดูเหมือนว่าด้วย 2D Beziers ที่เราต้องการตรวจสอบว่าทำหรือไม่ตัดกันมีหกกรณีที่ต้องพิจารณา:
กรณีที่เราสามารถ "บังเอิญ" ได้ว่าพวกเขาไม่ตัดกัน
กรณีที่พวกเขาตัดกันจำนวนครั้งที่ จำกัด และเราสามารถ "ง่าย" กำหนดว่าพวกเขาตัดกันอย่างน้อยหนึ่งครั้ง (แต่เราไม่สนใจว่าจะเกิดการแยกที่ใด)
หนึ่งใน Beziers เสื่อมโทรมคือจุด (ซึ่งจะเกิดขึ้นหากจุดควบคุมทั้งหมดเหมือนกัน) เราสามารถสมมติว่าเราจัดการกรณีที่ทั้งสองเป็นจุดแล้ว
มีการปิดโค้งอย่างน้อยหนึ่งเส้นเช่น A0 == เพื่อให้ชีวิตง่ายขึ้นเราจะแบ่งเส้นโค้งดังกล่าวแล้วเริ่มใหม่อีกครั้ง
มีจำนวนจุดตัดที่ไม่สิ้นสุดเนื่องจากแต่ละจุดย่อยของ "แม่" Bezier และซ้อนทับกัน
เราไม่แน่ใจเกี่ยวกับกรณีข้างต้นและต้องการการตรวจสอบเพิ่มเติม
สำหรับช่วงเวลาที่เราจะละเว้น 3 และ 4 แต่กลับมาหาพวกเขาในภายหลัง
กรณีที่ 1
ในขณะที่คุณพูดถึงคำถามของคุณหากกล่องที่เกี่ยวข้องของจุดควบคุมของAและB ) อย่าตัดกันดังนั้นเส้นโค้งจึงไม่สามารถตัดกันได้ เห็นได้ชัดว่านี่คือการทดสอบการปฏิเสธอย่างรวดเร็ว แต่มันเป็นแบบอนุรักษ์นิยมมากเกินไป อย่างที่คุณอาจทราบว่าด้วยเส้นโค้ง Bezier ตัวเรือนูนของจุดควบคุมนั้นจะมีลักษณะเป็น (แน่น) ลงบนโค้ง เราสามารถใช้เทคนิคแกนแยกเพื่อตัดสินใจว่าลำเรือของAและBไม่ตัดกันหรือไม่ (เช่นที่แสดงใน Wikipedia :)
กรณีที่ 2
หากการทดสอบกรณีที่ 1 ล้มเหลวคุณสามารถตรวจสอบการมีอยู่ของ "จุดตัด" เล็กน้อย ขณะนี้มีวิธีที่ดีกว่าในการทำเช่นนี้ แต่วิธีการดังกล่าวค่อนข้างถูกเกิดขึ้นกับฉัน:
พิจารณาเพียงการโค้ง A:
เรารู้ว่าเส้นโค้งเริ่มต้นที่ A0สิ้นสุดที่เวลา Anและจะอยู่ข้างในตัวเรือนูน เพื่อความง่ายให้เราคำนวณทิศทางของส่วนของเส้นตรงA0An¯¯¯¯¯¯¯¯¯¯¯¯ และคำนวณขอบเขตทั้งสองด้าน (เช่นนำผลิตภัณฑ์ดอทของจุดควบคุมที่เหลือเทียบกับตั้งฉากกับ A0An¯¯¯¯¯¯¯¯¯¯¯¯)
หากเราทำเช่นเดียวกันกับเส้นโค้ง B เราจะได้รับกรณี (เป็นไปได้) ต่อไปนี้:
หากเราพบ A0 และ Anอยู่นอกขอบเขตตรงข้ามของ B และนั่นB0 และ Bm อยู่ด้านนอกของขอบเขตของ A จากนั้นโดยความต่อเนื่องของเบซิเยร์ต้องมีจุดตัดอย่างน้อยหนึ่งจุด
กรณีที่ 6
หากเราไม่สามารถแสดงกรณีใดกรณีหนึ่งข้างต้นได้ทันทีให้แบ่ง Beziers แต่ละรายการออกเป็นสองส่วน "ครึ่งหนึ่ง" A1,A2,B1,B2. นี่เป็นเรื่องตรงไปตรงมา (จากการออกกำลังกายไปยังผู้อ่าน) แต่โดยเฉพาะอย่างยิ่งสำหรับเบซิเยร์กำลังสอง :
เปรียบเทียบชุดค่าผสม 4 แบบซ้ำ ๆ : (A1,B1),(A2,B1)...(A2,B2). เห็นได้ชัดว่าทุกกรณีผ่าน 1 ไม่มีจุดตัด หากล้มเหลว 1 ให้ดำเนินการทดสอบส่วนที่เหลือต่อด้วยเซตย่อยที่ลดลง
กรณีที่ 3 และ 5
นี่คือที่ที่มันน่าเบื่อกว่าเล็กน้อย
หาก "กรณีที่ 3" ผ่านการทดสอบ "กรณีที่ 1" ดูเหมือนว่าคุณต้องแก้ปัญหาสำหรับการตัดกันจริง เนื่องจากมีขั้นตอนง่าย ๆ ในการทำแผนที่จุดควบคุม N ของ Bezier, A (s), ไปยังจุด N-1 ของ Bezier, A (s) ซึ่งเป็นตัวแทนของอนุพันธ์อันดับที่ 1 ของมันแล้ว ค่อนข้างยากที่เรียกว่าสถานการณ์ "เสื่อม" ซึ่งอนุพันธ์อันดับที่ 1 มีค่าเป็นศูนย์) จากนั้นก็สามารถใช้การวนซ้ำของนิวตัน (ในมิติเดียว) เพื่อหาคำตอบที่อาจเกิดขึ้น
โปรดทราบว่าเนื่องจากจุดควบคุมของ A 'มีความผูกพันกับมูลค่าอนุพันธ์จึงมีความเป็นไปได้ที่จะทำการกำจัดบางกรณีในช่วงต้น
กรณีที่ 5 ดูเหมือนไม่น่าจะเป็นไปได้ดังนั้นถ้าหลังจากการเรียกซ้ำสองสามครั้งโดยไม่มีข้อสรุปที่แน่ชัดก็สามารถลองแต่ละจุดสิ้นสุดของ A กับเส้นโค้ง B และกลับกันได้ นี่จะให้การพิสูจน์การตัดกันเท่านั้นไม่ใช่การพิสูจน์การตัดกัน