7

下面是安卓代码。

path.moveTo(xx, yy);
for (...) {
    path.lineTo(xx, yy);
}
canvas.drawPath(this.path, paint);

在此处输入图像描述

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

final CornerPathEffect cornerPathEffect = new CornerPathEffect(50);
paint.setPathEffect(cornerPathEffect);

在此处输入图像描述

当谈到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);

我得到以下效果。

在此处输入图像描述

请注意,我避免使用PolyQuadraticBezierSegmentor PolyBezierSegment。它往往变得不稳定。这意味着,每当我向折线图添加新的输入点时,新添加的点往往会改变已在屏幕上绘制的旧路径。作为最终效果,您可能会观察到整个折线图在晃动

我可以知道在 WPF 中,我怎样才能平滑线段?虽然我用过lineSegment.IsSmoothJoin = true;,但我仍然可以看到尖角。我可以拥有与 Android 的 CornerPathEffect 等效的东西吗?

4

1 回答 1

0

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


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

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

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

关于我能想到的唯一其他选择是尝试根据您之前的数据预测几个点,即使输入相当规律也可能很困难。我用它来合成曲线末端的 Bezier 控制点——我正在计算所有点的 CP,并且需要一些东西用于端点——并且有一些有趣的时间试图阻止最终曲线段看起来严重变形.

哦,还有一个……不要画出最终的曲线段。如果您在 P n-1处终止曲线,则曲线应保持稳定。如果您必须展示它,请以不同的样式绘制最后一段。由于 CR 样条只需要来自插值的 +/- 2 个已知点,因此段 P n-2 -P n-1应该足够稳定。

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

于 2015-12-05T23:30:42.037 回答