SkiaSharp ConicTo 方法不绘制曲线

Posted

技术标签:

【中文标题】SkiaSharp ConicTo 方法不绘制曲线【英文标题】:SkiaSharp ConicTo Method does not draw a curve 【发布时间】:2019-10-24 11:04:06 【问题描述】:

我是 SkiaSharp 画布的新手,想要实现如下所示的画布。

我尝试使用下面的代码来实现画布,但失败了。

SKSurface vSurface = args.Surface;
SKCanvas vCanvas = vSurface.Canvas;
vCanvas.Clear(SKColors.White);

var w = args.Info.Width;
var h = args.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 / 4);
path3.ConicTo(w / 3, h / 2, w, h, 1f);
path3.LineTo(0, h);
path3.Close();

vCanvas.DrawPath(path3, pathStroke3);

结果如下所示。

【问题讨论】:

【参考方案1】:

您的圆锥曲线规范存在一些问题需要修复。我尝试在下面解释它们的原因。

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

从下图中可以看出,你已经将圆锥曲线的控制点定义在一个非常不寻常的地方。

w / 3 第一个参数是你的圆锥曲线控制点的x坐标。由于您希望曲线顶部水平居中,因此应将宽度除以 2 而不是 3。

h / 2 第二个参数是你曲线的垂直控制点。您已定义曲线从 y 轴上的 h/4 开始,因此曲线的顶点需要高于此值。我在示例中使用了 h/6,但您可以尝试使用 h/8 甚至 0 或其他绝对值。

w 第三个参数是曲线的水平端点,在您的实现中是正确的。

h第四个参数应该和我们开始画曲线的地方一样。否则它不会是对称的,这就是为什么在你的情况下,终点在h(=屏幕的右下角)。让它h/4 和瞧,曲线现在在正确的点结束。

这将更接近您想要实现的目标:

path3.ConicTo(w / 2, h / 6, w, h/4, 1f);

即使现在曲线没问题,你仍然会遇到路径无法关闭的问题。您首先必须在屏幕的右下角和左下角画一条线,以便很好地填充整个区域。像这样的:

path3.LineTo(w, h);
path3.LineTo(0, h);

现在您已经准备好填充路径,并且应该与您发布的示例图片相似。


编辑:如果你想修改曲线的强度,你可以做几件事。例如,您可以在屏幕下方开始曲线,它会立即变得更加曲线:

path3.MoveTo(0, h / 3);
path3.ConicTo(w / 2, h / 6, w, h / 3, 1f);

在这里,我将 MoveTo 方法的 y 坐标编辑到屏幕下方,以及将 ConicTo 方法的结束 y 坐标相同。您甚至可以同时使用h/2

您可以做的另一件事是使用 ConicTo 方法的最后一个参数。它定义了控制点的权重。值越高,曲线越接近它,从而产生具有高值的非常尖锐的曲线。试着调高或调低也可以改变曲线的强度。

最后,当前为 h/6 的参数标志着曲线的顶部。您可以尝试h/10 之类的方法,甚至可以尝试使用0 之类的绝对坐标来更改曲线。

【讨论】:

尝试使用您的代码并对其进行更改以获得准确的结果,但没有运气。这是我得到的输出 [link] (ibb.co/dWfyyY0) 嗯,问题出在哪里?看起来和中间没有圆圈的输入图像一模一样。 是的,它看起来确实像图像,但弯曲和曲线较少。如何调整代码以弯曲画布。 很好的解释。我需要更新文档来帮助解决这个问题。仅供参考:“请发送 PR 来帮助世界”github.com/mono/SkiaSharp-API-docs 是要更新的存储库! 谢谢@Matthew,这是个好主意。我在 Xamarin 文档项目中非常活跃,但在这种情况下,我绝对应该更新 SkiaSharp 文档。

以上是关于SkiaSharp ConicTo 方法不绘制曲线的主要内容,如果未能解决你的问题,请参考以下文章

SkiaSharp 不使用 StrokeAndFill 填充三角形

Xamarin.Forms - SkiaSharp 在后台线程中绘图

如何提高使用 SkiaSharp 绘制大多边形的性能?

C# SkiaSharp OpenTK Winform - 如何从后台线程中绘制?

在 WPF 中使用 SkiaSharp 模糊文本

有没有一种简单的方法来处理(转换)SkiaSharp 中的一组对象?