Courbes de bézier en C
Apparence
Ce code permet de tracer une courbe de Bézier définie par 4 points de contrôle. C'est donc une courbe cubique. Cet algorithme est une implémentation de l'algorithme de de Casteljau.
Pour adapter ce code C à votre système, il vous suffit de remplacer la procédure de tracé de segment (ici en OpenGL).
La structure Global_Bezier contient les 4 points de contrôle de la courbe de Bézier à tracer. level contient le nombre d'appel récursif.
typedef struct { float x, y; } point;
typedef struct { point P[4]; } Bezier;
/* Variables globales */ Bezier Global_Bezier; int level=1;
// Draw a line with color (r,v,b) void DrawLine(int x1, int y1, int x2, int y2,float r, float v, float b) { glColor3f(r,v,b); glBegin(GL_LINES); glVertex2i(x1,y1); glVertex2i(x2,y2); glEnd(); glFlush(); }
void DrawBezierBase(Bezier p,float r,float v,float b) { DrawLine(p.P[0].x,p.P[0].y,p.P[1].x,p.P[1].y,r,v,b); DrawLine(p.P[1].x,p.P[1].y,p.P[2].x,p.P[2].y,r,v,b); DrawLine(p.P[2].x,p.P[2].y,p.P[3].x,p.P[3].y,r,v,b); }
void DrawBezierRecursive (Bezier b, int level) { if (level <= 0) { /* draw a line segment */ DrawLine((int) (b.P[0].x + 0.5), (int) (b.P[0].y + 0.5), (int) (b.P[3].x + 0.5), (int) (b.P[3].y + 0.5),1,1,1); } else { Bezier left, right; /* subdivide into 2 Bezier segments */ left.P[0].x = b.P[0].x; left.P[0].y = b.P[0].y; left.P[1].x = (b.P[0].x + b.P[1].x) / 2; left.P[1].y = (b.P[0].y + b.P[1].y) / 2; left.P[2].x = (b.P[0].x + 2*b.P[1].x + b.P[2].x) / 4; left.P[2].y = (b.P[0].y + 2*b.P[1].y + b.P[2].y) / 4; left.P[3].x = (b.P[0].x + 3*b.P[1].x + 3*b.P[2].x + b.P[3].x) / 8; left.P[3].y = (b.P[0].y + 3*b.P[1].y + 3*b.P[2].y + b.P[3].y) / 8; DrawBezierBase(left,0,1,0); right.P[0].x = left.P[3].x; right.P[0].y = left.P[3].y; right.P[1].x = (b.P[1].x + 2*b.P[2].x + b.P[3].x) / 4; right.P[1].y = (b.P[1].y + 2*b.P[2].y + b.P[3].y) / 4; right.P[2].x = (b.P[2].x + b.P[3].x) / 2; right.P[2].y = (b.P[2].y + b.P[3].y) / 2; right.P[3].x = b.P[3].x; right.P[3].y = b.P[3].y; DrawBezierBase(right,0,0,1); /* draw the 2 segments recursively */ DrawBezierRecursive (left, level -1); DrawBezierRecursive (right, level -1); } }
void DrawBezier() { DrawBezierBase(Global_Bezier,1,0,0); DrawBezierRecursive(Global_Bezier,level); }