2014-04-28 3 views
0

Je génère une courbe B-spline de degré 3 avec 10 points de contrôle. Mon vecteur de noeud a 14 entrées allant de 0 à 1. Pour une raison quelconque, ma courbe commence toujours et se termine à l'origine. Il échoue également à dessiner une courbe si n'importe quel noeud est égal à un autre noeud.B-spline Courbe se terminant à l'origine?

Voici mon code pour la fonction de base:

if(p == 0) { 
    if((KN[i] <= u) && (u < KN[i+1])){ 
     return 1; 
    } 
    return 0; 
} 

else{ 
    u1 = (u - KN[i])/(KN[i+p]-KN[i]); 
    u2 = (KN[i+p+1]-u)/(KN[i+p+1]-KN[i+1]); 

    return u1*Basis(i,(p-1),u)+u2*Basis(i+1,p-1,u); 
} 

où i est le point courant (0 à 9), p est le degré, 3, et où u est dans mon domaine [0,1 ] nous sommes. Ma fonction de prise de courbe appelle cette fonction de base et ressemble à ceci:

void makeCurve (int n, int p){ 
    G_rgb(0,1,0); 

    double u, x, y; 
    int i; 

    for(u = 0; u <= 1; u += 0.0001){ 
     x = 0; 
     y = 0; 

     for(i = 0; i < n; i ++){ 
      x += Basis(i,p,u) * PX[i]; 
      y += Basis(i,p,u) * PY[i]; 
     } 

     G_point(x,y); 
    } 
} 

où n est le nombre de points, 10, et p est le degré 3.

Pour référence est le programme ici dans son entier:

double PX[20], PY[20], KN[11]; 

int factorial(int n) 
{ 
int res, i; 
    if(n <= 0){ 
     return 1 ; // safeguard 0 and -ve 
    } 

    res = n ; 

    for(i = n-1; i > 1; i --){ 
     res *= i; 
    } 

    return res; 
} 

double Basis(int i, int p, double u){ 
double u1, u2; 

if(p == 0) { 
    if((KN[i] <= u) && (u < KN[i+1])){ 
     return 1; 
    } 
    return 0; 
} 
else{ 
    u1 = (u - KN[i])/(KN[i+p]-KN[i]); 
    u2 = (KN[i+p+1]-u)/(KN[i+p+1]-KN[i+1]); 

    return u1*Basis(i,(p-1),u)+u2*Basis(i+1,p-1,u); 
} 
} 

void makeCurve (int n, int p){ 

G_rgb(0,1,0); 

double u, x, y; 
int i; 

for(u = 0; u <= 1; u += 0.0001){ 
    x = 0; 
    y = 0; 

    for(i = 0; i < n; i ++){ 
     x += Basis(i,p,u) * PX[i]; 
     y += Basis(i,p,u) * PY[i]; 
    } 

    G_point(x,y); 
} 
} 


void makeLines(int n){ 
    int i; 

    G_rgb(1,1,1); 

for(i = 0; i < n - 1; i ++){ 
    G_line(PX[i],PY[i],PX[i+1],PY[i+1]); 
} 
} 

void makeDots(int n){ 

int i; 

G_rgb(1,0,0); 

for(i = 0; i < n; i ++){ 
    G_fill_circle(PX[i],PY[i],5); 
} 

} 

void main(){ 

G_init_graphics(800,800); 
G_rgb(0,0,0); 
G_clear(); 

double p[2], u; 

int i, n, m; 
n = 0; 

for(i = 0; i < 10; i ++){ 

    G_wait_click(p); 

    PX[i] = p[0]; 
    PY[i] = p[1]; 

    G_rgb(1,0,0); 
    G_fill_circle(p[0],p[1],5); 

    if(i != 0){ 
     G_rgb(1,1,1); 
     G_line(p[0],p[1],PX[i-1],PY[i-1]); 
    } 
} 

// so n = 9 and p = 6 so m = 13 and there are 14 knots 
KN[0] = 0; 
KN[1] = 0.03; 
KN[2] = 0.1; 
KN[3] = 0.12; 
KN[4] = 0.14; 
KN[5] = 0.28; 
KN[6] = 0.42; 
KN[7] = 0.57; 
KN[8] = 0.71; 
KN[9] = 0.85; 
KN[10] = 0.9; 
KN[11] = 0.99; 
KN[12] = 0.999; 
KN[13] = 1; 

makeCurve(10, 3); 

while(1 == 1){ 
    if(G_wait_key() == 'q') { 
     break; 
    } 
} 
} 
+0

Bienvenue dans Stack Overflow. Veuillez lire la page [About] bientôt. Pour le code de formatage sur SO, n'utilisez pas d'onglets; cela conduit à une indentation excentrique. Utilisez uniquement des espaces, et il est recommandé de mettre en retrait 4 espaces par niveau (c'est à peu près ce qui se passe avec les onglets, de toute façon). J'ai essayé d'améliorer le code, mais il me resterait encore du travail à faire. –

Répondre

1

vous obtenez une division par zéro erreur dans Base() lorsque p = 0, mais KN [i + p] == KN [i], ce qui est pourquoi il ne fonctionne pas lorsque les nœuds sont égaux, et KN devrait contenir 14 éléments, pas 11.

Gcc et clang vous avertissent automatiquement que KN n'a pas la bonne taille, vous devriez donc envisager de mettre à jour votre compilateur.