多角形やパラメーターの式

SkiaSharp を使用して、パラメトリック方程式で定義できる任意の線をレンダリングする

このガイドの [SkiaSharp 曲線とパス] セクションでは、特定の種類の曲線をレンダリングするために SKPath が定義するさまざまな方法を確認できます。 ただし、SKPath で直接サポートされていない種類の曲線を引くことが必要な場合があります。 このような場合は、ポリライン (接続された線のコレクション) を使用して、数学的に定義できる任意の曲線を描画できます。 線を十分に小さく、十分に多くすると、結果は曲線のように見えます。 このスパイラルは、実際には 3,600 の小さな線です。

スパイラル

一般に、一対のパラメトリック方程式の観点から曲線を定義することをお勧めします。 これらは、3 番目の変数に依存する X 座標と Y 座標の方程式であり、時間の t とも呼ばれることもあります。 例えば、次のパラメトリック方程式は、t が 0 から 1 まで、点 (0, 0) を中心とする半径1の円を定義します。

x = cos(2πt)

y = sin(2πt)

半径が 1 より大きい場合は、サイン値とコサイン値をその半径で乗算するだけでよく、中心を別の場所に移動する必要がある場合は、次の値を追加します。

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

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

横軸と垂直軸が平行な楕円の場合、次の 2 つの半径が関係します。

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

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

その後、さまざまなポイントを計算してパスに追加するループに、同等の SkiaSharp コードを配置できます。 次の SkiaSharp コードは、ディスプレイ面を塗りつぶす楕円の SKPath オブジェクトを作成します。 ループは 360 度を直接循環します。 中心はディスプレイ面の幅と高さの半分であり、2 つの半径も同じになります。

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

これにより、楕円が 360 の小さな線で定義されます。 レンダリングされると、スムーズに表示されます。

もちろん、ポリラインを使用して楕円を作成する必要はありません。SKPath に含まれる AddOval メソッドがその作業を行います。 ただし、SKPath により提供されないビジュアル オブジェクトを描画することもできます。

[螺線] ページには、楕円コードに似ているが、重要な違いがあるコードがあります。 それは 360 度の円を 10 回ループし、半径を継続的に調整します。

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

各ループ間のオフセットが一定であるため、結果は算術スパイラルとも呼ばれます。

[アルキメデスらせん] ページのトリプル スクリーンショット

SKPathusing ブロックに作成されていることに注意してください。 この SKPath は、前のプログラムの SKPath オブジェクトよりも多くのメモリを消費しています。これは、管理されていないリソースを破棄するにはusing ブロックがより適切であることを示唆しています。