สคริปต์แบบบล็อก

  • บทความก่อนหน้านี้พูดถึงตัวอักษรภาษาอังกฤษในเวอร์ชันพิมพ์บล็อก
  • สรุปแล้ว ทำขึ้นผ่านกระบวนการดังนี้:
    • เขียนโค้ดกำหนดจุดสำคัญของเส้นทางสำหรับตัวอักษรแต่ละตัว (ประมาณ 10 จุดต่อตัวอักษร)
    • ใช้อัลกอริทึมเส้นโค้งของ Chaikin เพื่อทำให้เส้นทางเรียบขึ้น
    • แปลงเส้นทางให้เป็นรูปทรงที่มีความหนาแปรผัน
    • ใช้ p5js วาดเส้นทางของรูปทรง
  • หน้าตาออกมาเป็นแบบนี้
  • บทความเกี่ยวกับวิธีสร้างประโยคด้วยระบบนี้จะตามมาเร็ว ๆ นี้ ฝากสมัครรับจดหมายข่าวเพื่อรอติดตาม
  • เดิมทีการกำหนดเส้นทางของตัวอักษรต้องทำด้วยมือมาก โดยเขียนตำแหน่งลงในโค้ดและปรับจุดต่าง ๆ จนกว่าตัวอักษรจะดูถูกต้อง
  • ตอนทำลายมือแบบตัวเขียน ฉันทำให้กระบวนการนี้ง่ายขึ้น

การออกแบบตัวอักษร

  • ฉันสร้างเครื่องมือสำหรับกำหนดและแสดงผลจุดสำคัญของเส้นทาง เพื่อให้เข้าถึงได้ง่ายใน p5js editor
  • มันแสดงตัวอักษรตัวอย่างและมีพื้นที่สำหรับออกแบบตัวอักษรใหม่
  • ขั้นตอนถัดไปมีดังนี้:
    • คลิกวางจุดสำคัญของเส้นทาง แล้วเส้นทางโค้งแบบ Chaikin ที่ได้จะถูกแสดง
    • กด p เพื่อสลับไปยังโหมดแก้ไข
    • เลือกจุดแล้วลากไปยังตำแหน่งที่ต้องการ
    • กด enter เพื่อพิมพ์เส้นทางออกสู่คอนโซล
  • ฉันทำตัวเลือกไว้ 2-3 แบบสำหรับตัวอักษรแต่ละตัว
  • เส้นทางที่ได้มีลักษณะดังนี้:
    [{x:0.7,y:22.5},{x:8.2,y:18.1},{x:8.9,y:11.2},{x:3.7,y:11.4},{x:1.7,y:18.9},{x:8.4,y:22.4},{x:17.7,y:22.0}]
    
  • ฉันอยากใช้ลายมือของตัวเองเป็นแนวทาง จึงเขียนตัวอย่างทั้งตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ แล้วโหลดภาพเข้าไปในเครื่องมือโดยตรงเพื่อไล่ตามเส้น
  • ใช้ปุ่ม w/a/s/d เพื่อจัดภาพให้อยู่ในตำแหน่งที่ถูกต้อง และใช้ปุ่ม r/e เพื่อซูมเข้า/ออก
  • ตัวเลขคือพิกัด x y สำหรับวางส่วนนั้นในหน้าต่างสร้างตัวอักษร
  • หลังจากสร้างเส้นทางทั้งหมด วาดเส้นโค้ง และแปลงเป็นรูปทรงที่มีความกว้างแปรผันแล้ว ตัวอักษรแต่ละตัวมีหน้าตาแบบนี้

ทำให้เป็นตัวเขียน

  • บางครั้งการเชื่อมตัวอักษรเข้าด้วยกันก็ง่าย เพียงไปต่อจากเส้นทางจุดสำคัญของตัวหนึ่งไปยังเส้นทางถัดไปโดยตรง แล้วใช้งานเส้นโค้ง Chaikin กับทั้งหมดในครั้งเดียว
  • แต่คู่ตัวอักษรบางคู่เข้ากันได้ไม่ดี
  • ตัวอย่างเช่น ในคู่ na จุดสุดท้ายของ n อยู่ต่ำ แต่จุดแรกของ a อยู่สูง ทำให้เกิดเส้นทางที่พาดทแยงผ่าน a และดูเหมือน e
  • ในคู่ ti นั้น t จบเหนือเส้นฐาน และ i เริ่มที่เส้นฐาน ทำให้เกิดสันที่ดูไม่เป็นธรรมชาติ
  • เพื่อแก้ปัญหานี้ เราสามารถเพิ่มจุดพิเศษที่จุดเริ่มต้นของ a และลบสองจุดสุดท้ายของ t ได้
  • แต่เราไม่สามารถเปลี่ยนตัวอักษรแบบนี้ได้ในทุกสถานการณ์
  • ตัวอย่างเช่น ถ้า a อยู่ต้นคำ จุดที่เพิ่มเข้ามาจะอยู่ผิดที่ และถ้ามันตามหลังตัวอักษรอย่าง w ก็จะเกิดเส้นที่พาดผ่าน a ในอีกแบบหนึ่ง
  • ถ้า t จับคู่กับ k มันก็จะเสียรูป
  • จุดเริ่มต้นและจุดสิ้นสุดของเส้นทางตัวอักษรจึงต้องเปลี่ยนไปตามตำแหน่งสัมพันธ์กับตัวอักษรอื่น
  • ตอนแรกฉันตั้งใจจะระบุคู่ที่ “มีปัญหา” เป็นกรณีเฉพาะแล้วเขียนกฎให้แต่ละคู่ แต่สุดท้ายฉันเพิ่มตัวเลขไว้ที่ต้นและท้ายของแต่ละเส้นทางเพื่อบอกว่า:
    • ไม่ได้เชื่อมกับตัวอักษรอื่น (0)
    • เชื่อมกับตัวอักษรอื่นแถวเส้นฐาน (1)
    • เชื่อมกับตัวอักษรอื่นเหนือเส้นฐานขึ้นมาเล็กน้อย (2)
    • เชื่อมกับตัวอักษรอื่นแถว x-height (3)
  • ตัวอย่าง:
  • ตอนนี้เส้นทางของแต่ละตัวอักษรมีหน้าตาแบบนี้ สังเกตเลขหนึ่งหลักที่ต้นและท้าย:
    [0,{x:12.2,y:13.2},{x:13.5,y:11.0},{x:6.2,y:8.4},{x:1.1,y:13.0},{x:1.8,y:19.0},{x:7.0,y:23.4},{x:15.2,y:23.6},{x:18.4,y:22.1},1]
    
  • ฉันทดสอบทุกคู่ตัวอักษรแล้ว
  • ตรงนี้คุณจะเห็นว่าฉันมีตัวเลือกเส้นทางหลายแบบสำหรับแต่ละตัวอักษร และตัวอักษรจะถูกแก้ไขไปตามตัวข้างเคียง
  • ตามอุดมคติแล้ว ฉันอยากมีตัวเลือกเส้นทางอย่างน้อย 5-6 แบบต่อตัวอักษรแต่ละตัว แต่ต้องหาสมดุลกับขนาดไฟล์ด้วย

การสร้างคำ

  • เมื่อมีการสร้างคำ:
    • สำหรับแต่ละตัวอักษร จะมีการเลือกเส้นทางพื้นฐานจากตัวเลือก 2-3 แบบ
    • ข้อมูลเกี่ยวกับปลายของเส้นทางจะถูกส่งต่อไปยังตัวอักษรข้างเคียง (เนื่องจากตัวเลือกเส้นทางต่าง ๆ ของตัวอักษรเดียวกันอาจมีปลายทางต่างกัน จึงต้องเลือกเส้นทางของตัวอักษรทั้งหมดก่อน)
    • จากนั้นเส้นทางพื้นฐานจะถูกปรับให้ตอบสนองต่อตัวอักษรเพื่อนบ้าน เช่น ถ้าความสูงปลายของตัวอักษรก่อนหน้าเป็น 2 ก็อาจลบ 1 จุดที่จุดเริ่มต้นของเส้นทางนี้ หรือถ้าความสูงต้นของตัวอักษรถัดไปเป็น 1 ก็อาจเพิ่มจุดพิเศษในตำแหน่งหนึ่ง
  • ฟังก์ชันปรับแต่งอาจซับซ้อนอยู่บ้าง ตัวอย่างเช่น ฟังก์ชันสำหรับตัวอักษร q มีดังนี้:
    // ip = path
    // pc = previous letter ending info
    // nc = next letter starting info
    // n = index of chosen path for this letter
    adjust: (ip, pc, nc, n) => {
      // add a break to the end of this letter with a 70% chance
      if (rand() < 0.7 ) ip.splice(-1, 1, 0);
      // if [2] from the 4 options has been chosen for this path
      if (n < 2) {
        // if previous letter ends at 3 replace first two points with different point
        if (pc == 3) ip.splice(1, 2, {x:10,y:12});
        // otherwise if not 0 add a point to the start
        else if (pc > 0) ip.splice(1, 0, {x:10,y:20});
      }
      // if there is no break between this and next letter (0)
      if (nc > 0 && ip[ip.length-1] != 0){
        // replace last two points with different point
        ip.splice(-3, 2, {x:16,y:34});
      }
    }
    
  • แต่บ่อยครั้งมันก็สั้น ตัวอย่างเช่น ฟังก์ชันสำหรับตัวอักษร n มีดังนี้:
    adjust: (ip, pc, nc) => {
      // if next letter starts at 3 create a break at random or move the last point
      if (nc == 3) rand() < 0.3 ? ip.splice(-1, 1, 0) : ip.splice(-2, 1, {x:17,y:23.8});
    }
    
  • ถัดจากนั้น เส้นทางพื้นฐานของตัวอักษรทั้งหมดจะถูกเชื่อมเข้าด้วยกัน โดยในขั้นตอนนี้จะมองข้ามค่า 1, 2, 3 ในเส้นทาง แต่ทุกครั้งที่เจอ 0 จะเริ่มเส้นทางใหม่เพื่อสร้างจุดขาด
  • จากนั้นจึงทำให้เส้นทางเป็นเส้นโค้ง แปลงเป็นรูปทรงที่มีความกว้างแปรผัน และเพิ่มความสั่นเล็กน้อยด้วย Perlin noise แล้วลายมือแบบตัวเขียนจะออกมาหน้าตาแบบนี้
  • บทความเกี่ยวกับวิธีสร้างประโยคนี้จะตามมาเร็ว ๆ นี้ ฝากสมัครรับจดหมายข่าวเพื่อรอติดตาม
  • เพื่อความสนุก นี่คือการเปรียบเทียบลายมือที่โค้ดขึ้นแล้วนำไปรันผ่าน plotter กับลายมือจริงแบบวางคู่กัน

หนักแค่ไหน?

  • คลาสตัวอักษรสำหรับพิมพ์บล็อกมีขนาด 9.7kb
  • ตอนนี้คลาสตัวอักษรแบบตัวเขียนมีขนาด 26.1kb (หลังบีบอัด)
  • คลาสนี้มีหลายเส้นทางสำหรับตัวอักษรแต่ละตัวและมีฟังก์ชันปรับจุด จึงมีขนาดใหญ่กว่า แต่ก็มีวิธีประหยัดพื้นที่แบบอื่นอยู่บ้าง
  • น่าจะยังประหยัดได้อีก ฉันไม่ใช่จอมเวท code golf แต่ก็มีไอเดียบางอย่าง
  • ตัวอย่างเช่น ตอนนี้ตัวอักษรถูกออกแบบโดยยึดขนาดฟอนต์พื้นฐาน 20 แล้วค่อยสเกลตามทีหลัง นั่นหมายความว่าหลายจุดถูกกำหนดเป็นค่าอย่าง x: 14.5 แต่ถ้าเปลี่ยนขนาดพื้นฐานเป็น 200 ก็จะกำหนดจุดเป็น 145 ได้และตัดเลขทศนิยมทิ้ง การเปลี่ยนนี้ต้องทำอย่างระมัดระวัง จึงอยู่ในรายการสิ่งที่จะทำภายหลัง

วิธีใช้งาน

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

ความเห็นของ GN⁺

  • บทความนี้นำเสนอตัวอย่างที่น่าสนใจของกระบวนการแปลงลายมือให้เป็นดิจิทัลด้วย JavaScript และ p5.js ซึ่งอาจเป็นโอกาสที่ดีสำหรับวิศวกรซอฟต์แวร์ในการฝึกทักษะการเขียนโค้ดผ่านโปรเจกต์เชิงสร้างสรรค์
  • คุณสามารถเรียนรู้วิธีนำอัลกอริทึมทางคณิตศาสตร์อย่างเส้นโค้งของ Chaikin ไปใช้ในโปรเจกต์จริงได้ ซึ่งช่วยเพิ่มความเข้าใจด้านกราฟิกโปรแกรมมิง
  • คุณสามารถเรียนรู้วิธีจัดการกับตรรกะที่ซับซ้อนอย่างฟังก์ชันปรับเส้นทาง ซึ่งเป็นทักษะสำคัญในการเพิ่มความยืดหยุ่นและการขยายต่อของโค้ด
  • โปรเจกต์นี้ยังจัดการกับปัญหาเชิงปฏิบัติอย่างการปรับขนาดไฟล์ให้เหมาะสม ซึ่งเป็นสิ่งสำคัญในการพัฒนาซอฟต์แวร์จริง
  • เมื่อนำเทคนิคนี้ไปใช้ ควรคำนึงว่าการกำหนดเส้นทางและการเขียนฟังก์ชันปรับแต่งอาจใช้เวลามาก แต่ผลลัพธ์ที่ได้จะให้รูปแบบข้อความที่มีความเป็นเอกลักษณ์และเฉพาะตัวอย่างมาก

ยังไม่มีความคิดเห็น

ยังไม่มีความคิดเห็น