我遇到了这个问题平滑手绘曲线 https://stackoverflow.com/questions/5525665/smoothing-a-hand-drawn-curve(这个问题实际上可能是一个骗局),它的答案建议使用 Ramer-Douglas-Peucker,然后根据菲利普·施奈德 (Philip J. Schneiders) 方法 http://iut-arles.univ-provence.fr/web/romain-raffin/sites/romain-raffin/IMG/pdf/PSchndeider_An_Algorithm_for_automatically_fitting_digitized_curves.pdf.
将提供的示例代码快速适应我的绘图方法会产生以下曲线:
问题的输入数据已减少到 28 个点(使用贝塞尔样条绘制)。
我不确定 Adobe 到底使用的是哪一种方法,但到目前为止,这种方法对我来说非常有用。
适应
So, Kris 提供的代码 https://stackoverflow.com/a/5530600/259953是为 WPF 编写的,并在这方面做出了一些假设。为了适应我的情况(并且因为我不想调整他的代码),我编写了以下代码片段:
private List<Point> OptimizeCurve( List<Point> curve ) {
const float tolerance = 1.5f;
const double error = 100.0;
// Remember the first point in the series.
Point startPoint = curve.First();
// Simplify the input curve.
List<Point> simplified = Douglas.DouglasPeuckerReduction( curve, tolerance ).ToList();
// Create a new curve from the simplified one.
List<System.Windows.Point> fitted = FitCurves.FitCurve( simplified.Select( p => new System.Windows.Point( p.X, p.Y ) ).ToArray(), error );
// Convert the points back to our desired type.
List<Point> fittedPoints = fitted.Select( p => new Point( (int)p.X, (int)p.Y ) ).ToList();
// Add back our first point.
fittedPoints.Insert( 0, startPoint );
return fittedPoints;
}
结果列表的格式为起点, 控制点1, 控制点2, 终点.