เมื่อพิจารณาจากจุดของเส้นตรงและเส้นโค้งเบซิเยร์กำลังสองคุณจะคำนวณจุดที่ใกล้ที่สุดได้อย่างไร .... ในทำนองเดียวกันเมื่อกำหนดจุดโค้ง 2 จุดคุณจะได้รับจุดที่ใกล้ที่สุดได้อย่างไร
เมื่อพิจารณาจากจุดของเส้นตรงและเส้นโค้งเบซิเยร์กำลังสองคุณจะคำนวณจุดที่ใกล้ที่สุดได้อย่างไร .... ในทำนองเดียวกันเมื่อกำหนดจุดโค้ง 2 จุดคุณจะได้รับจุดที่ใกล้ที่สุดได้อย่างไร
คำตอบ:
นี่คือความพยายามของฉัน อัลกอริทึมต่อไปนี้ยังห่างไกลจากความสมบูรณ์แบบแต่มันง่ายและฉันเชื่อว่าคุณควรเริ่มต้นด้วยสิ่งนี้ตรวจสอบว่ามันทำงานในสถานการณ์ของคุณหรือไม่และเปลี่ยนเป็นบางสิ่งที่เร็วขึ้น
แนวคิดมีดังต่อไปนี้:
เส้นโค้งเบซิเยร์เป็น parametrised โดยฟังก์ชั่นใช้ชุดของจุดควบคุมและพารามิเตอร์ที่แตกต่างกันF(t)
t
จำนวนจุดที่สร้างไม่สำคัญ
สาย parametrised สองจุดและA
B
ขอSAMPLES = 10
ยกตัวอย่างเช่น
เริ่มต้นด้วยt0 = 0
และt1 = 1
ปล่อย dt = (t1 - t0) / SAMPLES
ถ้าdt < 1e-10
(หรือสภาพความถูกต้องอื่น ๆ ที่คุณเห็นพอดี) ขั้นตอนวิธีการเสร็จสิ้นแล้วและคำตอบคือF(t0)
คำนวณรายการSAMPLES + 1
คะแนนบนเส้นโค้งเบซิเยร์:
L[0] = F(t0)
L[1] = F(t0 + dt)
L[2] = F(t0 + 2 * dt)
L[SAMPLES] = F(t0 + SAMPLES * dt)
ค้นหาจุดที่L
มีดัชนีi
อยู่ใกล้กับเส้นมากที่สุด ใช้วิธีจุด / เส้นระยะห่างใด ๆ ที่คุณรู้ตัวอย่างเช่นระยะห่างของสแควร์||AB^L[i]A||² / ||AB||²
ที่^
หมายถึงผลิตภัณฑ์ครอสและ||…||
เป็นระยะทาง
ถ้าi == 0
ตั้งค่าi = 1
; ถ้าi == SAMPLES
ตั้งi = SAMPLES - 1
อนุญาตt1 = t0 + (i + 1) * dt
และt0 = t0 + (i - 1) * dt
กลับไปที่ขั้นตอนที่ 3
เวลานี้เรามีสองเส้นโค้งเบซิเยร์, parametrised โดยและF(t)
G(t)
ขอSAMPLES = 10
ยกตัวอย่างเช่น
เริ่มต้นด้วยt0 = 0
, t1 = 1
, s0 = 0
และs1 = 1
ปล่อย dt = (t1 - t0) / SAMPLES
ปล่อย ds = (s1 - s0) / SAMPLES
ถ้าdt < 1e-10
(หรือสภาพความถูกต้องอื่น ๆ ที่คุณเห็นพอดี) ขั้นตอนวิธีการเสร็จสิ้นแล้วและคำตอบคือF(t0)
หากนี่เป็นการเรียกใช้ครั้งแรกของลูป:
6.1 คำนวณรายการSAMPLES + 1
คะแนนบนF
( ดูด้านบน )
6.2 คำนวณรายชื่อของจุดบนSAMPLES + 1
G
6.3 ค้นหาจุดคู่ที่ใกล้เคียงที่สุด
6.4 ปรับปรุงt0
, t1
, s0
, s1
เท่าที่เห็นข้างต้น
ELSE : ผลัดคำนวณรายการของจุดบนF
หรือรายการของจุดบนG
แล้วหาที่จุดบนF
เป็นที่อยู่ใกล้G(s0)
และอัปเดตt0
และt1
, หรือที่จุดG
ใกล้เคียงกับF(t0)
และการปรับปรุงและs0
s1
กลับไปที่ขั้นตอนที่ 3
โดยการออกแบบอัลกอริทึมเหล่านี้จะมาบรรจบกันเป็นขั้นต่ำในท้องถิ่น อย่างไรก็ตามไม่มีการรับประกันว่าพวกเขาจะเข้าหาทางออกที่ดีที่สุด โดยเฉพาะอย่างยิ่งอัลกอริทึมเส้นโค้งBézierนั้นไม่ค่อยดีนักและในกรณีที่มีสองโค้งที่อยู่ใกล้กันในหลาย ๆ สถานที่คุณอาจพลาดวิธีแก้ปัญหาด้วยการยิงระยะไกล
แต่อย่างที่ฉันพูดก่อนที่คุณจะเริ่มคิดเกี่ยวกับการแก้ปัญหาที่มีประสิทธิภาพมากขึ้นคุณควรทดลองกับวิธีง่าย ๆ เหล่านั้นก่อน
1) แปลทุกอย่างเป็นหนึ่งแกนดังนั้นแทนที่จะต้องคำนวณความยาวของจุดหนึ่งไปที่ 'เส้น', 'เส้น' คือพูดแกน Y
จากนั้นเอ่อให้เส้นโค้งเบซิเยร์มากขึ้นฉันจะบอกว่ามันขึ้นอยู่กับจำนวนของจุดควบคุม
หากมีสาม (เริ่มต้น 'ควบคุม' และสิ้นสุด) ฉันจะทำการสแกนบางประเภท (พูดสองสามเปอร์เซ็นต์จากนั้นปรับแต่งระหว่างสิ่งที่ใกล้เคียงที่สุด (ด้วยวิธีพูด 'ไบนารี')
คะแนนเพิ่มเติมฉันลองคู่ที่ใกล้เคียงที่สุด (แปลแกน Y)
ฉันแน่ใจว่านักคณิตศาสตร์สามารถให้คำตอบที่ถูกต้อง (ในวิชาคณิตศาสตร์) แต่ถ้าคุณต้องการค้นหา / a วิธีแก้ปัญหาในวิดีโอเกมคุณอาจจะดีกว่าด้วยวิธีการแก้ปัญหาเล็กน้อยเนื่องจากโซลูชันจริงอาจมีหลายคำตอบ ( ฉันไม่ได้พูดถึงพลังการประมวลผล)
คำตอบบางส่วนจากหน้าบล็อกของอัลกอริทึมซึ่งพบจุดที่ใกล้ที่สุดบนเส้นโค้งเบซิเยร์กำลังสองที่ให้มาอย่างถูกต้อง
สำหรับเส้นโค้ง Bezier - เส้นตรงวิธีที่แม่นยำที่สุดในการค้นหาคำตอบคือทำดังต่อไปนี้: