如何获得最接近给定点的三次贝塞尔曲线?

给予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执行相同的操作,您将获得“着陆”方向。

使用那些线性解决方案来创建指向远离锚点的向量,然后尝试使这些向量变长和变短,以尽量减少误差。控制点将沿着来自锚点的向量。

这里还有其他一些想法(我只能发布两个链接!):

物理论坛问题

贝塞尔曲线拟合论文

以上是 如何获得最接近给定点的三次贝塞尔曲线? 的全部内容, 来源链接: utcz.com/qa/409954.html

回到顶部