OpenGL实现Hermite算法绘制三次曲线
来源:互联网 发布:ps盖印图层快捷键 mac 编辑:程序博客网 时间:2024/05/19 16:04
首先是推导:节省功夫我就直接贴照片了。
程序加了鼠标的监听器,可以移动控制点和型值点。
程序效果:
代码如下:
#include<gl/glut.h>#include<math.h>#include<windows.h>#include<algorithm>using namespace std;struct Vertex{ int x, y; Vertex(int tx, int ty) { x = tx; y = ty; }};Vertex p0(100, 250); //型值点Vertex p1(400, 250);Vertex c0(150, 200); //控制点Vertex c1(350, 300); bool mouseLeftIsDown = false;bool mouseRightIsDown = false;int caculateSquareDistance(Vertex a, Vertex b){ return (a.x - b.x)*(a.x - b.x) + (a.y - b.y);}void Hermite(int n) //精度{ //求出相对于控制点的向量(切线) //这里把切点的长度人为扩大4倍,划线的效果更为明显(实际上不符合计算出的公式) Vertex tempC0((c0.x - p0.x)<<2, (c0.y - p0.y)<<2); Vertex tempC1((c1.x - p1.x)<<2, (c1.y - p1.y)<<2); double delTa = 1.0 / n; glBegin(GL_LINE_STRIP); for (int i = 0; i < n; i++) { double t = i * delTa; double t1 = 2 * pow(t, 3) - 3 * pow(t, 2) + 1; double t2 = -2 * pow(t, 3) + 3 * pow(t, 2); double t3 = pow(t, 3) - 2 * pow(t, 2) + t; double t4 = pow(t, 3) - pow(t, 2); glVertex2d(p0.x*t1 + p1.x*t2 + tempC0.x*t3 + tempC1.x*t4, p0.y*t1 + p1.y*t2 + tempC0.y*t3 + tempC1.y*t4); } glEnd();}void myDisplay(){ glClear(GL_COLOR_BUFFER_BIT); //清除。GL_COLOR_BUFFER_BIT表示清除颜色 glPointSize(10.0f); glColor3f(0, 0, 1); //画出型值点和控制点(蓝色) glBegin(GL_POINTS); glVertex2d(p0.x, p0.y); glVertex2d(p1.x, p1.y); glVertex2d(c0.x, c0.y); glVertex2d(c1.x, c1.y); glEnd(); //画出控制点与型值点的连线(红色) glColor3f(1, 0, 0); glLineWidth(3); glBegin(GL_LINES); glVertex2d(p0.x, p0.y); glVertex2d(c0.x, c0.y); glVertex2d(p1.x, p1.y); glVertex2d(c1.x, c1.y); glEnd(); Hermite(200); glFlush(); glutSwapBuffers();}void mouse(int button,int state,int x, int y) //监听鼠标动作{ if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { mouseLeftIsDown = true; } if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) { mouseLeftIsDown = false; } if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) { mouseRightIsDown = true; } if (button == GLUT_RIGHT_BUTTON && state == GLUT_UP) { mouseRightIsDown = false; }}void motion(int x, int y) //移动点{ if (mouseLeftIsDown) //左键移动控制点 { if (caculateSquareDistance(Vertex(x, y), c0) < 400) //防止鼠标移动过快点位无法及时读取,经测试,400为一个较适合的值 { c0.x = x; c0.y = y; } else if (caculateSquareDistance(Vertex(x, y), c1) < 400) { c1.x = x; c1.y = y; } } else if (mouseRightIsDown) //右键移动型值点 { if (caculateSquareDistance(Vertex(x, y), p0) < 400) { p0.x = x; p0.y = y; } else if (caculateSquareDistance(Vertex(x, y), p1) < 400) { p1.x = x; p1.y = y; } } glutPostRedisplay(); //重新构图}void Reshape(int w, int h) //两个参数:窗口被移动后大小{ glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, w, h, 0); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}void initWindow(int &argc, char *argv[], int width, int height, char *title) //初始化并显示到屏幕中央{ glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutInitWindowPosition((GetSystemMetrics(SM_CXSCREEN) - width) >> 1, (GetSystemMetrics(SM_CYSCREEN) - height) >> 1); //指定窗口位置 glutInitWindowSize(width, height); //指定窗口大小 glutCreateWindow(title); glClearColor(1, 1, 1, 0.0); glShadeModel(GL_FLAT);}int main(int argc, char *argv[]){ initWindow(argc, argv, 500, 500, "Hermite"); puts("\n\t使用Hermite算法,用两顶点两控制点绘制三次曲线。"); puts("\t左键移动控制点,右键移动型值点"); glutDisplayFunc(myDisplay); glutReshapeFunc(Reshape); glutMouseFunc(mouse); glutMotionFunc(motion); glutMainLoop(); return 0;}
阅读全文
0 0
- OpenGL实现Hermite算法绘制三次曲线
- 三次 Hermite曲线算法
- MFC下实现图形学之Hermite、Bezier曲线的绘制
- OpenGL: 绘制三次哈密特曲线
- OpenGL: 鼠标动态绘制三次Bezier曲线
- OpenGL: OpenGL下通过鼠标动态绘制三次Bezier曲线
- OpenGL实现 贝塞尔三次方曲线
- OpenGL实现摄像机漫游/三次贝塞尔曲线
- [转载] Hermite 与 Bezier 曲线的绘制
- Hermite 与 Bezier 曲线的绘制
- Hermite与Bezier曲线绘制方法研究
- OpenGL下通过鼠标动态绘制三次Bezier曲线
- OpenGL下通过鼠标动态绘制三次Bezier曲线 .
- 开始学习opengl以及绘制三次Bezier曲线
- OpenGL 三次Bezier曲线
- hermite曲线
- 分段三次Hermite插值Matlab实现
- OpenGL曲线绘制:线段
- Linux 下设置IP、网关、DNS
- [david]unity3d绘制调用批处理(draw call batching)
- ArcGIS API for JavaScript 实现point multipoint line polyline cirle等graphics的绘制
- 使用 Spring Boot 快速构建 Spring 框架应用
- 环信笔记
- OpenGL实现Hermite算法绘制三次曲线
- 教您用数学课件制作工具画椭圆
- 大众点评接口优惠卷,订单对接
- myeclipse一直Building workspace
- Linux ALSA声卡驱动之一:ALSA架构简介
- 【zookeeper】Zookeeper 开发者手册
- Singleton(单例模式)的使用和测试效率
- linux文件分割(将大的日志文件分割成小的)
- Android生成帮助文档