1 điểm bởi GN⁺ 2024-05-20 | Chưa có bình luận nào. | Chia sẻ qua WhatsApp

Chữ in khối

  • Bài viết trước nói về phiên bản bảng chữ cái kiểu chữ in khối.
  • Tóm lại, nó được tạo ra theo quy trình như sau:
    • Viết mã để định nghĩa các điểm chính trên đường đi của từng chữ cái (~10 điểm cho mỗi chữ).
    • Dùng thuật toán đường cong Chaikin để làm mượt đường đi.
    • Chuyển đường đi thành hình dạng có độ dày biến thiên.
    • Dùng p5js để vẽ đường viền của hình dạng.
  • Nó trông như thế này:
  • Một bài viết về cách tạo câu bằng hệ thống này sẽ sớm được đăng. Hãy đăng ký newsletter để nhận tin.
  • Ban đầu, việc định nghĩa đường đi của chữ cái là công việc rất thủ công: nhập vị trí vào mã rồi tinh chỉnh các điểm để chữ trông đúng.
  • Khi mã hóa chữ viết tay nối nét, tôi đã đơn giản hóa quy trình này.

Thiết kế chữ cái

  • Tôi đã tạo một công cụ để định nghĩa và xuất ra các điểm chính của đường đi, giúp dễ truy cập ngay trong trình biên tập p5js.
  • Nó hiển thị một chữ cái mẫu và cung cấp khu vực để thiết kế chữ mới.
  • Các bước tiếp theo như sau:
    • Nhấp để đặt các điểm chính của đường đi - đường cong Chaikin kết quả sẽ được hiển thị.
    • Nhấn p để chuyển sang chế độ chỉnh sửa.
    • Chọn điểm và kéo đến vị trí mong muốn.
    • Nhấn enter để in đường đi ra console.
  • Tôi đã tạo 2-3 phương án cho mỗi chữ cái.
  • Đường đi kết quả như sau:
    [{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}]
    
  • Tôi muốn dùng chính nét chữ của mình làm hướng dẫn, nên đã viết mẫu chữ thường và chữ hoa, rồi tải ảnh trực tiếp vào công cụ để đồ theo.
  • Dùng các phím w/a/s/d để đặt ảnh vào đúng vị trí và r/e để phóng to hoặc thu nhỏ ảnh.
  • Các con số là tọa độ x y để đặt vùng đó vào cửa sổ tạo chữ.
  • Sau khi tạo toàn bộ đường đi, vẽ đường cong và chuyển chúng thành hình dạng có bề rộng biến thiên, từng chữ cái trông như thế này.

Biến thành chữ viết tay nối nét

  • Đôi khi việc nối các chữ cái khá dễ. Chỉ cần đi thẳng từ đường đi của các điểm chính sang đường tiếp theo rồi áp dụng đường cong Chaikin cho toàn bộ một lượt.
  • Nhưng một số cặp chữ lại không khớp tốt.
  • Ví dụ, với cặp na, điểm cuối của n thấp còn điểm đầu của a lại cao, tạo ra một đường chéo cắt qua a khiến nó trông giống e.
  • Với cặp ti, t kết thúc ở phía trên baseline còn i bắt đầu từ baseline, tạo ra một gờ không tự nhiên.
  • Để giải quyết các vấn đề này, có thể thêm điểm bổ sung ở đầu a và xóa hai điểm cuối của t.
  • Tuy nhiên, không thể sửa chữ theo cách này trong mọi tình huống.
  • Ví dụ, nếu a ở đầu từ thì điểm bổ sung sẽ nằm sai chỗ, và nếu nó đứng sau chữ như w thì sẽ tạo ra một nét cắt qua a theo cách khác.
  • t cũng bị méo khi ghép với k.
  • Điểm bắt đầu và kết thúc của đường đi chữ cái cần thay đổi tùy theo vị trí của các chữ khác.
  • Lúc đầu tôi định gọi ra các cặp "có vấn đề" cụ thể rồi viết quy tắc cho chúng, nhưng cuối cùng tôi thêm các con số vào đầu và cuối mỗi đường đi để biểu thị:
    • Không nối với chữ khác (0)
    • Nối với chữ khác quanh baseline (1)
    • Nối với chữ khác ngay phía trên baseline (2)
    • Nối với chữ khác quanh x-height (3)
  • Ví dụ:
  • Giờ đây, mỗi đường đi chữ cái trông như sau. Hãy chú ý các chữ số một chữ số ở đầu và cuối:
    [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]
    
  • Tôi đã kiểm thử mọi cặp chữ cái:
  • Ở đây bạn có thể thấy có nhiều phương án đường đi cho mỗi chữ, và các thay đổi phát sinh khi chữ được chỉnh sửa tùy theo chữ đứng cạnh nó.
  • Lý tưởng nhất là tôi muốn có ít nhất 5-6 phương án đường đi cho mỗi chữ, nhưng phải cân bằng với kích thước tệp.

Tạo từ

  • Khi một từ được tạo ra:
    • Với mỗi chữ cái, một đường đi mặc định được chọn trong 2-3 phương án khác nhau.
    • Thông tin về phần cuối của đường đi được truyền cho các chữ liền kề (vì các phương án đường đi khác nhau của cùng một chữ có thể có điểm cuối khác nhau, nên phải chọn toàn bộ đường đi của các chữ trước).
    • Đường đi mặc định sẽ được điều chỉnh để phản ứng với các chữ hàng xóm. Ví dụ, nếu độ cao điểm cuối của chữ trước là 2 thì xóa 1 điểm ở đầu đường đi này, hoặc nếu độ cao điểm đầu của chữ sau là 1 thì thêm một điểm phụ ở vị trí nhất định.
  • Hàm điều chỉnh có thể hơi phức tạp. Ví dụ, hàm cho chữ q như sau:
    // ip = đường đi
    // pc = thông tin điểm cuối của chữ trước
    // nc = thông tin điểm đầu của chữ sau
    // n = chỉ số của đường đi được chọn cho chữ này
    adjust: (ip, pc, nc, n) => {
      // thêm ngắt nét ở cuối chữ này với xác suất 70%
      if (rand() < 0.7 ) ip.splice(-1, 1, 0);
      // nếu [2] trong 4 lựa chọn được chọn cho đường đi này
      if (n < 2) {
        // nếu chữ trước kết thúc ở 3 thì thay hai điểm đầu bằng điểm khác
        if (pc == 3) ip.splice(1, 2, {x:10,y:12});
        // nếu không, nếu khác 0 thì thêm một điểm ở đầu
        else if (pc > 0) ip.splice(1, 0, {x:10,y:20});
      }
      // nếu không có ngắt nét giữa chữ này và chữ tiếp theo (0)
      if (nc > 0 && ip[ip.length-1] != 0){
        // thay hai điểm cuối bằng điểm khác
        ip.splice(-3, 2, {x:16,y:34});
      }
    }
    
  • Nhưng nhiều khi nó ngắn hơn. Ví dụ, hàm cho chữ n như sau:
    adjust: (ip, pc, nc) => {
      // nếu chữ sau bắt đầu ở 3 thì ngẫu nhiên tạo ngắt nét hoặc di chuyển điểm cuối
      if (nc == 3) rand() < 0.3 ? ip.splice(-1, 1, 0) : ip.splice(-2, 1, {x:17,y:23.8});
    }
    
  • Tiếp theo, toàn bộ các đường đi mặc định của các chữ cái được nối lại với nhau. Trong quá trình này, các giá trị 1, 2, 3 trong đường đi bị bỏ qua, nhưng mỗi khi có 0 thì một đường đi mới sẽ được bắt đầu để tạo ngắt nét.
  • Sau đó, các đường đi được làm cong, chuyển thành hình dạng có độ rộng biến thiên, rồi thêm một chút rung bằng nhiễu Perlin, và chữ viết tay nối nét sẽ trông như thế này.
  • Một bài viết về cách tạo ra câu này sẽ sớm được đăng. Hãy đăng ký newsletter để nhận tin.
  • Để cho vui, đây là phần so sánh song song giữa nét chữ đã được mã hóa chạy qua plotter và nét chữ thật.

Nó nặng bao nhiêu?

  • Lớp chữ cái cho chữ in khối có dung lượng 9.7kb.
  • Lớp chữ viết tay nối nét hiện tại là 26.1kb (sau nén).
  • Lớp này lớn hơn vì nó bao gồm nhiều đường đi cho mỗi chữ và các hàm điều chỉnh điểm. Tuy nhiên cũng có một vài cách tiết kiệm khác.
  • Có lẽ vẫn còn tối ưu thêm được. Tôi không phải phù thủy code golf, nhưng có vài ý tưởng.
  • Ví dụ, hiện tại chữ được thiết kế theo cỡ chữ cơ sở 20 rồi mới scale. Điều này có nghĩa là nhiều điểm được định nghĩa như x: 14.5, nhưng nếu đổi cỡ cơ sở thành 200 thì có thể định nghĩa điểm là 145 và loại bỏ số thập phân. Đây là thay đổi cần làm cẩn thận, nên tôi để vào danh sách việc cần làm sau.

Cách sử dụng

  • Mục đích chính của bộ nét chữ này là dùng cho tiêu đề, nhãn và ghi chú nguệch ngoạc trong các sơ đồ mà tôi đang làm.
  • Nhưng chỉ riêng việc nghịch với văn bản cũng đã rất thú vị.
  • Nhờ việc mã hóa các đường đi, thay vì dùng font, tôi có thể thao tác trực tiếp với các đường đi. Ví dụ như thay đổi vị trí chữ cái hoặc thay đổi độ dày của từng chữ riêng lẻ.
  • Tiếp theo tôi sẽ tích hợp bộ nét chữ này vào sơ đồ, nhưng cũng dự định làm một thứ tập trung hoàn toàn vào bản thân văn bản. Nó rất đẹp và có nhiều khả năng.

Ý kiến của GN⁺

  • Bài viết này đưa ra một ví dụ thú vị về quá trình số hóa nét chữ bằng JavaScript và p5.js. Đây có thể là cơ hội tốt để các kỹ sư phần mềm rèn luyện kỹ năng lập trình thông qua một dự án sáng tạo.
  • Có thể học cách áp dụng các thuật toán toán học như thuật toán đường cong Chaikin vào dự án thực tế. Điều này giúp nâng cao hiểu biết về lập trình đồ họa.
  • Có thể học cách xử lý logic phức tạp như các hàm điều chỉnh đường đi. Đây là kỹ năng quan trọng để tăng tính linh hoạt và khả năng mở rộng của mã.
  • Dự án này xử lý các vấn đề thực tế như tối ưu kích thước tệp. Đây là yếu tố quan trọng trong phát triển phần mềm thực tế.
  • Khi áp dụng kỹ thuật này, việc định nghĩa đường đi và viết các hàm điều chỉnh có thể tốn nhiều thời gian. Tuy nhiên, kết quả mang lại là một cách biểu đạt văn bản rất cá nhân hóa và độc đáo.

Chưa có bình luận nào.

Chưa có bình luận nào.