|
Алгоритм можно легко понять по исходнику для функции рисования кривой Безье по 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);
}
|