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);
我得到以下效果.
请注意,我避免使用PolyQuadraticBezierSegment或PolyBezierSegment.它往往变得不稳定.这意味着,每当我向线图添加新的传入点时,新添加的点将倾向于更改已在屏幕上绘制的旧路径.作为最终效果,您可以观察整个线图是否在颤抖
我可以在WPF中知道如何消除线段吗?虽然我使用了lineSegment.IsSmoothJoin = true;但我仍然可以看到尖角.我可以拥有与Android的CornerPathEffect相同的东西吗?
解决方法
由于平滑取决于线中的多个点,我认为很难找到看起来合理的平滑算法而不会在前沿产生一些不稳定性.您可以减少不稳定的范围,但只会产生非常奇怪的痕迹.
第一种选择是使用限制投影伪像的样条算法.例如,Catmull-Rom算法在被插值的曲线段的两侧使用两个已知点.您可以在曲线的每一端合成两个附加点,或者只是将第一个曲线段绘制为直线.这将给出一条直线作为最后一段,加上一条曲线作为倒数第二段,如果添加另一个点,它应该变化很小.
或者,您可以通过初始样条计算运行实际数据点以将这些点相乘,然后再次通过样条算法运行这些点.你仍然需要更新最近的2米点(其中m是第一遍的乘数)或者输出看起来是扭曲的.
关于我能想到的唯一其他选择是尝试根据您之前的数据预测未来几点,即使有相当规律的输入也很难.我用它来合成我的曲线末端的贝塞尔控制点 – 我正在计算所有点的CP并需要用于终点的东西 – 并且有一些有趣的时间试图阻止最终的曲线段看起来可怕的变形.
哦,还有一个…不要绘制最终曲线段的图表.如果在Pn-1处终止曲线,曲线应保持稳定.如果必须完全显示,则以不同的样式绘制最终片段.由于C-R样条仅需要来自插值的/ – 2个已知点,因此段Pn-2-Pn-1应足够稳定.
如果您没有C-R算法的代码,您可以使用合成Bezier控制点进行基本相同的操作.不要试图描述这个过程,而是查看this blog post,它给出了一个相当好的过程细分. This article附有可能有用的代码.