OpenGL:绘制B样条曲线
来源:互联网 发布:小仙女的网络意思 编辑:程序博客网 时间:2024/05/01 14:23
绘制B样条曲线:
#include <stdlib.h>#include <GL/glut.h>//#if 0/// the points of the curve - these are the same as the bezier curve/// points demonstrated in the bezier curve example.float Points[4][3] = {{ 10,10,0 },{ 5,10,2 },{ -5,0,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 to draw.////0 0 0 1// 0 0 1 2// 0 1 2 3// 1 2 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,-4,0 },{ 10,5,0 },{ 5,10,0 },{ -5,15,0 },{ -10,-5,0 }};#define NUM_POINTS 9//若绘制过首尾控制点的曲线 //0 0 0 1// 0 0 1 2// 0 1 2 3// 1 2 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!!////若绘制首尾相接的平滑曲线 ,即为当前绘制// 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 LOD=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 myIdle(void) {glutPostRedisplay();}//------------------------------------------------------------OnDraw()//void OnDraw() {// clear the screen & depth bufferglClear(GL_COLOR_BUFFER_BIT);// clear the previous transformglLoadIdentity();// set the camera position// gluLookAt(1,10,30,//eye pos// 0,0,0,//aim point// 0,1,0);//up direction// glColor3f(0.5,0.2,0); glPointSize(3);// // // draw curve hullglColor3f(0.3,0,0.5);glBegin(GL_LINE_STRIP);for(int i=0;i!=NUM_POINTS;++i) {glVertex3fv( Points[i] );}glEnd();glColor3f(0,1,0);// 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 LOD number of divisionsfor(int i=0;i!=LOD;++i) {// use the parametric time value 0 to 1 for this curve// segment.float t = (float)i/LOD;// the t value invertedfloat it = 1.0f-t;// calculate blending functions for cubic bsplinefloat b0 = it*it*it/6.0f;float b1 = (3*t*t*t - 6*t*t +4)/6.0f;float b2 = (-3*t*t*t +3*t*t + 3*t + 1)/6.0f;float b3 = t*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 visibleglutSwapBuffers();}//------------------------------------------------------------OnInit()//void OnInit() {//glClearColor(1,1,1,0);}//------------------------------------------------------------OnExit()//void OnExit() {}//------------------------------------------------------------OnReshape()//void OnReshape(int w, int h){// prevents division by zero when minimising windowif (h==0)h=1;// set the drawable region of the windowglViewport(0,0,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();}//------------------------------------------------------------main()//int main(int argc,char** argv) {// initialise glutglutInit(&argc,argv);// request a depth buffer, RGBA display mode, and we want double bufferingglutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);// set the initial window sizeglutInitWindowSize(640,480);// create the windowglutCreateWindow("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.glutMainLoop();return 0;}
closed-B样条:
Reference:
B样条详细说明:
http://blog.csdn.net/tuqu/article/details/5366701
绘制closed-B样条曲线:http://blog.csdn.net/tuqu/article/details/5386215
OpenGL绘制DDA、Hermite、Bezier、B样条:
http://blog.163.com/zhou_ghui/blog/static/177580120132159441827/
<1>DDA直线:(两点确定一条曲线,即用鼠标点两点);
#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(1,1,1,0); } void myReshape(int w,int h) { glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //gluPerspective(45.0,(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画线算法 { 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,1,0); //画两点之间的直线 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); //调用DDA画线算法 glPointSize(5); 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 == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { 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++; glutPostRedisplay(); } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB |GLUT_DEPTH); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow ("hello"); init (); glutDisplayFunc( display ); glutReshapeFunc(myReshape); glutMouseFunc(handle_mouseclick); glutMainLoop(); return 0; }
<2>Bezier曲线(三次:四点确定一条曲线)
#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(1,1,1,0); } void myReshape(int w,int h) { glViewport(0,0,(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(); } //P(t)= B0,3(t)P0 + B1,3(t)P1+ B2,3(t)P2﹢B3,3(t)P3 // B0,3(t)﹦(1-t)3 // B1,3(t)﹦3t(1-t)2 //B2,3(t)﹦3t2(1-t) //B3,3(t)﹦t3 void Bezier(int n) //Bezier曲线 { 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*t*(1-t); f4 = t*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) Bezier(20); glFlush(); } void handle_mouseclick (int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { 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++; glutPostRedisplay(); } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB |GLUT_DEPTH); glutInitWindowSize (250, 250); glutInitWindowPosition (100, 100); glutCreateWindow ("hello"); init (); glutDisplayFunc( display ); glutReshapeFunc(myReshape); glutMouseFunc(handle_mouseclick); glutMainLoop(); return 0; }
<3>Hermit曲线(三次,三点确定一条曲线)
#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(1,1,1,0); } void myReshape(int w,int h) { glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //gluPerspective(45.0,(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 * 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,1,0); //画两点之间的直线 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); //调用DDA画线算法 if (nPoints == 3) Hermit(20); glFlush(); } void handle_mouseclick (int button, int state, int x, int y){ if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { 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++; glutPostRedisplay(); } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB |GLUT_DEPTH); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow ("hello"); init (); glutDisplayFunc( display ); glutReshapeFunc(myReshape); glutMouseFunc(handle_mouseclick); glutMainLoop(); return 0; }
<4>B样条曲线(实现鼠标右键在屏幕中选点,左键可拖动点)(三次,四点确定一条曲线)
#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(1,1,1,0); } void myReshape(int w,int h) { glViewport(0,0,(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) //B样条3次曲线 { 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*t+3*t*t-3*t+1); f2 = (1.0/6)*(3*t*t*t-6*t*t+4); f3 = (1.0/6)*((-3)*t*t*t+3*t*t +3*t +1); f4= (1.0/6)*(t*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 == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) { 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++; glutPostRedisplay(); } } 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; glutPostRedisplay(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB |GLUT_DEPTH); glutInitWindowSize (250, 250); glutInitWindowPosition (100, 100); glutCreateWindow ("hello"); init (); glutDisplayFunc( display ); glutReshapeFunc(myReshape); glutMouseFunc(handle_mouseclick); glutMotionFunc(mousemotion); glutMainLoop(); return 0; }
- OpenGL:绘制B样条曲线
- OpenGL: 绘制B样条曲线
- 绘制B样条曲线
- MATLAB绘制B样条曲线
- 如何绘制三次B样条曲线
- MATLAB绘制B样条曲线
- B样条曲线的绘制
- OpenGL进阶(三) - 样条曲线的绘制
- OpenGL进阶(二)样条曲线的绘制
- B样条曲线
- B样条曲线
- B样条曲线
- B样条曲线
- B样条曲线
- B样条曲线
- B样条曲线
- B-样条曲线:开曲线
- B-样条曲线:闭曲线
- 系统栈的工作原理
- java反射机制
- 动态规划:从新手到专家
- 使用boost读取XML文件
- 【C++】STL的sort
- OpenGL:绘制B样条曲线
- uboot 串口初始化
- 性能分析工具gprof简介
- 常用AS3性能优化总结
- CodeBlocks+MinGW+Wxwidgets程序的静态链接
- 排序算法温习 - 冒泡排序
- HDU-1026Ignatius and the Princess I
- ASP.NET框架页中的网页重定向
- C语言--根据年月计算该月天数