Cardinal Spline
This is relatively simple, with one end point, one start point, and two control points.
Points between the end point and the start point are implemented by interpolation. interpolation functions:
P(U) =PK-1 (-S * u + 2 S * u) +PK [(2-s) u * u + (S-3) u * u + 1] +PK + 1 [(S-2) * u + (3-2 s) * u + S * u] +PK + 2 (S * u-s * u * U)
Code implementation:
void getInterpolation(point &p1,point &p2,point &p3,point &p4,float s,float u,point *result){ float u2=u*u; float u3=u2*u; result->x=p1.x*(2*s*u2 - s*u3 - s*u) + p2.x*((2-s)*u3 + (s-3)*u2 + 1) +p3.x*((s-2)*u3 + (3-2*s)*u2 + s*u) + p4.x*(s*u3 - s*u2); result->y=p1.y*(2*s*u2 - s*u3 - s*u) + p2.y*((2-s)*u3 + (s-3)*u2 + 1) +p3.y*((s-2)*u3 + (3-2*s)*u2 + s*u) + p4.y*(s*u3 - s*u2);}void drawCdnLine(point *a,float tension){ int i,j,k=100; float s,step=1.0/(float)k; s=(1.0-tension)/2.0; glColor3f(1.0f,0.0f,0.0f); glBegin(GL_LINE_STRIP); float uValue; for(i=0;i<4;i++) { uValue=0.0f; for(j=0;j<k;j++) { point tmp; getInterpolation(a[i],a[(i+1)%4],a[(i+2)%4],a[(i+3)%4],s,uValue,&tmp); glVertex2f(tmp.x,tmp.y); uValue += step; } } glEnd();}void renderGL(){ // Clear the color and depth buffers. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // We don't want to modify the projection matrix. */ glMatrixMode( GL_MODELVIEW ); glLoadIdentity( ); // Move down the z-axis. glTranslatef( 0.0, -1.0, -8.0 ); point c[4]={{-2,0,0},{0,2,0},{3,0,0},{0,-1,0}}; drawCdnLine(c,0.0); SDL_GL_SwapBuffers( );}
Bezr Curve
Similar to the above, the interpolation method is different.
Here we call the OpenGL library function directly.
First, define a global array:
GLfloat c[4][3]={{-10,-10,0},{-1,20,0},{1,-20,0},{10,10,0}};
Add two lines of code to the initialization function:
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &c[0][0]);glEnable(GL_MAP1_VERTEX_3);
Then write the rendering function:
void renderGL(){ int i; // Clear the color and depth buffers. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // We don't want to modify the projection matrix. */ glMatrixMode( GL_MODELVIEW ); glLoadIdentity( ); // Move down the z-axis. glTranslatef( 0.0, -0.0, -50.0 ); glColor3f(1.0, 1.0, 1.0); glBegin(GL_POINTS); for (i = 0; i <= 90; i++) glEvalCoord1f((GLfloat) i/90.0); glEnd(); glPointSize(5.0); glColor3f(1.0, 1.0, 0.0); glBegin(GL_POINTS); for (i = 0; i < 4; i++) glVertex3fv(&c[i][0]); glEnd(); SDL_GL_SwapBuffers( );}
Pay attention to two functions: glmap1 and glevalcoord1.
1. Void glmap1 {FD} (glenum target, type u1, type U2, glint stride, glint order, const type * points );
Function: defines the valuer.
Parameter: Target: indicates the significance of controlling vertices and the number of values required in the points parameter.
Points: points to the control point set, rgba color value, or texture coordinate string.
U1, U2: defines the value range of the variable U, usually from 0 to 1.
Stride: represents the span (the number of floating-point numbers or double-precision numbers in each storage area, that is, the offset between two control points ).
Order: Order, equal to the number of times plus 1, equal to the number of control points.
2. Void glevalcoord1 {FD} [v] (type U ).
Function: This function generates and draws the coordinate values of the curve.
Parameter: U: any value in the definition field. Each call generates only one coordinate, which is also arbitrary.
Currently, the uniform interval curve coordinate value is usually defined, and the same interval value can be obtained by calling glmapgrid1 * () and glevalmesh1 () in sequence. These two functions are respectively used to define a one-dimensional grid and calculate the corresponding coordinate values.
In addition, after the curve is defined, the function can only take effect after the glenable () function is explicitly started, and its parameters are consistent with the target. After use, use the gldisable () function to disable it.