2013-03-24 14 views
12

Udało mi się wprowadzić kwadratowe i sześcienne krzywe Beziera. Są dość proste, ponieważ mamy formułę. Teraz chcę reprezentować n-tego rzędu krzywej Beziera stosując uogólnienia:n-ty porządek Krzywe Beziera?

enter image description here

Gdzie

enter image description here

i

enter image description here

używam biblioteka bitmap do renderowania danych wyjściowych, więc oto mój kod:

// binomialCoef(n, k) = (factorial(n)/(factorial(k) * factorial(n- k))) 
unsigned int binomialCoef(unsigned int n, const unsigned int k) 
{ 
    unsigned int r = 1; 

    if(k > n) 
     return 0; 

    for(unsigned int d = 1; d <= k; d++) 
    { 
     r *= n--; 
     r /= d; 
    } 

    return r; 
} 

void nBezierCurve(Bitmap* obj, const Point* p, const unsigned int nbPoint, float steps, const unsigned char red, const unsigned char green, const unsigned char blue) 
{ 
    int bx1 = p[0].x; 
    int by1 = p[0].y; 
    int bx2; 
    int by2; 

    steps = 1/steps; 

    for(float i = 0; i < 1; i += steps) 
    { 
     bx2 = by2 = 0; 
     for(int j = 0; (unsigned int)j < nbPoint; j++) 
     { 
      bx2 += (int)(binomialCoef(nbPoint, j) * pow(1 - i, (float)nbPoint - j) * pow(i, j) * p[j].x); 
      by2 += (int)(binomialCoef(nbPoint, j) * pow(1 - i, (float)nbPoint - j) * pow(i, j) * p[j].y); 
     } 

     bresenhamLine(obj, bx1, by1, bx2, by2, red, green, blue); 

     bx1 = bx2; 
     by1 = by2; 
    } 

    // curve must end on the last anchor point 
    bresenhamLine(obj, bx1, by1, p[nbPoint - 1].x, p[nbPoint - 1].y, red, green, blue); 
} 

Oto zbiór punktów do renderowania:

Point ncurv[] = { 
        20, 200, 
        70, 300, 
        200, 400, 
        250, 200 
       }; 

i tu jest wyjście:

enter image description here

Czerwona krzywa jest Baziera. Niebieski ma być czwartym rzędem Beziera, który jest taki sam jak sześcienny Bezier, ale w tym przypadku nie są one takie same?!

EDIT: Zapomniałem zaznaczyć, że na dole po lewej jest punkt (0, 0)

+1

Wygląda jakbyś utraty dokładności ze względu na małe wartości zmiennoprzecinkowych. –

Odpowiedz

4

Suma w formule ...

enter image description here

... biegnie od 0 do n, czyli dla n-tego rzędu bezier trzeba n + 1 punktów.

Masz 4 punkty, więc rysujesz beziera trzeciego rzędu.

Błąd w kodzie jest tutaj:

for(int j = 0; (unsigned int)j < nbPoint; j++) 

powinno być:

for(int j = 0; (unsigned int)j <= nbPoint; j++) 

inaczej jesteś iteracji tylko od 0 do n-1.

3rd-order bezier

EDIT:

Z odsetek, kształt ty otrzymujesz jest taka sama jak wtedy, gdy brakuje (5) punkt był w punkcie (0,0), ponieważ jest to jedyny punkt, który będzie przyczynić się nic do sumy ...

4th-order bezier with 5th point at origin

+0

, ale gdy 'j' osiągnie' nbPoint', 'p [j]' przekracza limity tablicy punktów? – Jonas

+0

Tak - musisz dodać piąty punkt, aby stworzyć beziera 4-go rzędu. Więc p musi mieć rozmiar nbPoint + 1. –

+0

Tak, teraz rozumiem. Dziękuję Ci. – Jonas

2

Próbujesz zbudować 4-ci rzędu krzywej Beziera na zaledwie cztery punkty. Nic dziwnego, że to nie działa.

+3

Jak to jest odpowiedź? –

+1

To nie daje odpowiedzi na pytanie.Aby skrytykować lub poprosić o wyjaśnienie od autora, zostaw komentarz pod swoim postem. - [Z recenzji] (https://stackoverflow.com/review/low-quality-posts/16357822) –

+0

@DonaldDuck: To odpowiedź na pytanie zwięźle i poprawnie. Odpowiedź Richarda Inglisa jest lepsza, z tymi wszystkimi ładnymi zdjęciami i wszystkim, ale jeśli przeczytasz pierwsze zdanie tej odpowiedzi, zobaczysz, że jest w zasadzie taki sam jak mój. – TonyK

Powiązane problemy