Draw a B-spline:
# Include <stdlib. h> # include <Gl/glut. h> /// # If 0 /// the points of the curve-these are the same as the bezr curve /// points demonstrated in the bezercurve example. float points [4] [3] = {10, 10, 0}, {5, 10, 2}, {-5, 0}, {-10, 5,-2 }}; # define num_points 4 // The following sets of 4 indices are the curves that need to // be drawn to create a Clamped cubic B-spline. in total there // are 5 curve segments Draw. //// 0 0 0 1 // 0 0 1 2 // 0 1 2 3 // 1 2 3 3 3 // 2 3 3 3 // remember this when trying to understand knot vectors !! // # Elsefloat points [9] [3] = {10, 5, 0}, {5, 10, 0}, {-5, 15, 0}, {-10,-5, 0 }, {4,-}, {10, 5, 0}, {5, 10, 0}, {-5, 15, 0}, {-10,-5, 0 }}; # define num_points 9 // If the curve of the first and last control points has been drawn // 0 0 0 1 // 0 1 2 // 0 1 2 3 // 1 2 3 3 4 // 2 3 4 5 // 3 4 5 6 // 4 5 6 6 // 5 6 6 6 // remember this when trying to understand knot vectors !! /// If a smooth curve is drawn at the beginning and end, that is, the current drawing // 0 1 2 3 // 1 2 3 4 // 2 3 4 5 // 3 4 5 6 # endif // The level of detail for the curveunsigned int dump = 20; /// # define num_segments (NUM_POINTS-3) // float * getpoint (int I) {// return 1st pointif (I <0) {returnpoints [0];} if (I <num_points) return points [I]; // return last pointreturn points [NUM_POINTS-1];} // ---------------------------------------------------------------- onkeypress () // void m Yidle (void) {glupostredisplay ();} // effecondraw () // void ondraw () {// clear the screen & depth bufferglclear (gl_color_buffer_bit ); // clear the previous transformglloadidentity (); // set the camera position // glulookat (, 30, // eye POS //, 0, // aim point // 0.5, 0); // up direction // glcolor3f (0.2, 0); glpointsize (3); // draw curve hullglco Lor3f (0.3, 0, 0.5); glbegin (gl_line_strip); For (INT I = 0; I! = Num_points; ++ I) {glvertex3fv (points [I]);} glend (); glcolor3f (0, 1); // begin drawing our curveglbegin (gl_line_strip ); for (INT start_cv = 0, j = 0; j <num_segments; j ++, start_cv ++) {// For each section of curve, draw layd Number of divisionsfor (INT I = 0; I! = Dashboard; ++ I) {// use the Parametric Time Value 0 to 1 for this curve // segment. float t = (float) I/lods; // The T value invertedfloat it = 1.0f-T; // calculate blending functions for cubic bsplinefloat b0 = It * It/6.0f; float b1 = (3 * T * t-6 * T * t + 4)/6.0f; float b2 = (-3 * T * t + 3 * T * t + 3 * t + 1)/6.0f; float B3 = T * t/6.0f; // calculate the X, Y and Z of the curve pointfloat x = b0 * getpoint (start_cv + 0) [0] + B1 * getpoint (start_cv + 1) [0] + B2 * getpoint (start_cv + 2) [0] + B3 * getpoint (start_cv + 3) [0]; float y = b0 * getpoint (start_cv + 0) [1] + B1 * getpoint (start_cv + 1) [1] + B2 * getpoint (start_cv + 2) [1] + B3 * getpoint (start_cv + 3) [1]; float z = b0 * getpoint (start_cv + 0) [2] + B1 * getpoint (start_cv + 1) [2] + B2 * getpoint (start_cv + 2) [2] + B3 * getpoint (start_cv + 3) [2];/ /Specify the pointglvertex2f (x, y) ;}// we need to specify the last point on the curve // glvertex3fv (points [NUM_POINTS-1]); glend (); // draw CV 'sglbegin (gl_points); For (INT I = 0; I! = Num_points; ++ I) {glvertex3fv (points [I]);} glend (); // currently we 've been drawing to the back buffer, we need // to swap the back buffer with the front one to make the image visiblegluswapbuffers ();} // pythoninit () // void oninit () {// glclearcolor (,);} // pythonexit () // void onexit () {}// pythonreshape () // void onreshape (int w, int h) {// prevents division by zero when minimizing using WIF (H = 0) H = 1; // set the drawable region of the windowglviewport (, W, H ); // set up the projection matrixglmatrixmode (gl_projection); glloadidentity (); // just use a Perspective Projection // gluperspective (45, (float) W/H, 0.1, 100 ); if (W <= h) glortho (-20.0, 20.0,-20.0 * (glfloat) h/(glfloat) W, 20.0 * (glfloat) h/(glfloat) W, 0.0, 100.0); elseglortho (-20.0, 20.0,-20.0 * (glfloat) h/(glfloat) W, 20.0 * (glfloat) h/(glfloat) W, 0.0, 100.0); // go back to modelview matrix so we can move the objects aboutglmatrixmode (gl_modelview); glloadidentity () ;}// specify main () // int main (INT argc, char ** argv) {// initialise gloginit (& argc, argv); // request a depth buffer, rgba display mode, and we want double bufferingglinitdisplaymode (glu_rgba | glu_double ); // set the initial window sizeglutinitwindowsize (640,480); // create the windowglucreatewindow ("clamped B-spline curve"); // run our custom initialisationoninit (); // set the function to use to draw our sceneglutdisplayfunc (ondraw); // set the function to handle changes in screen sizeglutreshapefunc (onreshape); glutidlefunc (& myidle ); // set the function to be called when we exitatexit (onexit); // This function runs a while loop to keep the program running. glumainloop (); Return 0 ;}
Closed-B spline:
Reference:
B-spline details:
Http://blog.csdn.net/tuqu/article/details/5366701
Draw a closed-B-spline:
Http://blog.csdn.net/tuqu/article/details/5386215
OpenGL:
Http://blog.163.com/zhou_ghui/blog/static/177580120132159441827/
<1> DDA straight line: (two points determine a curve, that is, point two points with the mouse );
# Include <windows. h> # include <Gl/glut. h> # include <Gl/GL. h> # include <stdio. h> # include <math. h> glfloat x_coord [2], y_coord [2]; int npoints = 0; inline glfloat x_convert (int x) {return-8.0 + x/499.0*16 ;} inline glfloat y_convert (INT y) {return 8.0-y/499.0*16;} void Init () {glclearcolor (,);} void myreshape (int w, int H) {glviewport (45.0, (glsizei) W, (glsizei) H); glmatrixmode (gl_projection); glloadidentity (); // gluperspective (, (glfloat) W/(glfloat) h, 1.0, 50.0); If (W <= h) glortho (-8.0, 8.0,-8.0 * (glfloat) h/(glfloat) W, 8.0 * (glfloat) h/(glfloat) W,-8.0, 8.0); else glortho (-8.0 * (glfloat) h/(glfloat) W, 8.0 * (glfloat) h/(glfloat) w,-8.0, 8.0,-8.0, 8.0); glmatrixmode (gl_modelview); glloadidentity () ;}int round (float a) {return int (a + 0.5 );} void DDA (INT x0, int xend, int y0, int yend) // DDA draw line algorithm {int dx = xend-x0; int DY = yend-y0; int steps; float xincrement, yincrement, x = x0, y = y0; If (FABS (dx)> FABS (dy) Steps = FABS (dx); else steps = FABS (dy ); xincrement = (float) dx/steps; yincrement = (float) dy/steps; glbegin (gl_points); glpointsize (100); glvertex2i (round (x ), round (y); For (INT I = 0; I x + = xincrement; y + = yincrement; glvertex2i (round (x), round (y ));} glend () ;}void display () {glclear (gl_color_buffer_bit); glcolor3f (, 0); // draw a straight line between two points glbegin (gl_line_strip ); for (INT I = 0; I <npoints; I ++) glvertex3f (x_coord [I], y_coord [I], 0.0); glend (); glcolor3f (1.0, 0, 0); // call the glpointsize (5) of the DDA draw line algorithm; If (npoints = 2) DDA (x_coord [0], x_coord [1], y_coord [0], y_coord [1]); glflush ();} void handle_mouseclick (INT button, int state, int X, int y) {If (Button = maid & State = fig) {If (npoints = 2) npoints = 0; printf ("% d (% d, % d) ==> (% F, % F) \ n", npoints, x, Y, x_convert (x), y_convert (y); x_coord [npoints] = x_convert (x); y_coord [npoints] = y_convert (y); npoints ++; glupostredisplay () ;}} int main (INT argc, char ** argv) {gluinit (& argc, argv); gluinitdisplaymode (glu_single | glu_rgb | glu_depth); gluinitwindowsize (500,500 ); fig (100,100); fig ("hello"); Init (); fig (Display); fig (myreshape); fig (handle_mouseclick); fig (); Return 0 ;}
<2> besuppliers curve (three times: four points determine a curve)
# Include <windows. h> # include <Gl/glut. h> # include <Gl/GL. h> # include <stdio. h> # include <math. h> glfloat x_coord [4], y_coord [4]; int npoints = 0; inline glfloat x_convert (int x) {return-5.0 + x/249.0*10 ;} inline glfloat y_convert (INT y) {return 5.0-y/249.0*10;} void Init () {glclearcolor (,);} void myreshape (int w, int H) {glviewport (45.0, (glsizei) W, (glsizei) H); glmatrixmode (gl_projection); glloadidentity (); // gluperspective (, (glfloat) W/(glfloat) h, 1.0, 50.0); If (W <= h) glortho (-5.0, 5.0,-5.0 * (glfloat) h/(glfloat) W, 5.0 * (glfloat) h/(glfloat) W,-5.0, 5.0); else glortho (-5.0 * (glfloat) h/(glfloat) W, 5.0 * (glfloat) h/(glfloat) w,-5.0, 5.0,-5.0, 5.0); glmatrixmode (gl_modelview); glloadidentity () ;}// p (t) = b0, 3 (t) P0 + B1, 3 (t) P1 + B2, 3 (t) P2 forward B3, 3 (t) P3 // B0, 3 (t) Forward (1-T) 3 // B1, 3 (t) limit 3 T (1-T) 2 // B2, 3 (t) limit 3t2 (1-T) // B3, 3 (t) limit T3 void bezr (int n) // bezr curve {float T, DT, T2, T3, F1, F2, F3, F4; dt = 1.0/N; // T runs from 0 to 1. glbegin (gl_line_strip); For (t = 0.0; t <= 1.0; t + = DT) {t2 = (1-T) * (1-t ); t3 = T2 * (1-T); // T3 = (1-T) * (1-T) * (1-T) F1 = T3; F2 = 3 * T * t2; f3 = 3 * T * (1-T); F4 = T * t; glvertex2f (F1 * x_coord [0] + F2 * x_coord [1] + F3 * x_coord [2] + F4 * x_coord [3], f1 * y_coord [0] + F2 * y_coord [1] + F3 * y_coord [2] + F4 * y_coord [3]);} glend ();} void display () {glclear (gl_color_buffer_bit); glcolor3f (1, 0, 0); glbegin (gl_line_strip); For (INT I = 0; I <npoints; I ++) glvertex3f (x_coord [I], y_coord [I], 0.0); glend (); glcolor3f (0, 1, 0); If (npoints = 4) bezr (20 ); glflush ();} void handle_mouseclick (INT button, int state, int X, int y) {If (Button = maid & State = maid) {If (npoints = 4) npoints = 0; printf ("% d (% d, % d) ==> (% F, % F) \ n", npoints, x, Y, x_convert (x), y_convert (y); x_coord [npoints] = x_convert (x); y_coord [npoints] = y_convert (y); npoints ++; glupostredisplay () ;}} int main (INT argc, char ** argv) {gluinit (& argc, argv); gluinitdisplaymode (glu_single | glu_rgb | glu_depth); gluinitwindowsize (250,250 ); fig (100,100); fig ("hello"); Init (); fig (Display); fig (myreshape); fig (handle_mouseclick); fig (); Return 0 ;}
<3> hermit curve (three times, three points to determine a curve)
# Include <windows. h> # include <Gl/glut. h> # include <Gl/GL. h> # include <stdio. h> # include <math. h> glfloat x_coord [3], y_coord [3]; int npoints = 0; inline glfloat x_convert (int x) {return-8.0 + x/499.0*16 ;} inline glfloat y_convert (INT y) {return 8.0-y/499.0*16;} void Init () {glclearcolor (,);} void myreshape (int w, int H) {glviewport (45.0, (glsizei) W, (glsizei) H); glmatrixmode (gl_projection); glloadidentity (); // gluperspective (, (glfloat) W/(glfloat) h, 1.0, 50.0); If (W <= h) glortho (-8.0, 8.0,-8.0 * (glfloat) h/(glfloat) W, 8.0 * (glfloat) h/(glfloat) W,-8.0, 8.0); else glortho (-8.0 * (glfloat) h/(glfloat) W, 8.0 * (glfloat) h/(glfloat) w,-8.0, 8.0,-8.0, 8.0); glmatrixmode (gl_modelview); glloadidentity ();} void hermit (int n) // {float T, DT, T2, t3, F1, F2, F3, F4; dt = 1.0/N; // T runs from 0 to 1. glfloat pt0_x = x_coord [1]-x_coord [0]; glfloat pt0_y = y_coord [1]-y_coord [0]; glfloat pt1_x = x_coord [2]-x_coord [1]; glfloat pt1_y = y_coord [2]-y_coord [1]; glbegin (gl_line_strip); For (t = 0.0; t <= 1.0; t + = DT) {t2 = T * t; T3 = T2 * t; // T3 = T * t F1 = 2.0 * T3-3.0 * t2 + 1.0; f2 =-2.0 * T3 + 3.0 * t2; F3 = T3-2.0 * t2 + T; F4 = T3-t2; glvertex2f (F1 * x_coord [0] + F2 * x_coord [2] + F3 * pt0_x + F4 * pt1_x, f1 * y_coord [0] + F2 * y_coord [2] + F3 * pt0_y + F4 * pt1_y);} glend ();} void display () {glclear (gl_color_buffer_bit ); glcolor3f (0, 0); // draw a line between two points glbegin (gl_line_strip); For (INT I = 0; I <npoints; I ++) glvertex3f (x_coord [I], y_coord [I], 0.0); glend (); glcolor3f (1.0, 0, 0 ); // call the DDA draw line algorithm if (npoints = 3) hermit (20); glflush ();} void handle_mouseclick (INT button, int state, int X, int y) {If (Button = maid & State = maid) {If (npoints = 3) npoints = 0; printf ("% d (% d, % d) ==> (% F, % F) \ n ", npoints, X, Y, x_convert (x), y_convert (y )); x_coord [npoints] = x_convert (x); y_coord [npoints] = y_convert (y); npoints ++; glupostredisplay () ;}} int main (INT argc, char ** argv) {gluinit (& argc, argv); gluinitdisplaymode (glu_single | glu_rgb | glu_depth); gluinitwindowsize (500,500); gluinitwindowposition (100,100); glucreatewindow ("hello "); init (); fig (myreshape); fig (handle_mouseclick); fig (); Return 0 ;}
<4> B-spline (right-click to select a point on the screen, left-click to drag a point) (three times, four points to determine a curve)
# Include <windows. h> # include <Gl/glut. h> # include <Gl/GL. h> # include <stdio. h> # include <math. h> glfloat x_coord [100], y_coord [100]; int npoints = 0; Int J = 0; inline glfloat x_convert (int x) {return-5.0 + x/249.0*10;} inline glfloat y_convert (INT y) {return 5.0-y/249.0*10;} void Init () {glclearcolor, );} void myreshape (int w, int h) {glviewport (, (glsizei) W, (glsizei) H); glmatrixmode (gl_projection); glloadidentity (); // gluperspective (45.0, (glfloat) W/(glfloat) h, 1.0, 50.0); If (W <= h) glortho (-5.0, 5.0, -5.0 * (glfloat) h/(glfloat) W, 5.0 * (glfloat) h/(glfloat) W,-5.0, 5.0); else glortho (-5.0 * (glfloat) h/(glfloat) W, 5.0 * (glfloat) h/(glfloat) W,-5.0, 5.0,-5.0, 5.0); glmatrixmode (gl_modelview); glloadidentity ();} // (1/2) * (t-1) * (t-1) // (1/2) * (-2 * T * t + 2 * t + 1) // (1/2) * T * t void B2 (int n) // three times of B-Spline Curve {float T, DT, T2, T3, F1, F2, F3, F4; dt = 1.0/N; // T runs from 0 to 1. glbegin (gl_line_strip); For (Int J = 0; j <(npoints-2); j ++) for (t = 0.0; t <= 1.0; t + = DT) {F1 = (1.0/6) * (-1) * T * t + 3 * T * T-3 * t + 1); F2 = (1.0/6) * (3 * T * T-6 * T * t + 4); F3 = (1.0/6) * (-3) * T * t + 3 * T * t + 3 * t + 1); F4 = (1.0/6) * (T * t ); glvertex2f (F1 * x_coord [J] + F2 * x_coord [J + 1] + F3 * x_coord [J + 2] + F4 * x_coord [J + 3], f1 * y_coord [J] + F2 * y_coord [J + 1] + F3 * y_coord [J + 2] + F4 * y_coord [J + 3]);} glend ();} void display () {glclear (gl_color_buffer_bit); glbegin (gl_line_strip); glcolor3f (0, 1, 0); For (INT I = 0; I <npoints; I ++) {glvertex3f (x_coord [I], y_coord [I], 0.0);} glend (); glcolor3f (1.0, 0, 0 ); if (npoints> = 4) {B2 (20);} glflush ();} void handle_mouseclick (INT button, int state, int X, int y) {If (Button = maid & State = maid) {If (npoints> = 4) J ++; printf ("% d (% d, % d) ==> (% F, % F) \ n ", npoints, X, Y, x_convert (x), y_convert (y )); x_coord [npoints] = x_convert (x); y_coord [npoints] = y_convert (y); npoints ++; glupostredisplay () ;}} void mousemotion (int x, int y) {float min = 99999999; int index; X = x_convert (x); y = y_convert (y); int I; for (I = 0; I if (min> (x-x_coord [I]) * (x-x_coord [I]) + (y-y_coord [I]) * (y-y_coord [I]) {min = (x-x_coord [I]) * (x-x_coord [I]) + (y-y_coord [I]) * (y-y_coord [I]); Index = I ;} x_coord [Index] = x; y_coord [Index] = y; glupostredisplay ();} int main (INT argc, char ** argv) {gluinit (& argc, argv ); fig ); fig (handle_mouseclick); fig (mousemotion); fig (); Return 0 ;}