การวัดความตรงของส่วนโค้ง (แสดงเป็นรูปหลายเหลี่ยม)


11

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

เส้นชั้นความสูงแต่ละเส้นจะแสดงเป็นเส้นโค้ง (แต่มีจุดเชื่อมต่อกันเพื่อให้ดูเหมือนเส้นโค้งกับตาเปล่า) จากนั้นฉันมีความยาวคงที่ (ความกว้างของฉลาก) พูด 100 พิกเซล ถ้าฉันสุ่ม (หรืออื่น ๆ ) เลือกส่วนของรูปร่างที่มีความกว้าง 100 พิกเซลฉันต้องการที่จะได้ค่าเชิงตัวเลขที่เป็นตัวเลขของความตรงของมัน (บอกศูนย์สำหรับส่วนของรูปร่างที่เป็นเส้นตรงทั้งหมดค่าที่มากกว่าศูนย์สำหรับ ส่วนที่ตรงและค่านี้เพิ่มขึ้นเมื่อความคดเคี้ยวเพิ่มขึ้น

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

คำตอบ:


9

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

ตัวอย่างเช่นสมมติว่าคุณตั้งใจจะทำการค้นหาอย่างเป็นระบบข้ามส่วนประกอบที่เชื่อมต่อทั้งหมดของเส้นแสดงเป็นลำดับของจุด P (0), P (1), ... , P (n) สิ่งนี้จะทำได้โดยการเริ่มต้นตัวชี้ (ดัชนีในลำดับ) s = 0 ("s" สำหรับ "เริ่มต้น") และตัวชี้อีก f (สำหรับ "เสร็จสิ้น") เป็นดัชนีที่เล็กที่สุดซึ่งระยะทาง (P (f), P (s)> = 100 จากนั้นเลื่อน s ไปเป็นระยะทางไกล (P (f), P (s + 1))> = 100 ซึ่งจะสร้างโพลีไลน์ผู้สมัคร (P (s), P (s +) 1) ... , P (f-1), P (f)) สำหรับการประเมินผล หลังจากประเมินว่า "ความเหมาะสม" ของมันเพื่อรองรับฉลากคุณจะเพิ่ม s 1 (s = s + 1) และดำเนินการเพิ่ม f เป็น (พูด) f 'และ s เป็น s' จนกระทั่งโพลีไลน์ของผู้สมัครอีกครั้งเกินกว่าขั้นต่ำ ผลิตจากช่วง 100 แทนเป็น (P (s '), ... P (f), P (f + 1), ... , P (f')) ในการทำเช่นนั้นจุดยอด P (s) ... P (s ') เป็นที่พึงปรารถนาอย่างมากว่าการออกกำลังกายสามารถปรับปรุงได้อย่างรวดเร็วจากความรู้เกี่ยวกับจุดยอดที่เพิ่มและลดลงเท่านั้น (ขั้นตอนการสแกนนี้จะดำเนินต่อไปจนถึง s = n; ตามปกติจะต้องได้รับอนุญาตให้ "ห่อรอบ" จาก n กลับเป็น 0 ในกระบวนการ)

พิจารณากฎนี้ออกมาตรการเป็นไปได้มากของการออกกำลังกาย ( sinuosity , คดเคี้ยวฯลฯ ) ที่อื่นอาจจะเป็นที่น่าสนใจ มันทำให้เราเห็นชอบมาตรการที่ใช้L2เพราะโดยทั่วไปแล้วพวกเขาสามารถปรับปรุงได้อย่างรวดเร็วเมื่อข้อมูลพื้นฐานเปลี่ยนแปลงไปเล็กน้อย การคล้ายคลึงกับการวิเคราะห์องค์ประกอบหลักที่แสดงให้เห็นว่าเราสร้างความบันเทิงให้มาตรการดังต่อไปนี้ (ที่มีขนาดเล็กจะดีกว่าตามที่ร้องขอ): ใช้เล็ก ๆ สองค่าลักษณะเฉพาะของเมทริกซ์ความแปรปรวนของพิกัดจุด เชิงเรขาคณิตนี่เป็นมาตรวัดหนึ่งของการเบี่ยงเบนจากด้านหนึ่งไปอีกด้านหนึ่งของจุดยอดภายในส่วนของโพลีไลน์ (การตีความหนึ่งคือรากที่สองของมันคือกึ่งแกนเล็ก ๆ ของวงรีซึ่งแทนช่วงเวลาที่สองของความเฉื่อยของจุดยอดของโพลีไลน์) มันจะเท่ากับศูนย์สำหรับชุดของจุดยอด collinear; มิฉะนั้นจะเกินศูนย์ มันวัดค่าเบี่ยงเบนจากด้านหนึ่งไปอีกด้านหนึ่งโดยเฉลี่ยเมื่อเปรียบเทียบกับพื้นฐาน 100 พิกเซลที่สร้างโดยจุดเริ่มต้นและจุดสิ้นสุดของรูปหลายเหลี่ยมและดังนั้นจึงมีการตีความง่าย ๆ

เนื่องจากเมทริกซ์ความแปรปรวนร่วมเป็นเพียง 2 คูณ 2 ค่าลักษณะเฉพาะจึงถูกค้นพบอย่างรวดเร็วโดยการแก้สมการกำลังสองเดี่ยว ยิ่งกว่านั้นเมทริกซ์ความแปรปรวนร่วมนั้นเป็นผลรวมของเงินสมทบจากแต่ละจุดยอดในรูปหลายเหลี่ยม ดังนั้นจึงมีการอัปเดตอย่างรวดเร็วเมื่อมีการเลื่อนหรือเพิ่มจุดนำไปสู่อัลกอริธึม O (n) สำหรับเส้นขอบ n-point: สิ่งนี้จะปรับขนาดให้เข้ากับรูปทรงที่มีรายละเอียดสูงซึ่งมองเห็นได้ในแอปพลิเคชัน

นี่คือตัวอย่างของผลลัพธ์ของอัลกอริทึมนี้ จุดสีดำเป็นจุดยอดของเส้นชั้นความสูง เส้นสีแดงทึบเป็นส่วนของโพลิไลน์ที่ดีที่สุดของความยาวตั้งแต่ต้นจนจบที่มากกว่า 100 ภายในรูปร่างนั้น (ผู้สมัครที่เห็นได้ชัดเจนในมุมขวาบนนั้นไม่นานพอ)

รูป


ว้าวคุณทำให้ฉันหลงทางไปแล้ว :) คุณถูกต้องเกี่ยวกับการค้นหาอย่างเป็นระบบฉันต้องทำเช่นนั้นเพื่อให้ได้สัมผัสของแต่ละจุดสุดยอด polyline / รูปหลายเหลี่ยม (ป้ายแนวนอนเป็นที่นิยมในแนวตั้ง) ดังนั้นในทางทฤษฎีฉันสามารถขยายการค้นหานี้เพื่อครอบคลุมการวัดอื่น ๆ BTW: คุณสร้างพล็อตตัวอย่างโดยใช้อัลกอริทึมจริงหรือด้วยตนเองหรือไม่?
Igor Brejc

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

2
กราฟในตอนท้ายทำให้คำตอบนี้ยอดเยี่ยมยิ่งขึ้น
Ragi Yaser Burhum

2
อิกอร์ฉันควรพูดถึงว่าทิศทางของฉลากนั้นฟรี: ได้รับจากทิศทางของแกนหลักของวงรี (eigenvector ที่เกี่ยวข้องกับค่าลักษณะเฉพาะขนาดใหญ่) คุณจึงสามารถค้นหาพร้อมกันอย่างมีประสิทธิภาพเพื่อการผสมผสานที่ดีที่สุดของการวางแนวฉลากและเส้นตรงส่วนเส้น
whuber

3

ในชุมชนกราฟิกคอมพิวเตอร์มักจำเป็นต้องค้นหากล่องขอบรอบวัตถุ ดังนั้นนั่นเป็นปัญหาที่ได้รับการศึกษาเป็นอย่างดีพร้อมอัลกอริธึมที่รวดเร็ว เช่นดูที่วิกิพีเดียขั้นต่ำกล่องขอบเขตอัลกอริทึมบทความ คุณสามารถหาสี่เหลี่ยมพื้นที่ต่ำสุดที่ล้อมรอบ polyline ของคุณจากนั้นใช้อัตราส่วนกว้างยาวของสี่เหลี่ยมความสูง / ความยาว เพื่อให้ได้การวัดที่แม่นยำยิ่งขึ้นคุณสามารถดูการเบี่ยงเบนของโพลีไลน์จากกึ่งกลางของสี่เหลี่ยมผืนผ้าที่ล้อมรอบนี้


1
ฉันคิดเกี่ยวกับการใช้ขั้นต่ำ แต่ฉันเห็นปัญหาสองข้อ: ก) ความซับซ้อนในการคำนวณของการคำนวณกล่องที่จะเป็นค่าต่ำสุด (และหมุนได้), b) สองส่วนโค้งที่มีอัตราส่วนเดียวกันสามารถมีความโค้งที่แตกต่างกันมาก (คิดว่าเป็นไซนัส โค้งด้วยแอมพลิจูดเดียวกัน แต่ช่วงคลื่นต่างกัน)
Igor Brejc

1
ดีใจที่ได้พบคุณที่นี่ในหน้า GIS, Joseph!
whuber

1
ใช่ฉันมีหนังสือ "เรขาคณิตการคำนวณใน C" ของคุณอยู่ในมือตอนนี้ :)
Igor Brejc

1
ขอบคุณสำหรับการต้อนรับทุกคน! :-) ฉันรู้ว่าคำแนะนำของฉันไม่ใช่ตัวชี้วัดที่เหมาะสม แต่การเขียนโค้ดเป็นแบบ off-the-shelf (ถ้าคุณมีชั้นวางที่ถูกต้อง) ปัญหาประเภทนี้ได้รับการศึกษาค่อนข้างน้อยในบริบทการผลิตซึ่งพวกเขาจำเป็นต้องวัดคุณภาพของชิ้นส่วนกลึง
Joseph O'Rourke

3

ฉันไม่รู้ว่าสิ่งนี้ช่วยได้หรือเปล่าแม้ว่ามันจะนับเป็นคำตอบ แต่เมื่อฉันนั่งที่นี่กำลังคิดเกี่ยวกับคำถามที่ฉันเพิ่งโพสต์ฉันมีความคิด:

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

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

ฉันแน่ใจว่านี่ไม่ได้ช่วยอะไรมากและสิ่งที่ฉันพูดเป็นภาษาอังกฤษนั้นยากกว่ามากสำหรับภาษาที่คุณใช้ แต่มันอาจเป็นการเริ่มต้นใช่ไหม


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

3

วิธีที่ง่ายที่สุดที่ฉันคิดได้คืออัตราส่วนระหว่างความยาวเส้นทางจริงระหว่างจุดเริ่มต้นและจุดสิ้นสุดและระยะทางที่สั้นที่สุด (เส้นตรง) จากจุดเริ่มต้นถึงจุดสิ้นสุด เส้นตรงจะมีอัตราส่วนใกล้เคียงกับหนึ่งในขณะที่เส้นโค้งที่มากจะมีอัตราส่วนที่สูงมาก

นี่ควรเป็นโซลูชันที่ใช้งานง่าย


ปรับปรุง: ในฐานะที่เป็นไมค์สังเกตเห็นได้อย่างถูกต้องนี้จะเท่ากับSinuosity

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


เพียงแค่สิ่งที่เข้ามาในใจของฉันหลังจากที่ได้อ่านคำตอบของเร็กซ์ :)
อิกอร์ Brejc

4
โดยพื้นฐานแล้วการแลกเปลี่ยนของsinuosity
Mike T

แน่นอน :) ....
underdark

2
คุณพูดถูกว่าเป็นเรื่องง่ายที่จะนำมาใช้เนื่องจากการปรับปรุงความยาวเมื่อการค้นหากลุ่มที่เหมาะสมกับป้ายกำกับนั้นทำได้ง่ายเพียงแค่เพิ่มและลบความยาวระหว่างจุดยอดที่ต่อเนื่องกัน อย่างไรก็ตาม sinuosity ไม่สามารถจับความรู้สึกได้อย่างมีประสิทธิภาพซึ่งเส้นโค้งสามารถออกจากเส้นตรงได้ ตัวอย่างเช่นเปรียบเทียบครึ่งวงกลมของเส้นผ่านศูนย์กลาง 100 กับลำดับเชิงเส้นของครึ่งวงกลมของเส้นผ่าศูนย์กลาง 1 : เส้นโค้งทั้งคู่มีความโค้งเท่ากันแต่การเบี่ยงเบนจากด้านหนึ่งไปอีกด้านหนึ่งของครั้งแรกคือ 100 เท่าของวินาที (ซึ่งน่าจะเป็นฐานที่ดี สำหรับฉลาก)
whuber

โปรดคำนึงว่าถ้า polyline ของคุณวาดวงกลมวิธีนี้จะทำให้คุณมีความไม่มีที่สิ้นสุดซึ่งอาจไม่ใช่ผลลัพธ์ที่ต้องการ
obchardon

1

ด้วยการค้นหา "ความโค้ง" และ "โพลีไลน์" ฉันได้รับข้อมูลนี้ ฉันจะค้นหาความโค้งของโพลีไลน์ได้อย่างไร . - K= DF/Dsที่นั่นเขาได้แนะนำให้ใช้กลับไปที่ความหมายของความโค้ง ที่นี่FเขาหมายถึงphiหรือTในสัญลักษณ์ของวิกิพีเดียที่นี่ ( http://en.wikipedia.org/wiki/Curvature )

สมมติว่าคุณมีลำดับสามจุด, p0, p1 และ p2 คำนวณระยะทางsระหว่าง p0 และ p1 ซึ่งเป็นเดลต้าของ s ( Ds) โดยสมมติว่าจุดนั้นอยู่ใกล้กันมากพอ จากนั้นคุณต้องใช้เดลต้าของ T ( DT) ซึ่งเป็นการเปลี่ยนแปลงในเวกเตอร์แทนเจนต์หน่วยระหว่าง p0 และ p1 อาจมีวิธีที่ซับซ้อน แต่วิธีการที่ฉันคิดว่าจะใช้สอง bectors p0-> p1, p1-> p2, ทำให้ปกติแต่ละอันมีความยาวหนึ่งแล้วใช้การลบเวกเตอร์ของทั้งสองแล้วกำหนดขนาด DTกล่าวคือ K0_1ส่วนผลผลิตโค้ง คว้า p1, p2 และ p3 เพื่อคำนวณK1_2และอื่น ๆ

ฉันสงสัยว่าถ้าคุณได้รับเส้นชั้นความสูงเป็นเส้นตรงไม่ใช่เป็นพิกเซลที่เรนเดอร์ คุณพูด 100px แล้วทำให้ฉันกังวลเล็กน้อย


ขอบคุณสำหรับลิงค์ฉันจะต้องศึกษาคณิตศาสตร์ที่อยู่เบื้องหลัง ฉันพูดถึง 100px เพียงเพราะข้อความของฉลากที่แสดงนั้นมีความกว้างแน่นอน (เป็นพิกเซล) 100px เป็นเพียงตัวอย่าง
Igor Brejc

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