折线和参数等式
使用 SkiaSharp 呈现可以使用参数方程定义的任何线条
在本指南的 SkiaSharp 曲线和路径部分中,你将看到 SKPath
为呈现某些类型的曲线而定义的各种方法。 但是,有时有必要绘制一种不受 SKPath
直接支持的曲线类型。 在这种情况下,可以使用折线(连接线的集合)绘制可以数学定义的任何曲线。 如果使线条足够小且足够多,则结果将看起来像一条曲线。 这个螺线实际上是 3,600 条小线:
通常,最好用一对参数方程定义曲线。 这些是依赖于第三个变量的 X 坐标和 Y 坐标的方程,有时称为时间的 t
。 例如,以下参数方程定义了一个圆圈,其半径为 1,以点 (0, 0) 为中心,t 为 0 到 1:
x = cos(2πt)
y = sin(2πt)
如果希望半径大于 1,只需将正弦值和余弦值乘以该半径;如果需要将中心移到另一个位置,请添加这些值:
x = xCenter + radius·cos(2πt)
y = yCenter + radius·sin(2πt)
对于轴线平行于水平线和垂直线的椭圆,涉及两个半径:
x = xCenter + xRadius·cos(2πt)
y = yCenter + yRadius·sin(2πt)
然后,可以将等效的 SkiaSharp 代码放入一个循环中,以计算各种点并将这些点添加到路径中。 以下 SkiaSharp 代码为填充显示图面的椭圆创建一个 SKPath
对象。 该循环直接循环 360 度。 中心是显示图面的宽度和高度的一半,两个半径也是如此:
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);
}
}
结果也称为算术螺线,因为每个循环之间的偏移量是常量:
请注意,SKPath
是在 using
块中创建的。 SKPath
消耗的内存比上一程序中的 SKPath
对象多,这表明 using
块更适合释放任何非托管资源。