1 Punkte von GN⁺ 2024-05-20 | Noch keine Kommentare. | Auf WhatsApp teilen

Blockschrift

  • Der vorherige Artikel behandelte eine Alphabet-Version in Blockschrift.
  • Kurz gesagt wurde sie mit folgendem Prozess erstellt:
    • Code schreiben, der die wichtigsten Punkte des Pfads jedes Buchstabens definiert (~10 Punkte pro Buchstabe).
    • Den Pfad mit Chaikins Kurvenalgorithmus glätten.
    • Den Pfad in eine Form mit variabler Strichstärke umwandeln.
    • Den Formpfad mit p5js zeichnen.
  • So sah es aus:
  • Ein Artikel darüber, wie man mit diesem System Sätze erzeugt, erscheint bald. Am besten den Newsletter abonnieren, um informiert zu werden.
  • Das Definieren der ursprünglichen Buchstabenpfade war sehr manuell: Positionen mussten in den Code eingetragen und Punkte so angepasst werden, dass die Buchstaben richtig aussahen.
  • Beim Codieren einer Schreibschrift habe ich diesen Prozess vereinfacht.

Buchstabendesign

  • Ich habe ein Werkzeug erstellt, mit dem sich die wichtigsten Punkte eines Pfads definieren und ausgeben lassen, damit man im p5js-Editor leicht darauf zugreifen kann.
  • Es zeigt Beispielbuchstaben an und bietet einen Bereich zum Entwerfen neuer Buchstaben.
  • Der Ablauf ist dann folgender:
    • Die wichtigsten Punkte des Pfads anklicken und platzieren – der resultierende Chaikin-Kurvenpfad wird angezeigt.
    • Mit p in den Bearbeitungsmodus wechseln.
    • Punkte auswählen und an die gewünschte Position ziehen.
    • Mit enter den Pfad in der Konsole ausgeben.
  • Für jeden Buchstaben habe ich 2–3 Varianten erstellt.
  • Der resultierende Pfad sieht so aus:
    [{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}]
    
  • Ich wollte meine eigene Handschrift als Vorlage verwenden, also habe ich Beispiele für Klein- und Großbuchstaben geschrieben, das Bild direkt in das Werkzeug geladen und es nachgezeichnet.
  • Mit den Tasten w/a/s/d wird das Bild korrekt positioniert, mit r/e wird hinein- oder herausgezoomt.
  • Die Zahlen sind die x- und y-Koordinaten, um diesen Bereich im Fenster zur Buchstabenerzeugung zu platzieren.
  • Nachdem alle Pfade erstellt, geglättet und in Formen mit variabler Breite umgewandelt waren, sah jeder Buchstabe einzeln so aus.

In Schreibschrift umwandeln

  • Manchmal ist das Verbinden von Buchstaben einfach. Man geht direkt vom Pfad der wichtigsten Punkte zum nächsten Pfad über und wendet dann die Chaikin-Kurve auf alles zusammen an.
  • Einige Buchstabenpaare passen jedoch nicht gut zusammen.
  • Beim Paar na liegt zum Beispiel der letzte Punkt von n tief und der erste Punkt von a hoch, wodurch ein Pfad entsteht, der a diagonal durchquert und wie ein e aussieht.
  • Beim Paar ti endet das t über der Grundlinie und das i beginnt auf der Grundlinie, wodurch ein unnatürlicher Grat entsteht.
  • Um diese Probleme zu beheben, kann man am Anfang von a zusätzliche Punkte hinzufügen und die letzten zwei Punkte von t entfernen.
  • Allerdings kann man Buchstaben nicht in allen Szenarien auf diese Weise ändern.
  • Beginnt etwa ein Wort mit a, liegen die zusätzlichen Punkte an der falschen Stelle, und folgt auf Buchstaben wie w vor a, entsteht eine Linie, die a auf andere Weise durchquert.
  • Auch t wird verformt, wenn es mit k gepaart wird.
  • Start- und Endpunkte eines Buchstabenpfads müssen also je nach angrenzenden Buchstaben variieren.
  • Zuerst wollte ich bestimmte „Problem“-Paare aufrufen und Regeln dafür schreiben, habe dann aber schließlich am Anfang und Ende jedes Pfads Zahlen ergänzt, die Folgendes bedeuten:
    • Keine Verbindung mit einem anderen Buchstaben (0)
    • Verbindung mit einem anderen Buchstaben in der Nähe der Grundlinie (1)
    • Verbindung mit einem anderen Buchstaben direkt über der Grundlinie (2)
    • Verbindung mit einem anderen Buchstaben in der Nähe der x-Höhe (3)
  • Beispiel:
  • Jeder Buchstabenpfad sieht nun so aus. Beachte die einstelligen Zahlen am Anfang und Ende:
    [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]
    
  • Ich habe alle Buchstabenpaare getestet:
  • Hier sieht man, dass es für jeden Buchstaben mehrere Pfadvarianten gibt und wie sich die Buchstaben je nach Nachbarbuchstaben verändern.
  • Ideal wären mindestens 5–6 Pfadvarianten pro Buchstabe, aber das muss mit der Dateigröße abgewogen werden.

Wörter erzeugen

  • Wenn ein Wort erzeugt wird:
    • Für jeden Buchstaben wird ein Standardpfad aus 2–3 verschiedenen Varianten ausgewählt.
    • Informationen über das Ende des Pfads werden an benachbarte Buchstaben weitergegeben (verschiedene Pfadvarianten desselben Buchstabens können unterschiedliche Endpunkte haben, daher müssen zuerst alle Buchstabenpfade ausgewählt werden).
    • Der Standardpfad wird dann als Reaktion auf Nachbarbuchstaben angepasst. Endet zum Beispiel der vorherige Buchstabe auf Höhe 2, wird am Anfang dieses Pfads ein Punkt entfernt; beginnt der nächste Buchstabe auf Höhe 1, wird an einer bestimmten Stelle ein zusätzlicher Punkt eingefügt.
  • Die Anpassungsfunktion kann etwas komplex sein. Für den Buchstaben q sieht sie zum Beispiel so aus:
    // ip = Pfad
    // pc = Endinformation des vorherigen Buchstabens
    // nc = Startinformation des nächsten Buchstabens
    // n = Index des für diesen Buchstaben gewählten Pfads
    adjust: (ip, pc, nc, n) => {
      // Mit 70% Wahrscheinlichkeit einen Abbruch am Ende dieses Buchstabens einfügen
      if (rand() < 0.7 ) ip.splice(-1, 1, 0);
      // Falls [2] für diesen Pfad aus 4 Optionen ausgewählt wurde
      if (n < 2) {
        // Wenn der vorherige Buchstabe bei 3 endet, die ersten zwei Punkte durch einen anderen Punkt ersetzen
        if (pc == 3) ip.splice(1, 2, {x:10,y:12});
        // Andernfalls, wenn er nicht 0 ist, einen Punkt am Anfang hinzufügen
        else if (pc > 0) ip.splice(1, 0, {x:10,y:20});
      }
      // Wenn zwischen diesem Buchstaben und dem nächsten kein Abbruch liegt (0)
      if (nc > 0 && ip[ip.length-1] != 0){
        // Die letzten zwei Punkte durch einen anderen Punkt ersetzen
        ip.splice(-3, 2, {x:16,y:34});
      }
    }
    
  • Oft ist sie aber kurz. Für den Buchstaben n sieht die Funktion zum Beispiel so aus:
    adjust: (ip, pc, nc) => {
      // Wenn der nächste Buchstabe bei 3 beginnt, zufällig einen Abbruch erzeugen oder den letzten Punkt verschieben
      if (nc == 3) rand() < 0.3 ? ip.splice(-1, 1, 0) : ip.splice(-2, 1, {x:17,y:23.8});
    }
    
  • Danach werden die Standardpfade aller Buchstaben miteinander verbunden. Dabei werden die Werte 1, 2 und 3 im Pfad ignoriert, aber jedes Mal, wenn eine 0 vorkommt, wird ein neuer Pfad begonnen, um einen Abbruch zu erzeugen.
  • Anschließend wird der Pfad geglättet, in eine Form mit variabler Breite umgewandelt und mit Perlin-Rauschen leichtes Zittern hinzugefügt. So sieht die Schreibschrift dann aus.
  • Ein Artikel darüber, wie dieser Satz erzeugt wird, erscheint bald. Am besten den Newsletter abonnieren, um informiert zu werden.
  • Zum Spaß hier ein direkter Vergleich zwischen der programmierten Handschrift, die mit einem Plotter ausgeführt wurde, und der echten Handschrift.

Wie viel wiegt das?

  • Die Buchstabenklasse für Blockschrift war 9.7kb groß.
  • Die Schreibschrift-Buchstabenklasse ist derzeit 26.1kb groß (nach Komprimierung).
  • Diese Klasse ist größer, weil sie mehrere Pfade pro Buchstabe sowie Funktionen zum Anpassen der Punkte enthält. Es gibt aber auch noch einige andere Sparmöglichkeiten.
  • Ich glaube, da lässt sich noch mehr einsparen. Ich bin zwar kein Code-Golf-Zauberer, aber ich habe ein paar Ideen.
  • Aktuell sind die Buchstaben zum Beispiel für eine Standard-Schriftgröße von 20 entworfen und werden dann skaliert. Das bedeutet, viele Punkte sind als x: 14.5 definiert. Würde man die Standardgröße auf 200 ändern, könnte man Punkte als 145 definieren und die Dezimalstellen entfernen. Diese Änderung muss sorgfältig erfolgen, deshalb steht sie erst einmal auf meiner To-do-Liste.

Nutzung

  • Der Hauptzweck dieser Handschrift sind Titel, Labels und gekritzelte Notizen in Diagrammen, an denen ich gerade arbeite.
  • Es macht aber auch einfach sehr viel Spaß, mit dem Text selbst zu spielen.
  • Da die Pfade kodiert sind, kann ich statt einer Schriftart direkt mit den Pfaden arbeiten. Zum Beispiel die Positionen der Buchstaben ändern oder die Strichstärke einzelner Buchstaben variieren.
  • Als Nächstes werde ich diese Handschrift in Diagramme integrieren, plane aber auch etwas, das sich ganz auf den Text selbst konzentriert. Es ist sehr schön und bietet viele Möglichkeiten.

Meinung von GN⁺

  • Dieser Artikel liefert ein interessantes Beispiel für den Prozess, Handschrift mit JavaScript und p5.js zu digitalisieren. Für Softwareingenieure kann das eine gute Gelegenheit sein, ihre Coding-Fähigkeiten in einem kreativen Projekt zu trainieren.
  • Man kann lernen, wie mathematische Algorithmen wie Chaikins Kurvenalgorithmus in realen Projekten angewendet werden. Das hilft, das Verständnis für Grafikprogrammierung zu vertiefen.
  • Man kann lernen, mit komplexer Logik wie Pfadanpassungsfunktionen umzugehen. Das ist eine wichtige Fähigkeit, um Flexibilität und Erweiterbarkeit von Code zu erhöhen.
  • Das Projekt behandelt praktische Probleme wie die Optimierung der Dateigröße. Das ist ein wichtiger Aspekt in der realen Softwareentwicklung.
  • Bei der Einführung dieser Technik sollte man berücksichtigen, dass das Definieren der Pfade und das Schreiben der Anpassungsfunktionen viel Zeit kosten kann. Das Ergebnis bietet dafür aber eine stark personalisierte und einzigartige Darstellung von Text.

Noch keine Kommentare.

Noch keine Kommentare.