Ich möchte einen strichenen Pfad in ein gefülltes Objekt konvertieren. (Programmatisch, in JavaScript.)
Die Linie ist nur eine einfache gekrümmte Linie, eine Folge von Koordinaten. Ich kann diese Linie als einen Weg rendern und ihr einen Strich von bestimmter Stärke geben ... aber ich versuche eine gefüllte Form zu bekommen, anstatt eine Strichlinie, damit ich weitere Modifikationen daran vornehmen kann, wie zum Beispiel das Warping Es kann also sein, dass der resultierende "Schlag" in der Dicke schwankt oder dass benutzerdefinierte Bits herausgeschnitten werden (beides ist mit einem echten SVG-Schlag nicht möglich, soweit ich das beurteilen kann).
Ich versuche also, eine Linie manuell zu einer festen Form zu verdicken. Ich kann keine Funktion finden, die das tut - ich habe die Dokumente von D3.js und Raphaël , aber kein Glück. Kennt jemand eine Bibliothek / Funktion, die dies tun würde?
Oder, noch besser: wenn mir jemand die Geometrie-Theorie erklären könnte, wie ich diese Aufgabe manuell machen würde, indem ich die Liste der Linienkoordinaten, die ich habe, ausarbeite und einen neuen Weg ausarbeite, der ihn effektiv "streichelt" Sei unglaublich. Um es anders auszudrücken, was macht der Browser , wenn Sie ihm sagen, dass er einen Pfad streichen soll - wie funktioniert es, welche Form der Strich haben soll?
In letzter Zeit gab es eine ähnliche Frage: svg: generiere 'Outline-Pfad'
Alles in allem ist dies eine nicht-triviale Aufgabe. Wie in meiner Antwort auf die verknüpfte Frage erwähnt, hat PostScript einen Befehl zum Erzeugen von Pfaden, die im Grunde die gleiche Ausgabe wie ein Strich erzeugen, genannt strokepath
. Wenn Sie sich ansehen, was Ghostscript ausspuckt, wenn Sie den Code ausführen, den ich bei der verknüpften Frage gepostet habe, ist das ziemlich hässlich. Und selbst Inkscape macht keinen guten Job. Ich habe gerade versucht Path = & gt; Umrissstrich in Inkscape (ich denke, das sollten die englischen Untertitel sagen), und was herauskam, sah nicht wirklich genauso aus wie der strichförmige Pfad.
Der "einfachste" Fall wäre, wenn Sie nur sich nicht selbst schneidende Polylinien, Polygone oder Pfade haben, die keine Kurven enthalten, weil Sie im Allgemeinen keine exakten "parallelen" Bézier-Kurven nach rechts ziehen können links von einer nicht-trivialen Bézier-Kurve, die den gerasterten Bereich abgrenzen würde - mathematisch nicht existent. Sie müssten es also auf die eine oder andere Weise angehen. Für gerade Liniensegmente kann die exakte Lösung vergleichsweise einfach gefunden werden.
Die klassische Art, Vektorpfade mit Kurven / Bögen in ihnen zu rendern, ist es, alles mit einer ausreichend glatten Polylinie anzunähern. De Casteljaus Algorithmus wird normalerweise verwendet, um Bézier-Kurven in Liniensegmente zu verwandeln. (Das ist auch der Fall, wenn Sie den Befehl strokepath
in Ghostscript verwenden.) Sie können dann parallele Liniensegmente abgrenzen, müssen diese jedoch korrekt verbinden, indem Sie die entsprechenden Linejoin- und Miterlimit-Regeln verwenden. Vergesse natürlich nicht die Linecaps.
Ich dachte, dass sich selbst schneidende Pfade schwierig sein könnten, weil Sie hohle Bereiche innerhalb des Pfades bekommen könnten, d. h. der "Kreuzungsbereich" eines schwarzen Pfades könnte weiß werden. Dies ist möglicherweise kein Problem für offene Pfade, wenn Sie die Regel mit nicht null Zeilenumbrüchen verwenden, aber ich wäre vorsichtig dabei. Für geschlossene Pfade benötigen Sie wahrscheinlich die zwei "begrenzenden" Pfade, die in entgegengesetzter Ausrichtung verlaufen. Aber ich bin mir nicht sicher, ob das wirklich alle möglichen Fallstricke abdeckt.
Tut mir leid, wenn ich damit viel Verwirrung stifte und vielleicht nicht viel hilft.
Die Standardmethode ist der Tiller-Hanson-Algorithmus (Offsets of Two-Dimensional Profiles, 1984, der irritierend nicht online verfügbar ist), der eine gute Annäherung erzeugt. Die Idee ist, dass, da die Kontrollpunkte jeder Bezier-Kurve auf Linien liegen, die tangential zum Anfang und Ende der Kurve liegen, eine parallele Kurve die gleiche Eigenschaft haben wird. Wir gleichen den Anfang und das Ende der Kurve aus und finden dann neue Kontrollpunkte mit diesen Schnittpunkten. Dies führt jedoch zu sehr schlechten Ergebnissen für scharfe Kurven. Daher besteht der erste Schritt darin, die ursprüngliche Kurve zu halbieren, was sehr einfach für Bezier-Kurven ist, bis sie sich durch einen ausreichend kleinen Winkel dreht.
Andere Verfeinerungen sind erforderlich, um (i) Schnittpunkte zwischen den Parallelen auf der Innenseite jeder Ecke zu behandeln; (ii) Einfügen eines Kreisbogens, um die Lücke an der Außenseite jedes Scheitelpunkts zu füllen; und (iii) Hinzufügen von Endkappen - quadratisch, stumpf oder kreisförmig.
Tiller-Hanson ist schwer zu implementieren, aber es gibt eine gute Open-Source-Implementierung in der FreeType-Bibliothek in ftstroke.c (http://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree /src/base/ftstroke.c).
Es tut mir leid zu sagen, dass es ziemlich schwierig sein kann, diesen Code zu integrieren, aber ich habe ihn erfolgreich verwendet, und es funktioniert gut.
Diese Seite hat ein ziemlich gutes Tutorial über Bezier-Kurven im Allgemeinen mit einem schönen Abschnitt über Offset-Kurven.
Eine weniger genaue, aber möglicherweise schnellere Methode kann hier gefunden werden.
Es gibt keine mathematische Antwort, da die Kurve parallel zu einer Bezier-Kurve im Allgemeinen keine Bezier-Kurve ist. Die meisten Methoden haben degenerierte Fälle, besonders wenn es sich um eine Reihe von Kurven handelt.
Stellen Sie sich eine einfache Kurve ohne Probleme vor. Keine Höcker, keine Schleifen, keine Beugungen und idealerweise eine streng zunehmende Krümmung. Zerschneide alle Anfangskurven in diese einfachen Kurven. Finden Sie alle Offset-Kurven dieser einfachen Kurven. Setzen Sie alle Offset-Kurven wieder zusammen, indem Sie Lücken und Überschneidungen behandeln. Quadratische Kurven sind viel leichter zu handhaben, wenn Sie die Option haben, mit ihnen zu arbeiten.
Ich denke, die meisten Browser machen etwas ähnliches wie die Verarbeitung von js, da sie selbst bei quadratischen Kurven degenerierte Fälle haben. Betrachten Sie zum Beispiel die Kurve 200,300 719,301 500,300 mit einer Dicke von 100 oder mehr.
Tags und Links svg d3.js raphael vector-graphics