Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »

Как нарисовать кривую Безье чтобы она проходила точно через точки


Кто б сомневался ©   (15.06.18 15:39

Как нарисовать кривую Безье из 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]

https://stackoverflow.com/questions/7054272/how-to-draw-smooth-curve-through-n-points-using-javascript-html5-canvas


версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо