PerfectVector
โดย Irene Kimอ่าน 3 นาที

เส้นโค้งเบซิเยร์ SVG: แก้รอยหักโดยไม่เพิ่มโหนด

ซ่อมรอยต่อเบซิเยร์คิวบิก SVG ด้วยการจัดแนวแขนควบคุม เปรียบเทียบแขนยาวไม่เท่ากับแขนสะท้อน เข้าใจคำสั่ง S และรักษามุมที่ตั้งใจไว้

ในหน้านี้

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

ตรวจรูปทรงต้นทางก่อนเปลี่ยน ปลายใบแหลม รอยเว้า หรือมุมตัวอักษรอาจเป็นความตั้งใจ การซ่อมด้านล่างแก้การเปลี่ยนทิศที่ไม่ต้องการหนึ่งจุด โดยคงจุดเริ่ม รอยต่อ จุดจบ และจำนวนช่วงไว้

หาแขนสองข้างที่ควบคุมรอยต่อ

คำสั่ง SVG คิวบิกมีจุดควบคุมสองจุดและจุดปลาย:

C firstControlX firstControlY secondControlX secondControlY endX endY

ช่วงเริ่มที่จุดปัจจุบัน จุดควบคุมแรกนำทิศทางออกจากจุดเริ่ม จุดที่สองนำการเข้าหาจุดปลาย บทสอนพาธของ MDN แสดงจุดควบคุมและไวยากรณ์คิวบิก สำหรับคู่พิกัดตัวพิมพ์เล็ก ทำตามคำสั่งพาธ SVG แบบสัมพัทธ์ เพื่อติดตามจุดอ้างอิงก่อนเปลี่ยนแขน

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

ซ่อมตัวอย่างต้นฉบับสองช่วง

บันทึก SVG สมบูรณ์นี้เป็น join-example.svg แล้วเปิดในเบราว์เซอร์ เป็นสัญลักษณ์โค้งต้นฉบับที่จงใจมีรอยหักที่ (150, 100)

<svg xmlns="http://www.w3.org/2000/svg" width="900" height="600"
     viewBox="0 0 300 200">
  <path fill="none" stroke="#137f74" stroke-width="5"
    d="M30 150 C60 150 100 100 150 100
       C170 50 240 50 270 50"/>
</svg>

จุดควบคุมขาเข้าคือ (100, 100) อยู่ซ้ายของรอยต่อโดยตรง จุดควบคุมขาออกคือ (170, 50) อยู่เหนือและขวา เส้นโค้งเข้ามาแนวนอนแล้วออกไปทิศอื่น

เปลี่ยนเฉพาะจุดควบคุมแรกของช่วงที่สองเป็น (175, 100):

<path fill="none" stroke="#137f74" stroke-width="5"
  d="M30 150 C60 150 100 100 150 100
     C175 100 240 50 270 50"/>

แขนที่ติดกันทั้งสองอยู่บนเส้นแนวนอนผ่านรอยต่อแล้ว แขนขาเข้ายาว 50 หน่วยและขาออกยาว 25 ทิศสัมผัสตรงกันแม้ความยาวต่างกัน

สำหรับคู่สะท้อน เปลี่ยนจุดควบคุมนั้นเป็น (200, 100) แทน แขนทั้งคู่จะยื่น 50 หน่วยจากจุดยึดร่วม วิธีนี้เปลี่ยนรูปช่วงที่สองมากกว่าการแก้แขนยาวไม่เท่า จึงเทียบทั้งคู่กับเส้นรอบรูปที่ต้องการรักษา

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

ทุกแบบมีช่วงคิวบิกสองช่วงและจุดยึดบนเส้นโค้งสามจุด: เริ่ม รอยต่อ และจบ จุดควบคุมเป็นพิกัดแยก ภาพเปรียบเทียบเป็นการเรนเดอร์ต้นฉบับในเบราว์เซอร์ ไม่ใช่ผลไล่เส้น PerfectVector หรือภาพหน้าจอเครื่องมือโหนด

ตรวจทิศแยกจากความยาวแขน

สำหรับคิวบิกที่จบที่รอยต่อ J และจุดควบคุมสุดท้าย A อนุพันธ์ที่ปลายคือ 3 × (J − A) คิวบิกถัดไปเริ่มที่ J และมีจุดควบคุมแรก B จะมีอนุพันธ์เริ่ม 3 × (B − J)

ในตัวอย่าง อนุพันธ์ขาเข้าเป็น (150, 0) ทุกแผง:

จุดควบคุมขาออก Bอนุพันธ์ขาออกเงื่อนไขรอยต่อ
(170, 50)(60, −150)ทิศสัมผัสต่างกัน
(175, 100)(75, 0)ทิศเดียวกัน ขนาดต่างกัน
(200, 100)(150, 0)ทิศและขนาดเดียวกัน

ทิศสัมผัสตรงกันเรียกความต่อเนื่อง G1 อนุพันธ์อันดับแรกตรงกันเรียกความต่อเนื่อง C1 เมื่อใช้ช่วงพารามิเตอร์ศูนย์ถึงหนึ่งตามปกติของคิวบิกสองช่วงนี้ บันทึกอนุพันธ์เบซิเยร์ของ Michigan Tech อนุมานเงื่อนไขปลายเหล่านี้

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

ตัวอย่างที่จัดแนวทั้งสองไม่ได้รับประกันว่าความโค้งของทั้งสองช่วงจะเท่ากันที่รอยต่อ เส้นโค้งอาจไม่มีมุมทิศสัมผัสแต่ยังต้องปรับให้ตรงขอบโลโก้ที่ตั้งใจ ตรวจทั้งส่วนโค้ง ไม่ใช่แค่โหนดที่เลือก

ใช้ S เมื่อการสะท้อนเป็นรูปที่ต้องการเท่านั้น

แบบสะท้อนเขียนสั้นลงได้:

<path fill="none" stroke="#137f74" stroke-width="5"
  d="M30 150 C60 150 100 100 150 100
     S240 50 270 50"/>

ในที่นี้ S อนุมานจุดควบคุมแรกด้วยการสะท้อนจุดควบคุมสุดท้ายของคิวบิกก่อนรอบจุดปัจจุบัน:

reflectedX = 2 × 150 − 100 = 200
reflectedY = 2 × 100 − 100 = 100

คู่ที่เหลือใน S240 50 270 50 ระบุจุดควบคุมที่สองและจุดปลาย นี่เป็นแบบแขนสะท้อน 50/50 ใช้แทนแบบ 50/25 โดยไม่เปลี่ยนเส้นโค้งไม่ได้

ข้อกำหนดคำสั่งคิวบิก SVG จำกัดกฎสะท้อนนี้เมื่อคำสั่งก่อนเป็น C, c, S หรือ s หากก่อนหน้าเป็นเส้นตรงหรือโค้งกำลังสอง จุดควบคุมแรกโดยนัยจะเป็นจุดปัจจุบันแทน

เช่น:

M30 150 L150 100 S240 50 270 50

หลังเส้นตรง ช่วงสุดท้ายทำงานเหมือน C150 100 240 50 270 50 แขนแรกยุบถึงจุดเริ่ม ยังโค้งได้เพราะเรขาคณิตควบคุมที่เหลือไม่ได้อยู่บนเส้นตรงเดียว S หลังเส้นตรงไม่ได้บังคับให้ช่วงเป็นเส้นตรง

การตรวจในเบราว์เซอร์เทียบพาธ S แบบสะท้อนกับ C ที่เขียนชัด แล้วตรวจตัวอย่างเส้นตรงตามด้วย S กับการขยายชัดของมันเอง ทั้งคู่ตรงกันที่ตำแหน่งที่เก็บตัวอย่างมาวัด ยืนยันตัวอย่างเหล่านี้ ส่วนข้อกำหนดนิยามกฎทั่วไป

ซ่อมแบบเดียวกันในโปรแกรมแก้โหนด

ทำงานบนสำเนา เลือกพาธ และแสดงแขนรอบรอยต่อที่สงสัย ยืนยันว่ามีจุดยึดร่วมจุดเดียว จุดปลายแยกสองจุดที่เพียงซ้อนอาจต้องซ่อมโครงสร้างเชื่อมต่อก่อนเปลี่ยนทิศแขน

ใน Inkscape คู่มือประเภทโหนด แยกโหนด smooth ที่แขนอยู่แนวเส้นเดียวจากโหนด symmetric ที่แขนยังยาวเท่ากันด้วย ใช้ประเภทที่เหมาะเส้นรอบรูป แทนการบังคับทุกจุดให้สมมาตร

คงจุดยึดขณะปรับทิศแขน จากนั้นลดหรือเพิ่มความยาวแขนเพื่อคืนรูปร่างรอบรอยต่อที่ต้องการ เทียบผลทั้งที่ซูมสูงและขนาดดูปกติ แล้วเปิด SVG ที่บันทึกใหม่เพื่อตรวจพาธส่งออก

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

เปรียบเทียบรูปที่ซ่อมกับต้นทาง

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

หากมีเพียง PNG หรือ JPG ของสัญลักษณ์ เครื่องมือแปลงโลโก้เป็นเวกเตอร์ของ PerfectVector เตรียม SVG ที่แก้ได้สำหรับประเมิน ตรวจเส้นรอบรูปแล้วซ่อมแขนเฉพาะจุดที่ยังมีรอยหักไม่ตั้งใจ เก็บราสเตอร์อ้างอิงข้างพาธที่แก้เพื่อไม่ให้การทำเรียบลบรายละเอียดที่ควรเก็บ

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

คำถามที่พบบ่อย

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

ทำไมคำสั่ง S ของ SVG เปลี่ยนเส้นโค้ง? S อนุมานจุดควบคุมแรก หลัง C หรือ S จะสะท้อนจุดควบคุมสุดท้ายของคิวบิกก่อน หลังคำสั่งชนิดอื่นใช้จุดปัจจุบัน จุดที่อนุมานอาจต่างจากจุดควบคุมที่ตั้งใจเขียนชัด

ควรทำทุกโหนดในโลโก้ไล่เส้นให้เรียบหรือไม่? ไม่ รักษามุม ปลาย และรอยเว้าที่ตั้งใจ ซ่อมรอยหักไม่ตั้งใจเฉพาะจุดแล้วเทียบขอบรูปทั้งหมดกับต้นทาง รอยต่อที่ต่อเนื่องทางสัมผัสอย่างเดียวไม่ยืนยันการสร้างกลับแม่นยำ

แหล่งอ้างอิง

  1. MDN — พาธ SVG — อธิบายจุดควบคุมคิวบิกและไวยากรณ์คำสั่งพาธ
  2. Michigan Tech — อนุพันธ์เบซิเยร์ — อนุมานเส้นสัมผัสปลายและเงื่อนไขเชื่อมเส้นโค้ง
  3. W3C — คำสั่งเบซิเยร์คิวบิก SVG — นิยามกฎสะท้อนและจุดควบคุมสำรองของ S
  4. Inkscape — ประเภทโหนด — แยกพฤติกรรมโหนด cusp, smooth, symmetric และ automatic

หากโลโก้เริ่มจากราสเตอร์ เตรียม SVG สำหรับประเมินด้วย PerfectVector ตรวจรอยต่อและขอบรูป แล้วซ่อมเฉพาะเส้นโค้งที่ต้องแก้โดยรักษามุมที่ตั้งใจ

เพิ่มเติมจากบล็อก

เริ่มต้นด้วย SVG ที่เรียบร้อยขึ้น
และแก้ไขได้ง่ายกว่า