其他计算机图形学实验见 链接

#include<gl/glut.h>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const float window_width = 800, window_height = 600;
const int d = 8;struct point
{float x, y;point() {}point(float xx, float yy):x(xx), y(yy) {}
};
vector<point> input_vertice;
vector<point> controlpoint;char OP;
float controlpoint_color[3] = { 1,0,0 };
float straightline_color[3] = { 0,1,0 };
float bezierline_color[3] = { 0,0,1 };void draw_a_point(float x, float y, float color[]);
void deCasteljau();
void mymouse(int button, int state, int x, int y);
void dragmouse(int x, int y);
void keyboard(unsigned char key, int x, int y);
int getdis(int x, int y);//获取离得最近的点int main(int argc, char* argv[])
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowPosition(50, 50);glutInitWindowSize(window_width, window_height);glutCreateWindow("de Casteljau 绘制bezier曲线");cout << "键盘点击p后,点击左键绘制控制点" << endl;cout << "键盘点击i后,插入控制点" << endl;cout << "键盘点击d后,移动控制点" << endl;cout << "键盘点击e后,点击鼠标左键删除控制点" << endl;cout << "按ESC退出" << endl << endl;glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0, window_width, 0, window_height);glClearColor(1, 1, 1, 1);glClear(GL_COLOR_BUFFER_BIT);glutMouseFunc(&mymouse);glutMotionFunc(&dragmouse);glutKeyboardFunc(&keyboard);glutMainLoop();return 0;
}void draw_a_point(float x, float y, float color[])
{glPointSize(3.0f);glBegin(GL_POINTS);glColor3fv(color);glVertex2f(x, y);glEnd();glFlush();
}int getdis(int x, int y)
{int ans = -1;float shortdis = 99999999;for (int i = 0; i < input_vertice.size(); i++){float dis = sqrt(pow(x - input_vertice[i].x, 2) + pow(y - input_vertice[i].y, 2));if (dis < shortdis && dis <= d){shortdis = dis;ans = i;}}return ans;
}int index1 = -1;
void mymouse(int button, int state, int x, int y)
{if (OP == 'p')//绘制控制点{int drag_point_index = -1;if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){int index = getdis(x, window_height - y);if (index == -1)//鼠标范围内没有控制点,新加操作点{draw_a_point(x, window_height - y, controlpoint_color);point p(x, window_height - y);input_vertice.push_back(p);cout << "新输入的控制点" << input_vertice.size() << ":(" << x << ", " << window_height - y << ")" << endl;}//把新的输入的控制点赋值给控制点数组controlpoint = input_vertice;if (input_vertice.size() >= 2)//大于等于两个点的时候,画bezier曲线,控制点留给bezier函数画deCasteljau();else              //小于两个点的时候,只画出控制点{glBegin(GL_LINE_STRIP);glColor3fv(straightline_color);for (int i = 0; i < input_vertice.size(); i++)glVertex2f(input_vertice[i].x, input_vertice[i].y);glEnd();glFlush();}//glutPostRedisplay();//}}if (OP == 'i')//插入控制点{//int index1 = -1;//不可以放在这里,否则会因为不断刷新导致判断up时候index恒等于-1if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){index1 = getdis(x, window_height - y);cout << "将插入新的控制点到 选中的控制点" << index1 << "前" << endl;}if (button == GLUT_LEFT_BUTTON && state == GLUT_UP && index1 != -1){input_vertice.insert(input_vertice.begin() + index1, point(x, window_height - y));//在下标pos前插入一个元素//cout << input_vertice.size() << endl;}//把新的输入的控制点赋值给控制点数组controlpoint = input_vertice;if (input_vertice.size() >= 2)//大于等于两个点的时候,画bezier曲线,控制点留给bezier函数画deCasteljau();else               //小于两个点的时候,只画出控制点{glBegin(GL_LINE_STRIP);glColor3fv(straightline_color);for (int i = 0; i < input_vertice.size(); i++)glVertex2f(input_vertice[i].x, input_vertice[i].y);glEnd();glFlush();}}if (OP == 'e'){if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)//删除控制点{int index = getdis(x, window_height - y);cout << "删除点" << index << endl;if (index != -1)//鼠标范围内有控制点了,可以删除,否则不做操作{vector<point>::iterator it = input_vertice.begin();cout << (*(it + index)).x << " " << (*(it + index)).y << endl;input_vertice.erase(it + index);}elsecout << "没有可以删除的点" << endl;glClear(GL_COLOR_BUFFER_BIT);//把新的输入的控制点赋值给控制点数组controlpoint = input_vertice;//bezier曲线deCasteljau();}}
}void dragmouse(int x, int y)
{int index = getdis(x, window_height - y);if (OP == 'd' && index != -1)//鼠标范围内有控制点了,可以拖动{cout << "修改控制点" << input_vertice.size() << ":(" << input_vertice[index].x << ", " << input_vertice[index].y << ")" << endl;input_vertice[index].x = x;input_vertice[index].y = window_height - y;//把新的输入的控制点赋值给控制点数组controlpoint = input_vertice;if (input_vertice.size() >= 2)//大于等于两个点的时候,画bezier曲线,控制点留给bezier函数画deCasteljau();else               //小于两个点的时候,只画出控制点{glBegin(GL_LINE_STRIP);glColor3fv(straightline_color);for (int i = 0; i < input_vertice.size(); i++)glVertex2f(input_vertice[i].x, input_vertice[i].y);glEnd();glFlush();}}
}void keyboard(unsigned char key, int x, int y)
{if (key == 27)exit(0);if (key == 'p')//画点{OP = 'p';cout << "请点击鼠标左键,开始绘制控制点以及bezier曲线" << endl;}if (key == 'd')//拖动端点{OP = 'd';cout << "请按住端点拖动" << endl;}if (key == 'i')//插入控制点{OP = 'i';cout << "请点击一个已有的控制点按住不放,松开位置为新插入顶点的位置。新插入的顶点位于点击的顶点之前。 "<< endl;}if (key == 'e'){OP = 'e';cout << "鼠标左键点击要删除的点" << endl;}
}void deCasteljau()
{vector<point> bezierpoint;int n = controlpoint.size();for (double t = 0.0; t <= 1.0; t += 0.005 / n)//保证点的数量足够多,使曲线更加圆滑{for (int i = 1; i < n; i++)//控制每走一轮,控制点都会少 1{for (int j = 0; j < n - i; j++)//每走一轮,控制点都会少 1{if (i == 1)//迭代第一轮必须是输入的那几个控制点,so,,不可以只用一个controlpoint,input_vertice也有用。。。。{controlpoint[j].x = (1 - t) * input_vertice[j].x + t * input_vertice[j + 1].x;controlpoint[j].y = (1 - t) * input_vertice[j].y + t * input_vertice[j + 1].y;continue;}else{controlpoint[j].x = (1 - t) * controlpoint[j].x + t * controlpoint[j + 1].x;controlpoint[j].y = (1 - t) * controlpoint[j].y + t * controlpoint[j + 1].y;}}}//cout << "控制点数量=" << controlpoint.size() << endl;一直是点的数目,因为之前直接存在这个里面了,但是有用的只有下标为1的才有用bezierpoint.push_back(controlpoint[0]);//把最后一个在bezier曲线上的点保存起来,最后链接在一起即为bezier曲线}glClear(GL_COLOR_BUFFER_BIT);//清空屏幕上上一次的bezier曲线//输出新的所有的控制点glBegin(GL_LINE_STRIP);glColor3fv(straightline_color);for (int i = 0; i < input_vertice.size(); i++)glVertex2f(input_vertice[i].x, input_vertice[i].y);glEnd();glFlush();//画出bezier曲线glLineWidth(3.0f);glBegin(GL_LINE_STRIP);glColor3fv(bezierline_color);for (int i = 0; i < bezierpoint.size(); i++)glVertex2f(bezierpoint[i].x, bezierpoint[i].y);glEnd();glFlush();
}

计算机图形学E10——Bezier曲线相关推荐

  1. 计算机图形学:Bezier曲线的绘制

    1.实验目的 掌握Bezier曲线的定义原理及绘制过程 定义: 贝塞尔曲线(Bezier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线.一般的矢量图形软件通过它来精确画出 ...

  2. 【CAD算法】【计算机图形学】Bezier贝塞尔曲线生成程序(python/numpy实现)[1]

    整个项目,从Bezier曲线的创建,到Coons Patch曲面的实现,再到网格的实现和优化,还有最后对表面的光顺,链接如下: [CAD算法][计算机图形学]Bezier贝塞尔曲线生成程序(pytho ...

  3. 计算机图形学中的曲线问题

    文章目录 免责 前言 拉格朗日插值多项式 第一步:得到一个基函数 第二步:得到所有基函数 第三步:对所有基函数进行线性组合 举例验证 拉格朗日插值曲线绘制实践 三次埃尔米特插值多项式 第一步:得到第一 ...

  4. 计算机图形学中的曲线问题——贝塞尔曲线的绘制

    贝塞尔曲线的绘制 由于 CSDN 的博客修改字数的限制,我们不得不将这一部分放到一个新的博客中.原文详见: GGN_2015 计算机图形学中的曲线问题 贝塞尔曲线的几何作图法 在上面介绍儿时的回忆中, ...

  5. 计算机图形学空间曲线,课程追忆之《计算机图形学》【曲线曲面篇】

    大家好,距离上一篇博文将近一个月,时间过得好快,原本计划周更的,后面推到半月跟,实际到现在是月更,每次在准备写点什么的时候,都会被一些杂乱的事物打扰,哎,重度拖延症.懒癌晚期- 继上次述说了<计 ...

  6. [计算机图形学]几何:曲线和曲面(前瞻预习/复习回顾)

    一.曲线 1.Bézier Curves-贝塞尔曲线 贝塞尔曲线也是一种显式的几何表示方法.贝塞尔曲线定义了一系列的控制点,致使确定满足这些控制点关系的唯一一条曲线:如上图定义的贝塞尔曲线满足 起始点 ...

  7. 计算机图形学Bezier曲线试题,《计算机图形学》试题-C卷及参考答案

    计算机图形学试题 C 一.选择题(20分) 1.计算机图形显示器一般使用什么颜色模型?(A ) A. RGB B. CMY C. HSV D. HLS 2.分辨率为1024×1024的显示器各需要多少 ...

  8. 计算机图形学 实验7 《复杂图形绘制-Bezier曲线与Hermite曲线》

    计算机图形学 实验7 <复杂图形绘制-Bezier曲线与Hermite曲线> 一.实验目的 学习样条曲线的绘制. 二.实验内容 1.绘制Bezier曲线: 2.绘制Hermite曲线. 三 ...

  9. 计算机图形学作业( 七):利用 OpenGL 绘制 Bezier 贝塞尔曲线

    计算机图形学作业( 七):利用 OpenGL 绘制 Bezier 贝塞尔曲线 Bezier 曲线原理 OpenGL 实现思路 捕获鼠标点击时的坐标 根据顶点画出连续的线段 根据顶点画出 Bezier ...

最新文章

  1. c语言延时函数_介召几个frida在安卓逆向中使用的脚本以及延时Hook手法
  2. 一个包从服务器到达客户端
  3. 一份超级全面的PHP面试题
  4. SpringCloud之Hystrix
  5. 解决dubbo-admin管控台不能显示服务的问题
  6. 机器学习_机器不学习:从Spark MLlib到美图机器学习框架实践
  7. python之新式类与经典类
  8. 【计算机视觉】基于OpenCV的人脸识别
  9. 去年的今天,我和小叶子完成了《阿猫阿狗2》,缅怀一下。
  10. 米斯特白帽培训讲义(v2)漏洞篇 Web 中间件
  11. 机器学习技法总结(六)Decision Tree Hypothesis
  12. 设置tomcat内存
  13. 独立站运营成败,7个细节不可忽视
  14. 如何将超大文件传输给别人,超大文件如何传输
  15. 计算方法(三)分段线性插值和Hermite插值
  16. 原子操作:CAS、TAS、TTAS、FAA浅析
  17. 《Objective-C 程序设计(第4版)》图书信息
  18. 如何清除/删除最近的文档历史记录?
  19. 理解HTML HTTP API 和URL
  20. IT人士常喝点菊花茶泡枸杞

热门文章

  1. 最大熵学习笔记(三)最大熵模型
  2. IOS APP 国际化(实现不跟随系统语言,不用重启应用,代码切换stroyboard ,xib ,图片,其他资源)...
  3. MC新手入门(二十八)------ 顺序结构程序
  4. jqGrid专题:jqGrid原理
  5. 用Javascript实现面向对象编程(封装,抽象,继承,多态)
  6. 关于SSH的分工(网友讨论集合贴)
  7. 【20090702-03】ArcEngine的类库介绍(转)
  8. leetcode 92 python
  9. CCF202006-1 线性分类器
  10. hbuilderx设置新建jsx后缀名_TypeScript编写前基本配置操作