Ligne polygonale à lisser
Courbes B-Spline par morceaux de types NRUBS et Catmull-Rom
Courbe de Bezier
Trois courbes superposées
Fichier source : BSplineEtBezier.cpp
/* Calcul la position d'un point sur une courbe */
/* B-Spline controlee par quatre sommets */
/* g : le tableau des 4 sommets de controle */
/* t : la valeur de calcul du point */
/* t a prendre dans l'intervalle [0.0,1.0] */
/* mb : la matrice de base */
/* p : le point resultat */
static void determinationPositionSurBSpline(Pos3D **g,double t,double mb[4][4],Pos3D *p) {
double vt[4] = { t*t*t,t*t,t,1.0 };
double vtmb[4] = { 0.0,0.0,0.0,0.0 };
for ( int j = 0 ; j < 4 ; j++ ) {
for ( int k = 0 ; k < 4 ; k++ )
vtmb[j] += vt[k] * mb[k][j] ; }
p->x = p->y = p->z = 0.0;
for ( int j = 0 ; j < 4 ; j++ ) {
p->x += vtmb[j] * g[j]->x ;
p->y += vtmb[j] * g[j]->y ;
p->z += vtmb[j] * g[j]->z ; }
}
/* Calcul les points definissant une courbe */
/* B-Spline par morceaux definie par un ensemble */
/* de sommets de controle */
/* tPos : le tableau des sommets de controle */
/* n : le nombre de sommets de contrôle */
/* mb : la matrice de base */
/* nb : le nombre de points a calculer */
/* tRes : le tableau de points resultat */
static void calculBSpline(Pos3D **tPos,int n,double mb[4][4],int nb,Pos3D **tRes) {
for ( int i = 0 ; i < nb ; i++ ) {
double pos = i/(nb-1.0)*(n-3);
int nb =(int) pos;
if ( nb == n-3 )
nb = n-4;
double t = pos-nb;
determinationPositionSurBSpline(&tPos[nb],t,mb,tRes[i]); }
}
/* Calcul de v a la puissance p */
float power(double v,int p) {
return((float) (( v || p ) ? pow(v,(double) p) : 1.0));
}
/* Calcul les points definissant une courbe */
/* de Bezier definie par un ensemble */
/* de sommets de controle */
/* tPos : le tableau des sommets de controle */
/* n : le nombre de sommets de contrôle */
/* nb : le nombre de points a calculer */
/* tRes : le tableau de points resultat */
static void calculBezier(Pos3D **tPos,int n,int nb,Pos3D **tRes) {
float t,mt;
long long *cn;
float x,y,z,fac;
cn =(long long *) calloc(n,sizeof(long long));
cn[0] = 1;
cn[1] = n-1;
for ( int i = 2 ; i < n ; i++ )
cn[i] = (cn[i-1]*(n-i))/i;
for ( int i = 0 ; i < nb ; i++ ) {
t =(float) i/(nb-1);
mt = 1.0F-t;
x = y = z = 0.0F;
for ( int j = 0 ; j < n ; j++ ) {
fac = cn[j]*power(t,j)*power(mt,n-1-j);
x += fac * tPos[j]->x;
y += fac * tPos[j]->y;
z += fac * tPos[j]->z; }
tRes[i]->x = x;
tRes[i]->y = y;
tRes[i]->z = z; }
free(cn);
}