Partilhar via


Polilinhas e equações paramétricas

Use SkiaSharp para renderizar qualquer linha que você possa definir com equações paramétricas

Na seção SkiaSharp Curves and Paths deste guia, você verá os vários métodos que SKPath definem para renderizar determinados tipos de curvas. No entanto, às vezes é necessário desenhar um tipo de curva que não é diretamente suportada pelo SKPath. Nesse caso, você pode usar uma polilinha (uma coleção de linhas conectadas) para desenhar qualquer curva que você possa definir matematicamente. Se você tornar as linhas pequenas o suficiente e numerosas o suficiente, o resultado parecerá uma curva. Esta espiral é, na verdade, 3.600 pequenas linhas:

Uma espiral

Geralmente é melhor definir uma curva em termos de um par de equações paramétricas. Estas são equações para coordenadas X e Y que dependem de uma terceira variável, às vezes chamada t de tempo. Por exemplo, as seguintes equações paramétricas definem um círculo com um raio de 1 centrado no ponto (0, 0) para t de 0 a 1:

x = cos(2πt)

y = sin(2πt)

Se você quiser um raio maior que 1, você pode simplesmente multiplicar os valores de seno e cosseno por esse raio e, se precisar mover o centro para outro local, adicione esses valores:

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

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

Para uma elipse com os eixos paralelos ao horizontal e vertical, dois raios estão envolvidos:

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

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

Em seguida, você pode colocar o código SkiaSharp equivalente em um loop que calcula os vários pontos e os adiciona a um caminho. O código SkiaSharp a seguir cria um SKPath objeto para uma elipse que preenche a superfície de exibição. O loop percorre os 360 graus diretamente. O centro é metade da largura e altura da superfície do monitor, assim como os dois raios:

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();

Isso resulta em uma elipse definida por 360 pequenas linhas. Quando é renderizado, ele parece suave.

Claro, você não precisa criar uma elipse usando uma polilinha porque SKPath inclui um AddOval método que faz isso para você. Mas talvez você queira desenhar um objeto visual que não é fornecido pelo SKPath.

A página Espiral de Arquimedes tem código semelhante ao código de elipse, mas com uma diferença crucial. Ele dá uma volta em torno dos 360 graus do círculo 10 vezes, ajustando continuamente o raio:

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);
    }
}

O resultado também é chamado de espiral aritmética porque o deslocamento entre cada loop é constante:

Captura de tela tripla da página Espiral de Arquimedes

Observe que o SKPath é criado em um using bloco. Isso SKPath consome mais memória do que os objetos nos programas anteriores, o SKPath que sugere que um using bloco é mais apropriado para descartar quaisquer recursos não gerenciados.