Programmation C/Courbe de Bézier
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 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.
#include <GL/glu.h>
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);
}