代码之家  ›  专栏  ›  技术社区  ›  CMPXCHG8B

将单个贝塞尔曲线拟合到3D中的4个点

  •  0
  • CMPXCHG8B  · 技术社区  · 6 年前

    有没有一种简单的曲线拟合方法,一个贝塞尔曲线的单段4点在三维?

    下面是我要做的一个例子:

    bezier_1

    下面是为该段生成的Bezier句柄的另一张图片:

    bezier_2

    在本例中,我尝试用手将贝塞尔曲线对齐,以便它与4个给定点相交,并得到尽可能短的曲线。理想情况下,我想以某种方式进行编程-我在网上发现了一些算法可以做到这一点,但大多数算法似乎是用于创建具有任意数量段的曲线…而我只需要把一个段(两个点,两个控制点)尽可能地拟合到三维的四个点上。

    最好的方法是什么?

    1 回复  |  直到 6 年前
        1
  •  0
  •   MBo    6 年前

    使 单一的 贝塞尔曲线通过需要的点,你应该知道参数 t 对于这些点。

    似乎您没有关于曲线的附加信息,所以第一个附加值可以是priopi assign参数 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;