如何平滑路径图的WPF线段

Che*_*eng 7 c# wpf android

以下是Android代码.

path.moveTo(xx, yy);
for (...) {
    path.lineTo(xx, yy);
}
canvas.drawPath(this.path, paint);
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

为了消除尖角,我正在使用

final CornerPathEffect cornerPathEffect = new CornerPathEffect(50);
paint.setPathEffect(cornerPathEffect);
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

来到WPF时,我使用以下代码.

PathFigure pathFigure = new PathFigure();
pathFigure.StartPoint = new Point(xx, yy);
for (...) {
    LineSegment lineSegment = new LineSegment(new Point(xx, yy), true);
    lineSegment.IsSmoothJoin = true;
    pathFigure.Segments.Add(lineSegment);
}
PathGeometry pathGeometry = new PathGeometry(new PathFigure[] { pathFigure });
drawingContext.DrawGeometry(null, new Pen(Brushes.White, 3), pathGeometry);
Run Code Online (Sandbox Code Playgroud)

我得到以下效果.

在此输入图像描述

请注意,我避免使用PolyQuadraticBezierSegmentPolyBezierSegment.它往往变得不稳定.这意味着,每当我向线图添加新的传入点时,新添加的点将倾向于更改已在屏幕上绘制的旧路径.作为最终效果,您可以观察整个线图是否在颤抖

我可以在WPF中知道如何消除线段吗?虽然我已经习惯了lineSegment.IsSmoothJoin = true;,但我仍然可以看到尖角.我可以拥有与Android的CornerPathEffect相同的东西吗?

Cor*_*rey 0

我知道,僵尸帖子。你可能已经解决了这个问题,但这是我多年后的想法......


由于平滑取决于线上的多个点,我认为很难找到一种看起来合理且不会在前沿产生一些不稳定的平滑算法。您或许可以减少不稳定性的范围,但只是冒着产生看起来非常奇怪的痕迹的风险。

第一个选择是使用限制投影伪影的样条算法。例如,Catmull-Rom 算法使用插值曲线段两侧的两个已知点。您可以在曲线的每一端合成两个附加点,或者简单地将第一个曲线段绘制为直线。这将给出一条直线作为最后一段,加上一条曲线作为倒数第二段,当添加另一个点时,曲线的变化应该很小(如果有的话)。

或者,您可以通过初始样条计算运行实际数据点以将这些点相乘,然后再次通过样条算法运行这些点。您仍然需要更新最新的2m点(其中m是第一遍的乘数),否则输出看起来会失真。

我能想到的唯一其他选择是尝试根据之前的数据预测未来的几个点,即使使用相当常规的输入,这也可能很困难。我用它来合成曲线末端的贝塞尔曲线控制点 - 我正在计算所有点的 CP,并且需要一些用于端点的东西 - 并且在尝试阻止最终曲线段看起来可怕变形方面经历了一些有趣的时间。

哦,还有一点……不要绘制最终曲线段。如果您将曲线终止于 P n-1,则曲线应保持稳定。如果必须显示最后一段,请以不同的风格绘制它。由于 CR 样条仅需要插值中的 +/- 2 个已知点,因此段 P n-2 -P n-1应该足够稳定。

如果您没有 CR 算法的代码,您可以使用合成贝塞尔控制点执行基本相同的操作。与其尝试描述该过程,不如查看这篇博客文章,它对该过程进行了相当详细的分解。 本文附有可能有用的代码。