Подгонка одной кривой Безье к 4 точкам в 3D - PullRequest
0 голосов
/ 15 января 2019

Существует ли простой способ подгонки кривой одного сегмента кривой Безье к 4 точкам в 3D?

Вот пример того, что я пытаюсь сделать:

bezier_1

А вот еще одна картина полученных ручек Безье для сегмента:

bezier_2

В этом случае я попытался выстроить Безье от руки так, чтобы он пересекался с 4 указанными точками и приводил к самой короткой из возможных кривых. В идеале, я бы хотел сделать это программным способом - я нашел несколько онлайн-алгоритмов, которые делают это, но большинство из них, похоже, предназначены для создания кривых с произвольным числом сегментов ... тогда как мне просто нужно подогнать от одного отрезка (две точки, две контрольные точки) до четырех точек в 3D как можно ближе.

Какой лучший способ сделать это?

1 Ответ

0 голосов
/ 16 января 2019

Чтобы сделать одну кривую Безье, проходящую через необходимые точки, вы должны знать параметры 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;
...