gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 07:45:14 27 4
gpt4 key购买 nike

给定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),如何让其余两个控制点靠近原始点?

最佳答案

您可能想看看 this page

这是一个非常好的实现,尽管正如作者所写:“这种方法是纯粹的启发式和经验式的。从严格的数学建模的角度来看,它可能会给出错误的结果。但在实践中,结果已经足够好了,而且它需要绝对最少的计算。”

它是用 C++ 编写的,但确实很容易移植到任何语言...通过控制点计算函数传递你的每一个“边缘”,然后通过贝塞尔计算函数,你就拥有了它。要在多边形上执行贝塞尔平滑,请使用最后一个点和第一个点传递最后一条边。

Bezier smooth

关于c# - 如何获得最接近给定点的三次贝塞尔曲线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7729058/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com