简体   繁体   中英

Fitting a single bezier curve to 4 points in 3D

Is there an easy method of curve-fitting a single segment of a bezier curve to 4 points in 3D?

Here's an example of what I'm trying to do:

bezier_1

And here's another picture of the resulting Bezier handles for the segment:

bezier_2

In this case, I've attempted to line up the bezier by hand so that it intersects with the 4 given points and results in the shortest curve possible. Ideally, I'd like to do this programmatically somehow- I've found a few algorithms online that do this, but most of them seem to be for creating curves with an arbitrary number of segments... whereas I just need to fit a single segment (two points, two control points) to four points in 3D as closely as possible.

What's the best way of going about this?

To make single Bezier curve passing through needed points, you should know parameters t for these points.

Seems you have no additional information about curve, so as first appriximation you can a priopi assign parameter t=1/3 to the first point and parameter t=2/3 to the second point, then calculate control points for Bezier curve to provide P(1/3) == InternalPoint1 and P(2/3) == InternalPoint2

If the first internal point lies close to start point, such assumption might cause weird curve form, so in general case it is worth to roughly evaluate parameters - for example, using distance ratio between pairs P0-P3, P0-P1, P2-P3 .

Some more info and picture in linked answer

Excerpt from my Delphi function with some pseudocode

  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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM