Метод SkiaSharp ArcTo не рисует кривую

Я пытаюсь нарисовать дугу на холсте SkiaSharp, используя следующий код.

path3.ArcTo(new SKPoint(0, h/2), 1.57f, SKPathArcSize.Large,
            SKPathDirection.Clockwise, new SKPoint(w/2, h));

Но вместо кривой он рисует прямую линию. Как сделать его кривым?

Полный код

 private void OnPainting(object sender, SKPaintSurfaceEventArgs e)
 {

     var surface = e.Surface;
     var canvas = surface.Canvas;
     canvas.Clear(SKColors.White);

        var w = e.Info.Width;
        var h = e.Info.Height;

        var pathStroke3 = new SKPaint
        {
            IsAntialias = true,
            Style = SKPaintStyle.StrokeAndFill,
            Color = new SKColor(240, 0, 100, 250),
            StrokeWidth = 5
        };

        var path3 = new SKPath { FillType = SKPathFillType.EvenOdd };
        path3.MoveTo(0, h/2);
        path3.ArcTo(new SKPoint(0, h/2), 1.57f, SKPathArcSize.Large, SKPathDirection.Clockwise, new SKPoint(w/2, h));
        path3.LineTo(0, h);
        path3.Close();
        canvas.DrawPath(path3, pathStroke3);


 }

XAML

 <Grid x:Name="controlGrid" ColumnSpacing="0" RowSpacing="0" Padding="0" BackgroundColor="White" >
    <Grid.RowDefinitions>
        <RowDefinition Height="4*" />
        <RowDefinition Height="6*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <views:SKCanvasView PaintSurface="OnPainting" EnableTouchEvents="True" 
     Touch="OnTouch" HeightRequest="300" Grid.Row="0"/>
 </Grid>

введите здесь описание изображения


person LCJ    schedule 26.07.2017    source источник


Ответы (2)


Ваш радиус x равен нулю, поэтому ArcTo добавляет линию к пути от текущей точки до точки выхода.

arcTo добавляет линию к xy, если либо радиусы равны нулю, либо если последняя точка пути равна (x, y). arcTo масштабирует радиусы r так, чтобы они соответствовали последней точке пути и xy, если они больше нуля, но слишком малы.

Вы можете сделать что-то вроде:

path3.ArcTo(new SKPoint(100, 100), 0, SKPathArcSize.Large, SKPathDirection.Clockwise, new SKPoint(w / 2, h));

введите здесь описание изображения

Но я не знаю, каково ваше намерение рисовать; вогнутый, выпуклый, ограниченный, неограниченный и т. д. ... но некоторые другие примеры с использованием ConicTo, которые могут быть ближе к тому, что, как я думаю, может быть вашим намерением:

path3.ConicTo(w / 3, h / 2, w / 2, h, 0.50f);

введите здесь описание изображения

path3.ConicTo(0, h - (h / 5), w / 2, h, 0.50f);

введите здесь описание изображения

Возможно, вы захотите посмотреть официальные документы, чтобы понять, как ArcTo превращается в дуги, коники и движения:

person SushiHangover    schedule 26.07.2017

Я использую ConicTo для следующего в соответствии с ответом от @SushiHangover

Рекомендации:

  1. Три типа кривых Безье — developer.xamarin
  2. Три способа рисования дуги — developer.xamarin
  3. Экспериментальный SkPath — skia.org

введите здесь описание изображения

Код

private void OnPainting(object sender, SKPaintSurfaceEventArgs e)
{

     var surface = e.Surface;
     var canvas = surface.Canvas;
     canvas.Clear(SKColors.White);

        var w = e.Info.Width;
        var h = e.Info.Height;
        var h12 = h - (h / 8);
        var h8 = h - (h / 6);
        var h4 = h - (h / 3);


        var pathStroke3 = new SKPaint
        {
            IsAntialias = true,
            Style = SKPaintStyle.StrokeAndFill,
            Color = new SKColor(240, 0, 100, 250),
            StrokeWidth = 5
        };

        var path3 = new SKPath { FillType = SKPathFillType.EvenOdd };
        path3.MoveTo(0, h4);
        path3.ConicTo(0, h8, w/2, h12, 0.50f);
        path3.LineTo(w/2, h);
        path3.LineTo(0, h);
        path3.Close();
        canvas.DrawPath(path3, pathStroke3);

        var pathStroke6 = new SKPaint
        {
            IsAntialias = true,
            Style = SKPaintStyle.StrokeAndFill,
            Color = new SKColor(100,0, 240,  250),
            StrokeWidth = 5
        };
        var path6 = new SKPath { FillType = SKPathFillType.EvenOdd };
        path6.MoveTo(w, h4);
        path6.ConicTo(w, h8, w / 2, h12, 0.50f);
        path6.LineTo(w / 2, h);
        path6.LineTo(w, h);
        path6.Close();
        canvas.DrawPath(path6, pathStroke6);


        var pathStroke4 = new SKPaint
        {
            IsAntialias = true,
            Style = SKPaintStyle.Stroke,
            Color = new SKColor(0, 0, 255),
            StrokeWidth = 5
        };

        var path4 = new SKPath { FillType = SKPathFillType.EvenOdd };
        path4.MoveTo(0, h4);
        path4.LineTo(w / 2, h4);
        canvas.DrawPath(path4, pathStroke4);


        var pathStroke5 = new SKPaint
        {
            IsAntialias = true,
            Style = SKPaintStyle.Stroke,
            Color = new SKColor(0, 255, 0),
            StrokeWidth = 5
        };
        var path5 = new SKPath { FillType = SKPathFillType.EvenOdd };
        path5.MoveTo(0, h8);
        path5.LineTo(w / 2, h8);
        canvas.DrawPath(path5, pathStroke5);

        var path7 = new SKPath { FillType = SKPathFillType.EvenOdd };
        path5.MoveTo(w/4, h8);
        path5.LineTo(w /4, h);
        canvas.DrawPath(path5, pathStroke5);

  }
person LCJ    schedule 26.07.2017