:: алгоритмы  и методы :: :: олимпиадные задачи :: :: связь :: :: о сайте ::
Путь: Графика » Рисование » Кривая Безье
  Рисование кривой Безье по 4 точкам



Алгоритм можно легко понять по исходнику для функции рисования кривой Безье по 4 точкам:
(вообще-то в приведенной функции две средние точки совмещены, так что получается дуга)
Функция готова к употреблению для C++ Builder
// Hарисовать кривую Безье

//R(t) = P0*(1-t)^3 + P1 * t * (1-t)^2 + P2 * t^2 * (1-t) + P3 * t^3 ,

//   где 0<=t<=1

//P0,P2 - опорные точки

//P1,P3 -  управляющие точки

void DrawBezier 
(TImage *Image,int x0,int y0,int x,int y,int x1,int y1,int Count)

{

TPoint points[900];  // Массив точек для полигона

Extended Step = 1.0/Extended(x1-x0) ;  // Шаг изменения параметра t

Count = 0 ;

for (int i=x0;i<x1&& i-x0<900;i++){

Extended t = Extended(i-x0)*Step ; // Очередное значение параметра t

// Собственно рассчет координат очередной точки для 2D

// Это считаются коэффициенты q1,q2,q3,q4  
		 
Extended q1 = t*t*t*-1 + t*t*3 + t*(-3) + 1;

Extended q2 = t*t*t*3 + t*t*(-6) + t*3;

Extended q3 = t*t*t*(-3) + t*t*3;

Extended q4 = t*t*t;

// Здесь подставляются координаты опорных точек
Extended qx = q1*x0 + q2*x + q3*x + q4*x1;  

// для q2 и q3 одинаковые x,y , это для совмещения двух средних точек
Extended qy = q1*y0 + q2*y + q3*y + q4*y1;  

points[i-x0].x = qx ;

points[i-x0].y = qy ;

// Живой подсчет количества точек в полигоне 
// (гурманы могут его вычислить до цикла)
Count++ ;  
   }

// Очистка площади для рисования

Image->Canvas->Brush->Color= clWhite ;

Image->Canvas->FillRect(Rect(0,0,Image->Width,Image->Height));

Image->Canvas->Brush->Color= clRed ;

Image->Canvas->Pen->Color= clBlack ;

// Замыкаем полигон

points[Count].x = points[0].x ;

points[Count].y = points[0].y ;
Polyline (Image->Canvas->Handle,points,Count+1);

// И ВОТ ОHА КРИВАЯ БЕЗЬЕ, красная такая, 
// а заодно и проверка попадания x,y в ее тело

HRGN Rgn ;

    // Создать регион из точек
if ((Rgn = CreatePolygonRgn (points,Count,WINDING))!=NULL) {

if (PtInRegion (Rgn,x,y)) AForm->Label->Caption= "Мышка в норке" ;

// Проверить попадание точки в регион

else AForm->Label->Caption= "" ;
PaintRgn (Image->Canvas->Handle,Rgn);   // Отобразить регион

DeleteObject (Rgn) ;  // Удалить регион

}

// Hарисовать две прямые из крайних точек в точку x,y для эффекта

Image->Canvas->Pen->Color= clGreen ;

Image->Canvas->MoveTo(x0,y0);

Image->Canvas->LineTo(x,y);

Image->Canvas->Pen->Color= clBlue ;

Image->Canvas->MoveTo(x1,y1);

Image->Canvas->LineTo(x,y);

}