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[0]=1;
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()
{
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.