问题
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:
And here's another picture of the resulting Bezier handles for the segment:
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?
回答1:
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;
来源:https://stackoverflow.com/questions/54198446/fitting-a-single-bezier-curve-to-4-points-in-3d