Search code examples
xamarinxamarin.formsskiaskiasharp

SkiaSharp ArcTo Method does not draw curve


I am trying to draw an arc on a SkiaSharp canvas view using following code.

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

But instead of a curve, it is drawing a straight line. How to make it as a curve?

Complete Code

 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>

enter image description here


Solution

  • Your x radius is zero, thus ArcTo adds a line to the path from the current point to the exit point.

    arcTo appends Line to xy if either radii are zero, or if last Path Point equals (x, y). arcTo scales radii r to fit last Path Point and xy if both are greater than zero but too small.

    You can do something like:

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

    enter image description here

    But I do not know what your drawing intent is; concave, convex, bounded, unbounded, etc... but some other examples using ConicTo that might be closer to what I think your intent might be:

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

    enter image description here

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

    enter image description here

    You might want to look at the official docs to understand how ArcTo resolves into arcs, conics and moves: