我一直在寻找,但显然没有找到一种算法,它允许我插入已知沿曲线的x,y坐标列表,以便获得立方体的4个控制点bezier曲线吐出来。
更准确地说,我正在寻找一种算法,该算法将为我提供形成曲线所需的两个控制点,同时输入一系列离散点,包括确定曲线起点和终点的两个控制点。
谢谢!
编辑:好的,由于数学,一个老敌人,我需要要求最适合多项式函数的贝塞尔曲线。
答案 0 :(得分:9)
所以我假设端点是固定的,然后你有许多(x,y)采样点,你想要用立方贝塞尔曲线。
您拥有的样本点数量将决定采取何种方法。让我们看看几个案例:
2分
2个样本点是最简单的情况。如果计算终点,那么总共可以得到4分。这是立方贝塞尔曲线中的CV数。要解决此问题,您需要两个采样点的参数(t)值。然后你有一个2个方程和2个点需要求解的系统,其中方程是你选择的t值的贝塞尔曲线的参数方程。
t值可以是您喜欢的任何值,但是通过使用1/3和2/3,或者查看相对距离或沿基线的相对距离,您将获得更好的结果,具体取决于您的数据。
1分
这类似于2分,但您没有足够的信息来唯一确定您的所有自由度。我建议的是拟合二次Bezier,然后提升度。我在this question中写了一个二次拟合的详细例子。
超过2分
在这种情况下,没有独特的解决方案。我使用了最小二乘近似,结果很好。步骤是:
在这个free cagd textbook第11章中对这些步骤有了很好的描述。它讨论了拟合b样条,但是一个三次贝塞尔曲线是一种b样条(结矢量是0,0,0) ,1,1,1并且有4分)。
答案 1 :(得分:6)
假设你有一条曲线y = f(x)
要定义贝塞尔曲线,您需要4个点,例如: P1x,P1y,P2x,P2y,P3x,P3y和P4x和P4y
P1和P4你是曲线的起点/终点。 P2和P3是控制点。
您已经知道曲线的起点和终点在哪里。你必须计算P2和P3。 x坐标P2x和P3x很简单,因为你只需选择曲线的t
就可以选择它们,例如1/3和2/3。所以你有P2x和P3x
然后,您最终得到一个由两个方程和两个未知数(P2y和P3y)组成的系统。
在完成一些数学运算后,你最终会得到类似的东西:
(我的f(x)是一个三次多项式,它也保证了我能够准确地拟合一条三次贝塞尔曲线。)
/**
@params {Object} firstPoint = {x:...,y...}
@params {Object} lastPoint = {x:...,y...}
@params {Object} cubicPoly Definition of a cubic polynomial in the form y=ax^3+bx^2+c.
Has a method EvaluateAt, which calculates y for a particular x
*/
var CalcBezierControlPoints = function(firstPoint, lastPoint, cubicPoly) {
var xDiff = lastPoint.X - firstPoint.X;
var x1 = firstPoint.X + xDiff / 3.0;
var x2 = firstPoint.X + 2.0 * xDiff / 3.0;
var y1 = cubicPoly.EvaluateAt(x1);
var y2 = cubicPoly.EvaluateAt(x2);
var f1 = 0.296296296296296296296; // (1-1/3)^3
var f2 = 0.037037037037037037037; // (1-2/3)^3
var f3 = 0.296296296296296296296; // (2/3)^3
var b1 = y1 - firstPoint.Y * f1 - lastPoint.Y / 27.0;
var b2 = y2 - firstPoint.Y * f2 - f3 * lastPoint.Y;
var c1 = (-2 * b1 + b2) / -0.666666666666666666;
var c2 = (b2 - 0.2222222222222 * c1) / 0.44444444444444444;
var p2 = {};
var p3 = {};
p2.X = x1;
p2.Y = c1;
p3.X = x2;
p3.Y = c2;
return ([p2, p3]);
}