I'm trying to draw a bezier curve using 3 points. If I use the quadratic form:

enter image description here

I get this result:

enter image description here

And I believe it's correct.

Now since I need to draw it with a variable number of points, I'm trying to apply the explicit definition:

enter image description here

This is the code that implements it:

typedef struct Point2D
    GLfloat x;
    GLfloat y;
    Point2D operator+(GLfloat c) const 
        return {x+c, y+c};
    Point2D operator+ (const Point2D& other) const 
        return {x+other.x, y+other.y};
    void operator+= (GLfloat c)
    void operator+= (const Point2D& other)
        x+= other.x;
        y+= other.y;
    Point2D operator* (GLfloat factor) const 
        return {x*factor, y*factor};
    void operator*= (GLfloat factor)
        y*= factor;

Point2D bezier(const vector<Point2D>& points, GLfloat u) // u is t
    Point2D point;
    unsigned int n= points.size();
    vector<int> factorials(n);
    // For efficiency, I put all factorials in an array instead
    // of recalculating them each time.
    GLfloat c1= pow(1.0-u,n-2); 
    // This is (1-t)^(n-1)
    GLfloat c2= 1.0;
    // This is t^i , I'll progressively multiply it for u.
    for(unsigned int i=1; i<n;i++)
        factorials[i]= factorials[i-1]*i;
    point= points[0] * (GLfloat)(n-1) * c1; // This is the first point
    for(unsigned int i=1; i<n; i++)
        c2*= u;
        GLfloat bCoeff= factorials[n-1]/(factorials[i]*factorials[n-2]);
            // bCoeff is the binomial coefficient: n! / ( i! * (n-1)! )
        point+= points[i] * bCoeff * c1 * c2;
    return point;

void display()

    vector<Point2D> points{Point2D{200,200}, Point2D{400,400}, Point2D{600,200} };
    for(GLfloat u=0.0; u<=1.0; u+=1.0e-4)
        Point2D point;
        point= bezier(points,u);
        glVertex2f(point.x,point.y); // For now I use the immediate mode
                                         // I'll put it in a vbo.


Unfortunately this is the result that I get:

enter image description here

Which I believe is incorrect. I guess I'm not applying correctly the explicit definition, but I don't know where's the mistake, I would like to know what I'm doing wrong.


It is indeed wrong for at least two reasons:

  • you never update c1.
  • you use n! / ( i! * (n-1)! instead of n! / ( i! * (n-i)!.

This means you'll need to reorganise your code. You might try something like this:

unsigned int n = points.size();

vector<float> v;
for (unsigned i = 0; i < n; i++)

/* (un1) is t^i, (un2) is (1-t)^i */
float un1 = 1.f, un2 = 1.f, inv_fact = 1.f;

/* At the end of the loop, we are still missing the
 * "n!" multiplication, but we can do it at the very
 * end instead. */
for (unsigned i = 0; i < n; i++)
    v[i] *= un1 * inv_fact;
    un1 *= u;
    v[n - 1 - i] *= un2 * inv_fact;
    un2 *= (1.f - u);
    if (i != 0 && i != n - 1) inv_fact /= i;

Point2D point{0,0};
for (unsigned i = 0; i < n; i++)
    point += v[i] * points[i];

return (1.f / inv_fact) * point;

You could also use my recursive approach to n-order bezier curves. This method can also be adapted for use with integers if needed.

class bezier{
    std::vector<Point2D> points;
    void PushPoint2D( Point2D point );
    Point2D GetPoint( double time );

void bezier::PushPoint2D( Point2D point ){
Point2D bezier::GetPoint( double time ){
    Point2D p;
    if( points.size() == 1 ) return points[0];
    if( points.size() == 0 ) return p;

    bezier b;
    for( int i = 0; i < points.size()-1; ++i ){
        p.x = ( points[i+1].x - points[i].x ) * time + points[i].x;
        p.y = ( points[i+1].y - points[i].y ) * time + points[i].y;
        if( points.size() <= 2 ) return p;
    return b.GetPoint( time );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.