OpenGL下通過滑鼠動態繪製三次Bezier曲線

來源:互聯網
上載者:User

三次Bezier曲線有四個控制節點。利用OpenGL的一維求值器原理。

 

程式介紹:

第一次滑鼠左鍵down點為0控制節點, 按住左鍵移動動態移動確定1控制節點,

第二次滑鼠左鍵down點3控制節點,按住左鍵移動,確定2控制節點。

程式啟動並執行:

 

 代碼只是實現了繪製一段Bezier如下:

#include <GL/glut.h><br />#include <iostream><br />#include <vector><br />using namespace std;</p><p>#define KEY_POINT_NUM 6<br />#define CONTROL_POINT_NUM 4<br />#define WinWidth1024<br />#define WinHeight768</p><p>#define DrawOneLine(x1, y1, z1, x2, y2, z2) glBegin(GL_LINES);/<br />glVertex3d( (x1), (y1), (z1) ); glVertex3d( (x2), (y2), (z2) ); glEnd(); </p><p>enumDRAW_FLAG{<br />FIRST_LINE = 0,<br />SECOND_LINE = 1,<br />END = 2<br />};<br />intg_iFlag = FIRST_LINE;<br />intg_Viewport[4];<br />boolg_bIsDown = false;<br />doubleg_ModelMatrix[16];<br />doubleg_ProjMatrix[16];<br />double g_Vertex[KEY_POINT_NUM][3];//6個關鍵點,其中四個為控制結點。<br />doubleg_ControlVertex[CONTROL_POINT_NUM+3][3];</p><p>//////////////////////////////////////////////////////////////////////////<br />void init();<br />void display();<br />void reshape(int w, int h);<br />void keyboard(unsigned char key, int x, int y);<br />void mouse(int button, int state, int x, int y);<br />void motion(int x, int y);</p><p>int main(int argc, char** argv)<br />{<br />glutInit(&argc, argv);<br />glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);<br />glutInitWindowSize (WinWidth, WinHeight);<br />glutInitWindowPosition (100, 100);<br />glutCreateWindow (argv[0]);</p><p>init ();<br />glutDisplayFunc(display);<br />glutReshapeFunc(reshape);<br />glutKeyboardFunc (keyboard);<br />glutMouseFunc(mouse);<br />glutMotionFunc(motion);</p><p>glutMainLoop();</p><p>return 0;<br />}</p><p>void init(void)<br />{<br /> glClearColor(0.0, 0.0, 0.0, 0.0);<br /> glShadeModel(GL_SMOOTH);<br />}</p><p>void display(void)<br />{<br />glClear(GL_COLOR_BUFFER_BIT);</p><p>glPointSize(5.0);<br />glColor3f(1.0, 1.0, 0.0);</p><p>glEnable(GL_LINE_STIPPLE);<br />{<br />glLineStipple(1, 0x0101);<br />if (FIRST_LINE==g_iFlag)<br />{<br />DrawOneLine( g_Vertex[0][0], g_Vertex[0][1], g_Vertex[0][2],<br /> g_Vertex[1][0], g_Vertex[1][1], g_Vertex[1][2] );<br />DrawOneLine( g_Vertex[0][0], g_Vertex[0][1], g_Vertex[0][2],<br /> g_Vertex[2][0], g_Vertex[2][1], g_Vertex[2][2] );</p><p>glBegin(GL_POINTS);<br />{<br />glVertex3dv(g_Vertex[0]);<br />glVertex3dv(g_Vertex[1]);<br />glVertex3dv(g_Vertex[2]);<br />} glEnd();<br />}<br />else if (SECOND_LINE==g_iFlag)<br />{<br />DrawOneLine( g_Vertex[3][0], g_Vertex[3][1], g_Vertex[3][2],<br /> g_Vertex[4][0], g_Vertex[4][1], g_Vertex[4][2] );<br />DrawOneLine( g_Vertex[3][0], g_Vertex[3][1], g_Vertex[3][2],<br /> g_Vertex[5][0], g_Vertex[5][1], g_Vertex[5][2] );</p><p>glBegin(GL_POINTS);<br />{<br />glVertex3dv(g_Vertex[0]);<br />glVertex3dv(g_Vertex[3]);<br />glVertex3dv(g_Vertex[4]);<br />glVertex3dv(g_Vertex[5]);<br />} glEnd();<br />}<br />}glDisable(GL_LINE_STIPPLE);</p><p>//提取控制節點,繪製bezier曲線。<br />//////////////////////////////////////////////////////////////////////////<br />glBegin(GL_POINTS);<br />{<br />for (int i = 0; i < CONTROL_POINT_NUM; i++)<br />glVertex3dv(&g_ControlVertex[i][0]);<br />} glEnd();</p><p>glColor3f(1.0f, 1.0f, 1.0f);<br />glMap1d(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, CONTROL_POINT_NUM, &g_ControlVertex[0][0]);<br />glEnable(GL_MAP1_VERTEX_3);<br />glBegin(GL_LINE_STRIP);<br />{<br />for (int i = 0; i <= 30; i++)<br />glEvalCoord1f((GLfloat) i/30.0f);<br />} glEnd();<br />//////////////////////////////////////////////////////////////////////////</p><p>glutSwapBuffers();<br />}</p><p>void reshape(int w, int h)<br />{<br /> glViewport(0, 0, (GLsizei) w, (GLsizei) h);<br /> glMatrixMode(GL_PROJECTION);<br /> glLoadIdentity();<br /> if (w <= h)<br /> glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w,<br /> 5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);<br /> else<br /> glOrtho(-5.0*(GLfloat)w/(GLfloat)h,<br /> 5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);<br /> glMatrixMode(GL_MODELVIEW);<br /> glLoadIdentity();<br />}</p><p>void keyboard(unsigned char key, int x, int y)<br />{<br /> switch (key) {<br /> case 27:<br /> exit(0);<br /> break;<br /> }<br />}</p><p>void mouse(int button, int state, int x, int y)<br />{<br />//擷取矩陣資訊<br />glGetIntegerv(GL_VIEWPORT, g_Viewport);<br />glGetDoublev(GL_MODELVIEW_MATRIX, g_ModelMatrix);<br />glGetDoublev(GL_PROJECTION_MATRIX, g_ProjMatrix);</p><p>if (button==GLUT_LEFT && state==GLUT_DOWN)<br />{<br />g_bIsDown = true;</p><p>double _3dPoint[3];<br />y = g_Viewport[3] - y;</p><p>if (FIRST_LINE==g_iFlag)<br />{<br />gluUnProject( x, y, 0,<br />g_ModelMatrix, g_ProjMatrix, g_Viewport,<br />&_3dPoint[0], &_3dPoint[1], &_3dPoint[2] );</p><p>// 全部初始化<br />for (int i=0; i<3; i++)<br />g_ControlVertex[0][i] = g_Vertex[0][i] = _3dPoint[i];<br />}<br />else if (SECOND_LINE==g_iFlag)<br />{<br />gluUnProject( x, y, 0,<br />g_ModelMatrix, g_ProjMatrix, g_Viewport,<br />&_3dPoint[0], &_3dPoint[1], &_3dPoint[2] );</p><p>// 主要是儲存v(3)<br />for (int i=0; i<3; i++)<br />g_ControlVertex[3][i] = g_Vertex[3][i] = _3dPoint[i];<br />}<br />}</p><p>if (button==GLUT_LEFT && state==GLUT_UP)<br />{<br />g_bIsDown = false;</p><p>g_iFlag = (g_iFlag+1) % 3;</p><p>glutSetCursor( GLUT_CURSOR_RIGHT_ARROW );<br />}<br />}</p><p>//////////////////////////////////////////////////////////////////////////<br />// 計算控制節點<br />void motion(int x, int y)<br />{<br />if ( !g_bIsDown )<br />return;</p><p>glutSetCursor( GLUT_CURSOR_CROSSHAIR );<br />y = g_Viewport[3] - y;</p><p>if ( FIRST_LINE==g_iFlag )<br />{<br />gluUnProject( x, y, 0,<br />g_ModelMatrix, g_ProjMatrix, g_Viewport,<br />&g_Vertex[1][0], &g_Vertex[1][1], &g_Vertex[1][2] );</p><p>for (int i=0; i<3; i++)<br />{<br />// 記錄控制結點<br />g_ControlVertex[1][i] = g_Vertex[1][i];</p><p>// V0為V1和V2的中點<br />g_Vertex[2][i] = 2 * g_Vertex[0][i] - g_Vertex[1][i];<br />}<br />}<br />else if ( SECOND_LINE==g_iFlag )<br />{<br />gluUnProject( x, y, 0,<br />g_ModelMatrix, g_ProjMatrix, g_Viewport,<br />&g_Vertex[5][0], &g_Vertex[5][1], &g_Vertex[5][2] );</p><p>for (int i=0; i<3; i++)<br />{<br />// V3為V4和V5的中點<br />g_Vertex[4][i] = 2 * g_Vertex[3][i] - g_Vertex[5][i];</p><p>// 記錄控制結點<br />g_ControlVertex[2][i] = g_Vertex[4][i];<br />}<br />}</p><p>glutPostRedisplay();<br />}<br />

 

有時間將進一步實現多段拼接。 

 

 

 

 

 

 

 

 

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.