I am trying to find the way to generate bezier curve using de casteljau algorithm for one of my assignment here. I am able to generate bezier curve using normal method but unable to start on generating using the above algorithm. It will be of great help if someone can suggest me to right direction or share any piece of code you have. I am not just asking as is. I worked a lot on it and wrote the following code myself to generate the curve.
I found a web applet which does exactly i needed. (http://www2.mat.dtu.dk/people/J.Gravesen/cagd/decast.html). suggest me how to achieve that

#include <iostream>
    using std::cerr;
    using std::endl;
    #include <stdlib.h>
    //using std::exit;
    #include <GL/glut.h> // GLUT stuff, includes OpenGL headers as well 
    #include <windows.h>
    #include <math.h>
    #include <gl/Gl.h>
    #include <gl/Glu.h>
    
     
    int SCREEN_HEIGHT = 480;
    // Keep track of times clicked, on 3 clicks draw.
    int NUMPOINTS = 0;
     
    // Point class to keep it a little cleaner.
    class Point {
    public:
        float x, y, z;
        void setxy(float x2, float y2) { x = x2; y = y2; }
        const Point & operator=(const Point &rPoint) {
             x = rPoint.x;
             y = rPoint.y;
    		 z = rPoint.z;
     
             return *this;
          }
     
    };
     
    Point abc[4];
     
    void myInit() {
        glClearColor(0.0,0.0,0.0,0.0);
        glColor3f(1.0,0.0,0.0);
        glPointSize(4.0);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluOrtho2D(0.0,640.0,0.0,480.0);
        
    }
     
    void drawDot(int x, int y) {
        glBegin(GL_POINTS);
         glVertex2i(x,y);
        glEnd();
        glFlush();
    }
     
    void drawLine(Point p1, Point p2) {
        glBegin(GL_LINES);
          glVertex3f(p1.x, p1.y, p1.z);
          glVertex3f(p2.x, p2.y, p2.z);
    	 
        glEnd();
        glFlush();
    }
     
    // Calculate the next bezier point.
    Point drawBezier(Point A, Point B, Point C, Point D, double t) {
        Point P;
    
    	
    	
     
        P.x = pow((1 - t), 3) * A.x + 3 * t * pow((1 -t), 2) * B.x + 3 * (1-t) * pow(t, 2)* C.x + pow (t, 3)* D.x;
        P.y = pow((1 - t), 3) * A.y + 3 * t * pow((1 -t), 2) * B.y + 3 * (1-t) * pow(t, 2)* C.y + pow (t, 3)* D.y;
    	P.z = pow((1 - t), 3) * A.z + 3 * t * pow((1 -t), 2) * B.z + 3 * (1-t) * pow(t, 2)* C.z + pow (t, 3)* D.z;
    
        return P;
    }
     
    void myMouse(int button, int state, int x, int y) {
      // If left button was clicked
      if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
          // Store where the user clicked, note Y is backwards.
        abc[NUMPOINTS].setxy((float)x,(float)(SCREEN_HEIGHT - y));
        NUMPOINTS++;
            
        // Draw the red  dot.
        drawDot(x, SCREEN_HEIGHT - y);
     
        // If 3 points are drawn do the curve.
        if(NUMPOINTS == 4) {
            glColor3f(1.0,1.0,1.0);
            // Draw two legs of the triangle
            drawLine(abc[0], abc[1]);
            drawLine(abc[1], abc[2]);
    		drawLine(abc[2], abc[3]);
    		//drawLine(abc[3], abc[4]);
            Point POld = abc[0];
            /* Draw each segment of the curve.  Make t increment in
                       smaller amounts for a more detailed curve. */
            for(double t = 0.0;t <= 1.0; t += 0.1) {
                Point P = drawBezier(abc[0], abc[1], abc[2], abc[3],  t);
                drawLine(POld, P);
                POld = P;
            }
            glColor3f(1.0,0.0,0.0);
            NUMPOINTS = 0;
        }
      }
    }
     
    void myDisplay() {
        glClear(GL_COLOR_BUFFER_BIT);
        glFlush();
    }
     
    int main(int argc, char *argv[]) {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
        glutInitWindowSize(640,480);
        glutInitWindowPosition(100,150);
        glutCreateWindow("Bezier Curve");
     
        glutMouseFunc(myMouse);
        glutDisplayFunc(myDisplay);
     
        myInit();
        glutMainLoop();
     
        return 0;
    }

Recommended Answers

All 3 Replies

I'd suggest replacing your drawBezier() function at line 61 (which should really be called something like computeBezierPoint(), since that's what it does), with a new computeDeCasteljauPoint() function.

Note that the de casteljau definition lends itself well to recursion -- given an initial set of N points, and a value t, you compute a new set of N-1 points. And continue until there's only one point left. So maybe a shell of your function should look something like this:

Point computeDeCasteljauPoint(vector<Point> points, double t)
{
  // TODO: check for valid input before continuing, decide what to return if input is bogus.
  int numPoints = points.size() - 1;
  vector<Point> computedPoints(numPoints);
  // loop over input points, computing computedPoints
  // decide whether to recurse or return
  // if returning, return the correct thing
  // recursing should be simple enough
}

Thank you so much for your reply. I am just starting to learn open gl and C++. A bit on weaker side. the above code took one week for me to write though i have borrowed the skeleton of it from another forum.

I was given the question like this. As per your suggestion, i need to recurse 9 times as i was asked to do so. But is the logic same for de casteljau too?

You will write an interactive program for the definition and drawing of Bezier curve.
Your program should be able to:

1. Interactively define the initial control polyline as an OpenGL line strip. 
2. a numeber i, (i = 1 · · · 9): draw the level-i polylines generated from the procedure described above.
3. “+” or “-”: increase or decrease the current level of approximation by 1, and draw the new polylines.

Ah. First of all, move the code that draws the points and the Bezier curve out of MyMouse() into its own function, and then call that function from myDisplay(). That way you can add a key-capturing function to catch the '+' and '-' keys, and adjust how the curve is drawn.

I didn't previously follow your link, so I didn't realize it was a working example, rather than an explanation. Google is your friend, give it a try (I recommend wikipedia.com for excellent explanations of math/science-related stuff). The logic/algorithm is obvious enough, and no, it isn't the same as the polynomial approach you're using now (though the polynomial can be derived directly from the de casteljau logic).

Once you're clear on what the de casteljau algorithm is, you should be able to tell me what is meant by "the level-i polylines" referred to in step 2, how to handle levels above 3 (since your instructions tell you to be able to handle up to 9), and how you would modify the recursive shell I've given you to return the information you need (or what function you would write instead, since I don't think what you have now is really what's asked for).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.