小编这次要给大家分享的是OpenGL如何实现多段Bezier曲线拼接,文章内容丰富,感兴趣的小伙伴可以来了解一下,希望大家阅读完这篇文章之后能够有所收获。
我们提供的服务有:成都做网站、成都网站制作、成都外贸网站建设、微信公众号开发、网站优化、网站认证、双河ssl等。为1000多家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的双河网站制作公司运行程序的交互方式有点类似corelDraw中的自由曲线绘制,或者photoShop中的钢笔自由路径绘制。
截图:
将BezierCurve封装成了一个类,代码如下:
#ifndef _BEZIERCURVE_H #define _BEZIERCURVE_H #include "vec3.hpp" #include#include #include using namespace std; //// 3次bezier曲线: 四个控制节点。曲线经过首末两个顶点。 class BezierCurve { public: //cell一共有四个控制顶点 // -cell经过V0和V3顶点, // -cell的始端相切于直线:(V0, V1) 和末端相切于(V2,V3) class BezierCell { public: BezierCell(int i0, int i1, int i2, int i3) { setValue(i0, i1, i2, i3); } void setValue(int i0, int i1, int i2, int i3) { ctrlVertxIndex[0] = i0; ctrlVertxIndex[1] = i1; ctrlVertxIndex[2] = i2; ctrlVertxIndex[3] = i3; } const int operator[](int index) const { if (index > 3 || index < 0) return -1; return ctrlVertxIndex[index]; } int ctrlVertxIndex[4]; }; enum eventType { LButtonDown = 0, MouseMove = 1, LButtonUp = 2 }; enum { Bezier3CtrlPnt = 4 }; BezierCurve() { clear(); } ~BezierCurve(){} void begin() { // 开启求值器 glEnable(GL_MAP1_VERTEX_3); clear(); } void mouseSynchro(eventType type, const Vec3d& v) //响应鼠标motion { ////////////////////////////////////////////////////////////////////////// //LButtonDown: 压入点 if (type == LButtonDown) { if (isFirstRender) //for the first cell { vertexVector.push_back(v); //push V0... vertexVector.push_back(v); //push V1... } else if ( cellRenderState() == cellRenderImple::Push ) //for any cell { vertexVector.push_back(v); //push V2... vertexVector.push_back(v); //push V3... cellRenderState.setChange(); //set the flag to change V3 cellNum++; //increase the cell counter } } ////////////////////////////////////////////////////////////////////////// //MouseMove: 动态更新相应的顶点数据 else if (type == MouseMove) { if (isFirstRender) //for the first cell { vertexVector.back() = v; //change the V1 immediately } else if ( cellRenderState() == cellRenderImple::Change )//for any cell { int vecSize = vertexVector.size(); vertexVector[vecSize-2] = v; //change the V2 immediately } } ////////////////////////////////////////////////////////////////////////// //LButtonUp: 为拼接做准备 else if (type == LButtonUp) { if (isFirstRender) { //只有第一个BezierCell可以编辑bezierCell的起始段:(V0,V1) isFirstRender = false; } else if ( cellRenderState() == cellRenderImple::Change) { //if finish the current cell's render //利用v1和中点v0计算出v2:(v1 + v2) / 2 = v0 //next cell begin: push the next cell's V1... int vecSize = vertexVector.size(); Vec3d v0 = vertexVector[vecSize-1]; Vec3d v1 = vertexVector[vecSize-2]; Vec3d v2 = 2 * v0 - v1; vertexVector.push_back(v2); //重置cellRenderFlag cellRenderState.setPush(); } } ////////////////////////////////////////////////////////////////////////// //更新数组的长度 _updateVertexNum(); } void end() { glDisable(GL_MAP1_VERTEX_3); } void renderCurve() { ////////////////////////////////////////////////////////////////////////// //rendering vertex... for (int i=0; i =2 ) { glEnable(GL_LINE_STIPPLE); { glLineStipple(1, 0x0101); glBegin(GL_LINES); { Vec3d v1 = vertexVector[vertexNum-1]; Vec3d v2 = vertexVector[vertexNum-2]; glVertex3dv(v1.getValue()); glVertex3dv(v2.getValue()); } glEnd(); }glDisable(GL_LINE_STIPPLE); } ////////////////////////////////////////////////////////////////////////// //if ( !_check() ) // return; //rendering bezier cells... system("CLS"); for (int i=0; i vertexVector; //顶点数组 class cellRenderImple { public: enum RenderStep { Push = 0, Change = 1 }; cellRenderImple(){ setPush(); } bool operator()(void) { return flag; } void setPush() { flag = Push; } void setChange() { flag = Change; } RenderStep flag; //cell的渲染状态 } cellRenderState; };
另外有需要云服务器可以了解下创新互联建站www.cdcxhl.com,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。