Конференция "Прочее" » Как нарисовать кривую Безье чтобы она проходила точно через точки
 
  • Кто б сомневался © (15.06.18 15:39) [0]
    Как нарисовать кривую Безье из 3 точек, чтобы она проходила точно через точки.
    К примеру рисуем параболу вверх, соответственно пиковая точка на кривой Безье будет ниже нужной нам точки. Как сделать чтобы пиковая точка проходила через нужную координату? Как ее рассчитать?
    Спасибо
  • Кто б сомневался © (15.06.18 15:40) [1]
    Вопрос именно про то как ее рассчитать крайнюю точку.
    Нарисовать ее в FMX просто - CurveTo.
  • Кто б сомневался © (15.06.18 15:43) [2]
    Вот здесь показана проблема в секции "Рисование «де Кастельжо»":
    https://learn.javascript.ru/bezier  
    Указываются 3 координаты, но линия не проходит через пиковую точку.
  • Плохиш © (15.06.18 16:11) [3]
    Я правильно понимаю, что, по приведённой ссылке, до раздела "Как провести кривую Безье через нужные точки?" ты не дочитал?
  • Кто б сомневался © (15.06.18 16:28) [4]
    Дочитал, проблема вот в чем:

    https://upload.wikimedia.org/wikipedia/commons/3/3d/B%C3%A9zier_2_big.gif

    На картинке указаны 3 точки для построения кривой Безье, p0, p1, p2.
    Итого получаем кривую Безье.
    Вопрос, как сделать так, чтобы линия проходила точно через точку P1?
  • Кто б сомневался © (15.06.18 16:29) [5]
    Точнее дочитал, но так и не понял как сделать интерполяцию.
  • Кто б сомневался © (15.06.18 16:38) [6]
    Я сейчас пытаюсь разобраться с этим, так все сложно. Интерполяция, полиномы третьей степени,  кубический сплайн дефекта 1.
    Поэтому задал вопрос здесь, может кто готовую формулу приведет.
  • Dimka Maslov © (15.06.18 17:00) [7]
    Может помочь - функция аппроксимации кривой Безье 3-го порядка ломаной линией:

    procedure TPolygon.AddBezier(X0, Y0, X1, Y1, X2, Y2, X3, Y3: Double;
     N: Integer);
    var
    X, Y, T, DT: Double;
    i: Integer;
    begin
    DT := 1 / N;
    T := DT;
    for i := 1 to N do begin
     X := (1-T)*(1-T)*(1-T)*X0 +
      3*T*(1-T)*(1-T)*X1 +
      3*T*T*(1-T)*X2 +
      T*T*T*X3;
     Y := (1-T)*(1-T)*(1-T)*Y0 +
      3*T*(1-T)*(1-T)*Y1 +
      3*T*T*(1-T)*Y2 +
      T*T*T*Y3;
     AddVertex(X, Y);
     T := T + DT;
    end;
    end;
  • Кто б сомневался © (15.06.18 17:07) [8]
    Спасибо, попробую. Но наверное аппроксимация это все равно далеко от реальных точек.
    Скорее всего получиться что то вроде этого
    https://habrastorage.org/files/97d/266/683/97d266683e3645f4a8810dab675c930c.png
  • Кто б сомневался © (15.06.18 17:09) [9]
    [8]
    Видимо пнг был прозрачный, и сливает с черным фоном.
    https://habr.com/post/247235/#comment_8879240
  • dmk © (16.06.18 04:02) [10]
    Она не должна через управляющие проходить вроде. Это уже не Безье получается.
    А формулы вот:

    type
     TFloatPoint = record
       X, Y: double;
     end;

    //Прямая Безье
    //P = ((1-t) * A) + (t * B)
    function LinearBezier(P0, P1: TPoint; t: double): TFloatPoint;
    begin
     Result.X := ((1 - t) * P0.X) + (t * P1.X);
     Result.Y := ((1 - t) * P0.Y) + (t * P1.Y);
    end;

    //Квадратичная Безье
    //P = (1-t)^2P0 + 2t(1-t)P1 + t^2P2

    function QuadraticBezier(P0, P1, P2: TPoint; t: Double): TFloatPoint;
    begin
     Result.X := (((1 - t) * (1 - t)) * P0.X) + ((2 * t) * (1 - t) * P1.X) + ((t * t) * P2.X);
     Result.Y := (((1 - t) * (1 - t)) * P0.Y) + ((2 * t) * (1 - t) * P1.Y) + ((t * t) * P2.Y);
    end;

    //Кубическая Безье
    //P = (1-t)^3P0 + 3t(1-t)^2P1 + 3t^2(1-t)P2 + P3t^3 ,
    //где t = [0..1]
    function QubicBezier(P0, P1, P2, P3: TPoint; t: double): TFloatPoint;
    begin
     Result.X := ((1.0 - t) * (1.0 - t) * (1.0 - t) * P0.X) + (t * 3.0 * (1.0 - t) * (1.0 - t) * P1.X) + (3.0 * (t * t) * (1.0 - t) * P2.X) + (t * t * t) * P3.X;
     Result.Y := ((1.0 - t) * (1.0 - t) * (1.0 - t) * P0.Y) + (t * 3.0 * (1.0 - t) * (1.0 - t) * P1.Y) + (3.0 * (t * t) * (1.0 - t) * P2.Y) + (t * t * t) * P3.Y;
    end;
  • Pavia © (16.06.18 09:19) [11]
    Составляем уравнение решаем уравнение: К примеру как тут:
    https://s33.postimg.cc/b3hup433j/GIF.gif

    https://yadi.sk/d/eQQwrk4t3XxGpQ
  • Кто б сомневался © (17.06.18 12:43) [12]
    Итак, вот ребята что получилось:


    >   smoothness := 30;
    >   path.moveTo(TPointF.Create(point[0].x, point[0].y));
    >   dl := 0;
    >   t := 0.33;
    >   for I := 1 to Length(point) - 2 do
    >   begin
    >     dr := (point[i+2].y - point[i].y) / 2 * t;
    >
    >     p1 := TPointF.Create(point[i].x + t * smoothness, point[i].
    > y+dl);
    >     P2 := TPointF.Create(point[i+1].x - t* smoothness,  
    > point[i+1].y - dr);
    >     P3 := TPointF.Create(point[i+1].x, point[i+1].y);
    >     path.CurveTo(p1, p2, p3);
    >     dl := dr;
    >   end;


    В FMX рисуем Path в векторе, затем выводим на канву.
  • Кто б сомневался © (17.06.18 12:43) [13]
     smoothness := 30;
     path.moveTo(TPointF.Create(point[0].x, point[0].y));
     dl := 0;
     t := 0.33;
     for I := 1 to Length(point) - 2 do
     begin
       dr := (point[i+2].y - point[i].y) / 2 * t;

       p1 := TPointF.Create(point[i].x + t * smoothness, point[i].y+dl);
       P2 := TPointF.Create(point[i+1].x - t* smoothness,  point[i+1].y - dr);
       P3 := TPointF.Create(point[i+1].x, point[i+1].y);
       path.CurveTo(p1, p2, p3);
       dl := dr;
     end;
  • Кто б сомневался © (17.06.18 12:46) [14]
    Всем спасибо за помощь!
  • Кто б сомневался © (18.06.18 23:12) [15]
    Вот этот код дает отличные результаты без петель.
    Проверял на Delphi FMX (vector Path) все отлично (используйте Path.QuadCurveTo):

    move to the first point
      ctx.moveTo(points[0].x, points[0].y);

      for (i = 1; i < points.length - 2; i ++)
      {
         var xc = (points[i].x + points[i + 1].x) / 2;
         var yc = (points[i].y + points[i + 1].y) / 2;
         ctx.quadraticCurveTo(points[i].x, points[i].y, xc, yc);
      }
    // curve through the last two points
    ctx.quadraticCurveTo(points[i].x, points[i].y, points[i+1].x,points[i+1].y);
  • Кто б сомневался © (18.06.18 23:19) [16]

    > без петель


    Точнее без безье пиков (визуально - "скобок") на каждой точке, при любых разрешениях канваса.
  • Кто б сомневался © (18.06.18 23:20) [17]
 
Конференция "Прочее" » Как нарисовать кривую Безье чтобы она проходила точно через точки
Есть новые Нет новых   [134427   +34][b:0][p:0.001]