给予n分:
p0,p1,p2,…,pn;
如何获得点c1,c2,以便由
p0,c1,c2,pn
最接近给定的点?
我尝试了最小二乘法。在阅读http://www.mathworks.com/matlabcentral/fileexchange/15542-cubic- bezier-least-square- fitting的pdf文档后,我写了这篇文章。但是我找不到很好的t(i)函数。
using System; using System.Collections.Generic; using System.Linq; using System.Windows; namespace BezierFitting { class CubicBezierFittingCalculator { private List<Point> data; public CubicBezierFittingCalculator(List<Point> data) { this.data = data; } private double t(int i) { return (double)(i - 1) / (data.Count - 1); // double s = 0.0, d = 0.0; // // for (int j = 1; j < data.Count; j++) // { // if (j < i) // { // s += (data[j] - data[j - 1]).Length; // } // d += (data[j] - data[j - 1]).Length; // } // return s / d; } public void Calc(ref Point p1, ref Point p2) { double n = data.Count; Vector p0 = (Vector)data.First(); Vector p3 = (Vector)data.Last(); double a1 = 0.0, a2 = 0.0, a12 = 0.0; Vector c1 = new Vector(0.0, 0.0), c2 = new Vector(0.0, 0.0); for (int i = 1; i <= n; i++) { double ti = t(i), qi = 1 - ti; double ti2 = ti * ti, qi2 = qi * qi; double ti3 = ti * ti2, qi3 = qi * qi2; double ti4 = ti * ti3, qi4 = qi * qi3; a1 += ti2 * qi4; a2 += ti4 * qi2; a12 += ti3 * qi3; Vector pi = (Vector)data[i - 1]; Vector m = pi - qi3 * p0 - ti3 * p3; c1 += ti * qi2 * m; c2 += ti2 * qi * m; } a1 *= 9.0; a2 *= 9.0; a12 *= 9.0; c1 *= 3.0; c2 *= 3.0; double d = a1 * a2 - a12 * a12; p1 = (Point)((a2 * c1 - a12 * c2) / d); p2 = (Point)((a1 * c2 - a12 * c1) / d); } } }
使三次贝塞尔曲线最接近给定点的最佳方法是什么?
例如,这是30分:
22, 245 26, 240 39, 242 51, 231 127, 189 136, 185 140, 174 147, 171 163, 162 169, 155 179, 107 181, 147 189, 168 193, 187 196, 75 199, 76 200, 185 201, 68 204, 73 205, 68 208, 123 213, 118 216, 210 216, 211 218, 68 226, 65 227, 110 228, 102 229, 87 252, 247
这些点分布在由四个点控制的三次贝塞尔曲线周围:
P0(0,256),P1(512,0),P2(0,0),P3(256,256)。
假设曲线是从(0,256)到(256,256),如何使静止的两个控制点靠近原点?
如果要创建具有尖点的曲线,则问题非常棘手。我可以想到一种启发式方法来创建一组初始控制点。对于第一个控制点,当从距离到第一个锚点进行排序时,请尝试获取可用的点的前1/3。排序是必要的,否则,您可能会无所适从。取该点的1/3并进行线性最小二乘拟合,这具有线性时间复杂度。这为您提供了曲线起飞的方向。对最后1/3执行相同的操作,您将获得“着陆”方向。
使用那些线性解决方案来创建指向远离锚点的向量,然后尝试使这些向量变长和变短,以尽量减少误差。控制点将沿着来自锚点的向量。
这里还有其他一些想法(我只能发布两个链接!): 物理论坛问题 贝塞尔曲线拟合论文