将单个贝塞尔曲线拟合到 3D 中的 4 个点
Fitting a single bezier curve to 4 points in 3D
有没有一种简单的方法可以将贝塞尔曲线的单段曲线拟合到 3D 中的 4 个点?
这是我正在尝试做的一个例子:
这是该段生成的贝塞尔曲线图柄的另一张图片:
在这种情况下,我尝试手动排列贝塞尔曲线,使其与给定的 4 个点相交,并生成可能的最短曲线。理想情况下,我想以某种方式以编程方式执行此操作-我在网上找到了一些执行此操作的算法,但其中大多数似乎是用于创建具有任意数量段的曲线......而我只需要适合单段(两个点,两个控制点)到 3D 中的四个点尽可能接近。
解决这个问题的最佳方法是什么?
要使单贝塞尔曲线通过所需的点,您应该知道这些点的参数t
。
似乎您没有关于曲线的其他信息,因此作为第一次近似,您可以优先将参数 t=1/3
分配给第一个点,将参数 t=2/3
分配给第二个点,然后计算控制点贝塞尔曲线提供P(1/3) == InternalPoint1 and P(2/3) == InternalPoint2
如果第一个内部点靠近起点,这样的假设可能会导致奇怪的曲线形式,因此在一般情况下值得粗略地评估参数 - 例如,使用对之间的距离比 P0-P3, P0-P1, P2-P3
。
中的更多信息和图片
摘自我的 Delphi 函数和一些伪代码
procedure CalcBezierFromPoints(SrcPt: 4 source points
BezPt: 4 resulting control points
t1: Double = 1 / 3; t2: Double = 2 / 3);
var
tt1, tt2: Double;
Det, a11, a12, a21, a22, b1, b2: Double;
begin
//start and end points remains the same
BezPt[0] := SrcPt[0];
BezPt[3] := SrcPt[3];
//auxiliary values
tt1 := 1 - t1;
tt2 := 1 - t2;
//Solution of linear equation system
a11 := 3 * tt1 * tt1 * t1;
a12 := 3 * tt1 * t1 * t1;
a21 := 3 * tt2 * tt2 * t2;
a22 := 3 * tt2 * t2 * t2;
Det := a11 * a22 - a12 * a21;
b1 := SrcPt[1].X - SrcPt[0].X * tt1 * tt1 * tt1 - SrcPt[3].X * t1 * t1 * t1;
b2 := SrcPt[2].X - SrcPt[0].X * tt2 * tt2 * tt2 - SrcPt[3].X * t2 * t2 * t2;
BezPt[1].X := Round((b1 * a22 - b2 * a12) / Det);
BezPt[2].X := Round((-b1 * a21 + b2 * a11) / Det);
//the same for Y and Z components
end;
有没有一种简单的方法可以将贝塞尔曲线的单段曲线拟合到 3D 中的 4 个点?
这是我正在尝试做的一个例子:
这是该段生成的贝塞尔曲线图柄的另一张图片:
在这种情况下,我尝试手动排列贝塞尔曲线,使其与给定的 4 个点相交,并生成可能的最短曲线。理想情况下,我想以某种方式以编程方式执行此操作-我在网上找到了一些执行此操作的算法,但其中大多数似乎是用于创建具有任意数量段的曲线......而我只需要适合单段(两个点,两个控制点)到 3D 中的四个点尽可能接近。
解决这个问题的最佳方法是什么?
要使单贝塞尔曲线通过所需的点,您应该知道这些点的参数t
。
似乎您没有关于曲线的其他信息,因此作为第一次近似,您可以优先将参数 t=1/3
分配给第一个点,将参数 t=2/3
分配给第二个点,然后计算控制点贝塞尔曲线提供P(1/3) == InternalPoint1 and P(2/3) == InternalPoint2
如果第一个内部点靠近起点,这样的假设可能会导致奇怪的曲线形式,因此在一般情况下值得粗略地评估参数 - 例如,使用对之间的距离比 P0-P3, P0-P1, P2-P3
。
摘自我的 Delphi 函数和一些伪代码
procedure CalcBezierFromPoints(SrcPt: 4 source points
BezPt: 4 resulting control points
t1: Double = 1 / 3; t2: Double = 2 / 3);
var
tt1, tt2: Double;
Det, a11, a12, a21, a22, b1, b2: Double;
begin
//start and end points remains the same
BezPt[0] := SrcPt[0];
BezPt[3] := SrcPt[3];
//auxiliary values
tt1 := 1 - t1;
tt2 := 1 - t2;
//Solution of linear equation system
a11 := 3 * tt1 * tt1 * t1;
a12 := 3 * tt1 * t1 * t1;
a21 := 3 * tt2 * tt2 * t2;
a22 := 3 * tt2 * t2 * t2;
Det := a11 * a22 - a12 * a21;
b1 := SrcPt[1].X - SrcPt[0].X * tt1 * tt1 * tt1 - SrcPt[3].X * t1 * t1 * t1;
b2 := SrcPt[2].X - SrcPt[0].X * tt2 * tt2 * tt2 - SrcPt[3].X * t2 * t2 * t2;
BezPt[1].X := Round((b1 * a22 - b2 * a12) / Det);
BezPt[2].X := Round((-b1 * a21 + b2 * a11) / Det);
//the same for Y and Z components
end;