Pfadgrundlagen in SkiaSharp

Beispiel herunterladen Das Beispiel herunterladen

Erkunden des SkiaSharp SKPath-Objekts zum Kombinieren verbundener Linien und Kurven

Eines der wichtigsten Features des Grafikpfads ist die Möglichkeit zu definieren, wann mehrere Zeilen verbunden werden sollen und wann sie nicht verbunden werden sollen. Der Unterschied kann signifikant sein, wie die Oberen dieser beiden Dreiecke zeigen:

Zwei Dreiecke, die den Unterschied zwischen verbundenen und getrennten Linien zeigen

Ein Grafikpfad wird vom SKPath -Objekt gekapselt. Ein Pfad ist eine Auflistung einer oder mehrerer Konturen. Jede Kontur ist eine Sammlung verbundener gerader Linien und Kurven. Konturen sind nicht miteinander verbunden, aber sie können sich visuell überschneiden. Manchmal kann sich eine einzelne Kontur überlappen.

Eine Kontur beginnt im Allgemeinen mit einem Aufruf der folgenden Methode von SKPath:

  • MoveTo , um eine neue Kontur zu beginnen

Das Argument für diese Methode ist ein einzelner Punkt, den Sie entweder als SKPoint Wert oder als separate X- und Y-Koordinaten ausdrücken können. Der MoveTo Aufruf erstellt einen Punkt am Anfang der Kontur und einen anfänglichen Strompunkt. Sie können die folgenden Methoden aufrufen, um die Kontur mit einer Linie oder Kurve vom aktuellen Punkt zu einem in der -Methode angegebenen Punkt fortzusetzen, der dann zum neuen aktuellen Punkt wird:

  • LineTo , um dem Pfad eine gerade Linie hinzuzufügen
  • ArcTo , um einen Bogen hinzuzufügen, bei dem es sich um eine Linie im Umfang eines Kreises oder einer Ellipse handelt
  • CubicTo so fügen Sie eine kubische Bézier-Spline hinzu
  • QuadTo so fügen Sie eine quadratische Bézier-Spline hinzu
  • ConicTo , um eine rationale quadratische Bézier-Spline hinzuzufügen, die konische Abschnitte (Ellipsen, Parabeln und Hyperbeln) genau rendern kann

Keine dieser fünf Methoden enthält alle Informationen, die zum Beschreiben der Linie oder Kurve erforderlich sind. Jede dieser fünf Methoden funktioniert in Verbindung mit dem aktuellen Punkt, der durch den Methodenaufruf unmittelbar vor dem Aufruf festgelegt wurde. Beispielsweise fügt die LineTo -Methode der Kontur basierend auf dem aktuellen Punkt eine gerade Linie hinzu, sodass der Parameter von LineTo nur ein einzelner Punkt ist.

Die SKPath -Klasse definiert auch Methoden, die die gleichen Namen wie diese sechs Methoden haben, aber mit einem R am Anfang:

Steht R für relativ. Diese Methoden weisen die gleiche Syntax wie die entsprechenden Methoden ohne auf, R sind aber relativ zum aktuellen Punkt. Diese sind praktisch, um ähnliche Teile eines Pfads in einer Methode zu zeichnen, die Sie mehrmals aufrufen.

Eine Kontur endet mit einem weiteren Aufruf von MoveTo oder RMoveTo, der eine neue Kontur beginnt, oder mit einem Aufruf von Close, der die Kontur schließt. Die Close -Methode fügt automatisch eine gerade Linie vom aktuellen Punkt an den ersten Punkt der Kontur an und markiert den Pfad als geschlossen, was bedeutet, dass er ohne Strichkappen gerendert wird.

Der Unterschied zwischen offenen und geschlossenen Konturen wird auf der Seite Zwei Dreieckskonturen veranschaulicht, die ein SKPath Objekt mit zwei Konturen verwendet, um zwei Dreiecke zu rendern. Die erste Kontur ist offen und die zweite ist geschlossen. Dies ist die TwoTriangleContoursPage-Klasse:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    SKImageInfo info = args.Info;
    SKSurface surface = args.Surface;
    SKCanvas canvas = surface.Canvas;

    canvas.Clear();

    // Create the path
    SKPath path = new SKPath();

    // Define the first contour
    path.MoveTo(0.5f * info.Width, 0.1f * info.Height);
    path.LineTo(0.2f * info.Width, 0.4f * info.Height);
    path.LineTo(0.8f * info.Width, 0.4f * info.Height);
    path.LineTo(0.5f * info.Width, 0.1f * info.Height);

    // Define the second contour
    path.MoveTo(0.5f * info.Width, 0.6f * info.Height);
    path.LineTo(0.2f * info.Width, 0.9f * info.Height);
    path.LineTo(0.8f * info.Width, 0.9f * info.Height);
    path.Close();

    // Create two SKPaint objects
    SKPaint strokePaint = new SKPaint
    {
        Style = SKPaintStyle.Stroke,
        Color = SKColors.Magenta,
        StrokeWidth = 50
    };

    SKPaint fillPaint = new SKPaint
    {
        Style = SKPaintStyle.Fill,
        Color = SKColors.Cyan
    };

    // Fill and stroke the path
    canvas.DrawPath(path, fillPaint);
    canvas.DrawPath(path, strokePaint);
}

Die erste Kontur besteht aus einem Aufruf MoveTo der X- und Y-Koordinaten anstelle eines SKPoint Werts, gefolgt von drei Aufrufen von, LineTo um die drei Seiten des Dreiecks zu zeichnen. Die zweite Kontur hat nur zwei Aufrufe von LineTo , aber sie beendet die Kontur mit einem Aufruf von Close, der die Kontur schließt. Der Unterschied ist signifikant:

"

Wie Sie sehen können, besteht die erste Kontur offensichtlich aus einer Reihe von drei verbundenen Linien, aber das Ende verbindet sich nicht mit dem Anfang. Die beiden Zeilen überlappen sich oben. Die zweite Kontur ist offensichtlich geschlossen und wurde mit einem Aufruf weniger LineTo erreicht, da die Close Methode automatisch eine letzte Linie hinzufügt, um die Kontur zu schließen.

SKCanvas definiert nur eine DrawPath Methode, die in dieser Demonstration zweimal aufgerufen wird, um den Pfad zu füllen und zu strichen. Alle Konturen sind gefüllt, auch solche, die nicht geschlossen sind. Zum Füllen von nicht abgeschlossenen Pfaden wird angenommen, dass zwischen den Anfangs- und Endpunkten der Konturen eine gerade Linie vorhanden ist. Wenn Sie die letzte LineTo von der ersten Kontur oder den Close Aufruf von der zweiten Kontur entfernen, hat jede Kontur nur zwei Seiten, wird aber wie ein Dreieck ausgefüllt.

SKPath definiert viele andere Methoden und Eigenschaften. Die folgenden Methoden fügen dem Pfad ganze Konturen hinzu, die je nach Methode geschlossen oder nicht geschlossen sein können:

Beachten Sie, dass ein SKPath Objekt nur eine Geometrie definiert – eine Reihe von Punkten und Verbindungen. Nur wenn ein SKPath mit einem SKPaint -Objekt kombiniert wird, wird der Pfad mit einer bestimmten Farbe, Strichbreite usw. gerendert. Beachten Sie auch, dass das an die SKPaintDrawPath -Methode übergebene Objekt Merkmale des gesamten Pfads definiert. Wenn Sie etwas zeichnen möchten, das mehrere Farben erfordert, müssen Sie für jede Farbe einen separaten Pfad verwenden.

Genau wie die Darstellung von Anfang und Ende einer Linie durch eine Strichkappe definiert wird, wird die Darstellung der Verbindung zwischen zwei Linien durch einen Strichjoin definiert. Geben Sie dies an, indem Sie die StrokeJoin -Eigenschaft von SKPaint auf einen Member der SKStrokeJoin -Enumeration festlegen:

  • Miter für einen pointy join
  • Round für einen abgerundeten Join
  • Bevel für einen abgehackten Join

Auf der Seite Strichverknappungen werden diese drei Strichjoins angezeigt, deren Code der Seite Strichkappen ähnelt. Dies ist der PaintSurface Ereignishandler in der StrokeJoinsPage -Klasse:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    SKImageInfo info = args.Info;
    SKSurface surface = args.Surface;
    SKCanvas canvas = surface.Canvas;

    canvas.Clear();

    SKPaint textPaint = new SKPaint
    {
        Color = SKColors.Black,
        TextSize = 75,
        TextAlign = SKTextAlign.Right
    };

    SKPaint thickLinePaint = new SKPaint
    {
        Style = SKPaintStyle.Stroke,
        Color = SKColors.Orange,
        StrokeWidth = 50
    };

    SKPaint thinLinePaint = new SKPaint
    {
        Style = SKPaintStyle.Stroke,
        Color = SKColors.Black,
        StrokeWidth = 2
    };

    float xText = info.Width - 100;
    float xLine1 = 100;
    float xLine2 = info.Width - xLine1;
    float y = 2 * textPaint.FontSpacing;
    string[] strStrokeJoins = { "Miter", "Round", "Bevel" };

    foreach (string strStrokeJoin in strStrokeJoins)
    {
        // Display text
        canvas.DrawText(strStrokeJoin, xText, y, textPaint);

        // Get stroke-join value
        SKStrokeJoin strokeJoin;
        Enum.TryParse(strStrokeJoin, out strokeJoin);

        // Create path
        SKPath path = new SKPath();
        path.MoveTo(xLine1, y - 80);
        path.LineTo(xLine1, y + 80);
        path.LineTo(xLine2, y + 80);

        // Display thick line
        thickLinePaint.StrokeJoin = strokeJoin;
        canvas.DrawPath(path, thickLinePaint);

        // Display thin line
        canvas.DrawPath(path, thinLinePaint);
        y += 3 * textPaint.FontSpacing;
    }
}

Dies ist das Programm, das ausgeführt wird:

–Dreifacher Screenshot der Seite

Der Gehrungsjoin besteht aus einem scharfen Punkt, an dem sich die Linien verbinden. Wenn zwei Linien in einem kleinen Winkel miteinander verknüpft sind, kann die Gehrungsjoin ziemlich lang werden. Um zu lange Miterjoins zu verhindern, wird die Länge des Gehrungsjoins durch den Wert der StrokeMiter -Eigenschaft von SKPaintbegrenzt. Ein Gehrungsjoin, der diese Länge überschreitet, wird abgehackt, um zu einem Abgeschrägten zu werden.