# Bezier curve not drawn correctly

I'm trying to draw a bezier curve using 3 points. If I use the quadratic form: I get this result: 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: 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)
{
y+=c;
x+=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)
{
x*=factor;
y*= factor;
}
}Point2D;

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.
factorials=1;
for(unsigned int i=1; i<n;i++)
{
factorials[i]= factorials[i-1]*i;
}
point= points * (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()
{
glClearColor(0.75,0.75,0.75,1.0);
glClear(GL_COLOR_BUFFER_BIT);

glColor3f(1.0,0.0,0.0);
glBegin(GL_POINTS);
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.
}
glEnd();

glutSwapBuffers();
}


Unfortunately this is the result that I get: 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++)
v.push_back(1.f);

/* (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
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;
public:
bezier();
void PushPoint2D( Point2D point );
Point2D GetPoint( double time );
};

bezier::bezier(){}
void bezier::PushPoint2D( Point2D point ){
points.push_back(point);
}
Point2D bezier::GetPoint( double time ){
Point2D p;
if( points.size() == 1 ) return points;
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;
b.PushPoint2D(p);
}
return b.GetPoint( time );
}