SkiaSharp ArcTo 方法不绘制曲线
SkiaSharp ArcTo Method does not draw curve
我正在尝试使用以下代码在 SkiaSharp canvas 视图上绘制弧线。
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>
您的 x
半径为零,因此 ArcTo
在从当前点到出口点的路径中添加一条线。
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.
你可以这样做:
path3.ArcTo(new SKPoint(100, 100), 0, SKPathArcSize.Large, SKPathDirection.Clockwise, new SKPoint(w / 2, h));
但是我不知道你的绘图意图是什么; concave, convex, bounded, unbounded, 等等...但是其他一些使用 ConicTo
的例子可能更接近我认为你的意图:
path3.ConicTo(w / 3, h / 2, w / 2, h, 0.50f);
path3.ConicTo(0, h - (h / 5), w / 2, h, 0.50f);
您可能想查看官方文档以了解 ArcTo
如何解析为圆弧、二次曲线和移动:
根据@SushiHangover
的回复,我正在使用 ConicTo
进行以下操作
参考文献:
- Three Types of Bézier Curves - developer.xamarin
- Three Ways to Draw an Arc - developer.xamarin
- Experimental 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);
}
我正在尝试使用以下代码在 SkiaSharp canvas 视图上绘制弧线。
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>
您的 x
半径为零,因此 ArcTo
在从当前点到出口点的路径中添加一条线。
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.
你可以这样做:
path3.ArcTo(new SKPoint(100, 100), 0, SKPathArcSize.Large, SKPathDirection.Clockwise, new SKPoint(w / 2, h));
但是我不知道你的绘图意图是什么; concave, convex, bounded, unbounded, 等等...但是其他一些使用 ConicTo
的例子可能更接近我认为你的意图:
path3.ConicTo(w / 3, h / 2, w / 2, h, 0.50f);
path3.ConicTo(0, h - (h / 5), w / 2, h, 0.50f);
您可能想查看官方文档以了解 ArcTo
如何解析为圆弧、二次曲线和移动:
根据@SushiHangover
的回复,我正在使用ConicTo
进行以下操作
参考文献:
- Three Types of Bézier Curves - developer.xamarin
- Three Ways to Draw an Arc - developer.xamarin
- Experimental 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);
}