2013-03-24 13 views
12

Ich habe es geschafft, quadratische und kubische Bezier-Kurven zu implementieren. Sie sind ziemlich einfach, da wir eine Formel haben. Jetzt möchte ich ein n-ter Ordnung Bezier-Kurve darstellen mit der Verallgemeinerung:n-te Reihenfolge Bezier-Kurven?

enter image description here

Wo

enter image description here

und

enter image description here

Ich verwende ein Bitmap-Bibliothek, um die Ausgabe zu rendern, also hier ist mein Code:

// 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); 
} 

Hier ist der Satz von Punkten zu machen:

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

und hier ist die Ausgabe:

enter image description here

Die rote Kurve eine kubische Bezier ist. Der blaue soll der Bézier 4. Ordnung sein, der der kubischen Bézier entspricht, aber in diesem Fall sind sie nicht gleich?

EDIT: Ich habe vergessen zu beachten, dass die linke untere Punkt (0, 0)

+1

Sehen aus wie Sie Genauigkeit sind zu verlieren, weil der kleinen Gleitkommawerte. –

Antwort

4

Die Summe in der Formel ...

enter image description here

... läuft von 0 bis n, das heißt für eine n-ter Ordnung Bezier Sie n + 1 Punkte benötigen.

Sie haben 4 Punkte, also zeichnen Sie einen Bezier 3. Ordnung.

Der Fehler im Code ist hier:

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

es sein sollte:

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

sonst sind Sie nur von 0 bis n-1 iteriert.

3rd-order bezier

EDIT:

Aus Interesse, die Form, die Sie ist immer waren die gleichen, als ob die fehlende (5.) Punkt bei (0,0) war, denn das ist der einzige Punkt ist das würde nichts zu Ihrer Summe beisteuern ...

4th-order bezier with 5th point at origin

+0

Aber wenn 'j'' nbPoint' erreicht, liegt 'p [j]' über den Grenzen des Point-Arrays? – Jonas

+0

Ja - Sie müssen einen fünften Punkt hinzufügen, um einen Bezier 4. Ordnung zu erhalten. Also muss p von der Größe nbPoint + 1 sein. –

+0

Ja, ich verstehe jetzt. Vielen Dank. – Jonas

2

Sie versuchen, ein vierter Ordnung Bezier-Kurve auf nur vier Punkte zu konstruieren. Kein Wunder, dass es nicht funktioniert.

+3

Wie ist das eine Antwort? –

+1

Dies bietet keine Antwort auf die Frage.Um Kritik zu äußern oder um eine Klarstellung von einem Autor zu bitten, hinterlasse einen Kommentar unter ihrem Beitrag. - [Aus Review] (https://stackoverflow.com/review/low-quality-posts/16357822) –

+0

@ DonaldDuck: Dies beantwortet die Frage prägnant und korrekt. Richard Inglis 'Antwort ist besser, mit all den schönen Bildern und allem, aber wenn Sie den ersten Satz dieser Antwort lesen, werden Sie sehen, dass es im Wesentlichen das Gleiche ist wie meines. – TonyK