Condividi tramite


Polilinee ed equazioni parametriche

Usare SkiaSharp per eseguire il rendering di qualsiasi riga che è possibile definire con equazioni parametriche

Nella sezione SkiaSharp Curve and Paths di questa guida verranno visualizzati i vari metodi che SKPath definiscono per eseguire il rendering di determinati tipi di curve. Tuttavia, a volte è necessario disegnare un tipo di curva che non è supportato direttamente da SKPath. In questo caso, è possibile utilizzare una polilinea (una raccolta di linee connesse) per disegnare qualsiasi curva che è possibile definire matematicamente. Se si rendono le linee sufficientemente piccole e numerose, il risultato sarà simile a una curva. Questa spirale è in realtà 3.600 piccole linee:

Una spirale

In genere è preferibile definire una curva in termini di coppia di equazioni parametriche. Si tratta di equazioni per le coordinate X e Y che dipendono da una terza variabile, talvolta chiamata t per il tempo. Ad esempio, le equazioni parametriche seguenti definiscono un cerchio con un raggio di 1 centrato nel punto (0, 0) per t da 0 a 1:

x = cos(2πt)

y = sin(2πt)

Se si desidera un raggio maggiore di 1, è sufficiente moltiplicare i valori seno e coseno per tale raggio e, se è necessario spostare il centro in un'altra posizione, aggiungere tali valori:

x = xCenter + radius·cos(2πt)

y = yCenter + radius·sin(2πt)

Per un'ellisse con gli assi paralleli all'orizzontale e verticale, sono coinvolti due raggi:

x = xCenter + xRadius·cos(2πt)

y = yCenter + yRadius·sin(2πt)

È quindi possibile inserire il codice SkiaSharp equivalente in un ciclo che calcola i vari punti e li aggiunge a un percorso. Il codice SkiaSharp seguente crea un SKPath oggetto per un'ellisse che riempie la superficie di visualizzazione. Il ciclo scorre direttamente i 360 gradi. Il centro è la metà della larghezza e dell'altezza della superficie di visualizzazione, quindi sono i due raggi:

SKPath path = new SKPath();

for (float angle = 0; angle < 360; angle += 1)
{
    double radians = Math.PI * angle / 180;
    float x = info.Width / 2 + (info.Width / 2) * (float)Math.Cos(radians);
    float y = info.Height / 2 + (info.Height / 2) * (float)Math.Sin(radians);

    if (angle == 0)
    {
        path.MoveTo(x, y);
    }
    else
    {
        path.LineTo(x, y);
    }
}
path.Close();

Ciò comporta un'ellisse definita da 360 piccole linee. Quando viene eseguito il rendering, sembra uniforme.

Naturalmente, non è necessario creare un'ellisse usando una polilinea perché SKPath include un AddOval metodo che lo esegue automaticamente. È tuttavia possibile disegnare un oggetto visivo non fornito da SKPath.

La pagina Archimedean Spiral ha codice simile al codice dell'ellisse, ma con una differenza cruciale. Scorre intorno ai 360 gradi del cerchio 10 volte, regolando continuamente il raggio:

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

    canvas.Clear();

    SKPoint center = new SKPoint(info.Width / 2, info.Height / 2);
    float radius = Math.Min(center.X, center.Y);

    using (SKPath path = new SKPath())
    {
        for (float angle = 0; angle < 3600; angle += 1)
        {
            float scaledRadius = radius * angle / 3600;
            double radians = Math.PI * angle / 180;
            float x = center.X + scaledRadius * (float)Math.Cos(radians);
            float y = center.Y + scaledRadius * (float)Math.Sin(radians);
            SKPoint point = new SKPoint(x, y);

            if (angle == 0)
            {
                path.MoveTo(point);
            }
            else
            {
                path.LineTo(point);
            }
        }

        SKPaint paint = new SKPaint
        {
            Style = SKPaintStyle.Stroke,
            Color = SKColors.Red,
            StrokeWidth = 5
        };

        canvas.DrawPath(path, paint);
    }
}

Il risultato è detto anche spirale aritmetica perché l'offset tra ogni ciclo è costante:

Screenshot triplo della pagina Spirale di Archimedean

Si noti che l'oggetto SKPath viene creato in un using blocco. Questo SKPath utilizza più memoria degli SKPath oggetti nei programmi precedenti, che suggerisce che un using blocco è più appropriato per eliminare eventuali risorse non gestite.