OpenGL: Drawing B-Spline

Source: Internet
Author: User
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 ;}


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.