内容:画一个空心汉字和一个圆

设计一个画任意直线和圆的算法,可选所学的任一图形扫描转换算法(中点或bresenham算法),不能使用任何画线/画圆的API;
使用画线算法实现空心汉字的绘制,汉字必须为4划以上;
使用你设计的画圆算法绘制这个空心字的外接圆;
设计一种填充算法实现汉字的填充;

1.中点画圆法

生成八分之一圆,其他部分可以通过一系列的简单反射变换得到。
(1)已知圆心在原点的圆上的一点的(x,y),函数circlePlotPoint()
根据对称性得到8个对称点,分别为(y,x),(y,-x),(x,-y),(-x,-y),(-y,-x),(-y,x),(-x,y);
(2)函数circleMidpoint()
如果此时点的位置为(X1,Y1),那么下一个点位置只可能是(X1+1,Y1)或者(X1+1,Y1-1),根据判别式d:
d<0,应取(X1+1,Y1)为下一个点,d=d+2*x+3;
d>=0应取(X1+1,Y1-1)为下一个点,d=d+(x-y)+5;

2.中点画线法

(1)强制起点在终点左侧,如果不是的话,则交换两点;
(2)函数MidPoint()
分为四种情况,斜率0=<k<=1、斜率1<k、斜率-1 =<k<0和斜率k<-1时,根据每种情况下的判别式d,判断下一个点的位置;
(3) 函数setPoint()
每画一个点,就将其对应的flag置为1,说明此点已填充,则边界上所有的点的flag都已经置为1,为填充时判断边界做了准备。

3.种子填充法

函数Flood()
(1)先将种子像素压入栈;
(2)如果栈不为空,栈顶像素出栈;
(3)按左上右下的顺序搜索与出栈像素相邻的4个像素,若像素的flag值是1,说明该像素已填充,结束本次循环;若像素的flag值是0,说明该像素未填充,将该像素入栈。

#include <gl/glut.h>
#include <math.h>
#include <windows.h>
#include <iostream>
#include <vector>
#include <stack>
#include <stdlib.h>using namespace std;
int xc, yc, r;
int flag[2000][2000] = { 0 };
int winwidth = 500, winheight = 500;//窗口长宽//声明一个类
class screenPt
{public:screenPt(){x = y = 0;}void setCoords(GLint xCoordValue, GLint yCoordValue) {x = xCoordValue;y = yCoordValue;}GLint x, y;
};void init() {glClearColor(0, 0, 0, 0);//设置绘制窗口颜色为黑色glClear(GL_COLOR_BUFFER_BIT);//清除窗口显示内容/*设置为投影类型模式和其他观察参数*/glPointSize(1.0f);glColor3f(1.0, 0.0, 0.0);//设置颜色为红glMatrixMode(GL_PROJECTION);glLoadIdentity();//左上角坐标为(0,0),长宽为500gluOrtho2D(0, winwidth, winheight, 0);
}//画点
void setPixel(GLint xCoord, GLint yCoord) {glBegin(GL_POINTS);glVertex2i(xCoord, yCoord);glEnd();
}//八个对称点
void circlePlotPoints(GLint xc, GLint yc, screenPt circpt) {setPixel(xc + circpt.x, yc + circpt.y);setPixel(xc - circpt.x, yc + circpt.y);setPixel(xc + circpt.x, yc - circpt.y);setPixel(xc - circpt.x, yc - circpt.y);setPixel(xc + circpt.y, yc + circpt.x);setPixel(xc - circpt.y, yc + circpt.x);setPixel(xc + circpt.y, yc - circpt.x);setPixel(xc - circpt.y, yc - circpt.x);
}/*中心画圆法*/
void circleMidpoint(GLint xc, GLint yc, GLint radius) {glClear(GL_COLOR_BUFFER_BIT);//清除窗口显示内容screenPt circpt;//创建一个对象GLint p = 1 - radius;circpt.setCoords(0, radius);//显示圆弧上的八个点circlePlotPoints(xc, yc, circpt);while (circpt.x < circpt.y) {circpt.x++;if (p < 0) {p += 2 * circpt.x + 3;}else {circpt.y--;p += 2 * (circpt.x - circpt.y) + 5;}//显示圆弧上的八个点circlePlotPoints(xc, yc, circpt);}}class Point {public:Point();Point(GLint  _x, GLint _y) {x = _x;y = _y;}GLint x, y;
};// 种子填充
void Flood(int a, int b)   {//      (x - 1, y);  //left//       (x, y - 1);  //up//     (x + 1, y);  //right//     (x, y + 1);  //downint dx[4] = { -1, 0, 1,0 };int dy[4] = { 0, -1, 0,1 };stack<Point> q;q.push(Point(a, b));while (q.size()) {auto t = q.top();q.pop();for (int i = 0; i < 4; i++) {int n = t.x + dx[i];int m = t.y + dy[i];//cout << m << "  " << n << endl;if (flag[n][m])continue;flag[n][m] = 1;glBegin(GL_POINTS);glColor3f(255, 255, 0);glVertex2f(n ,m );glEnd();q.push(Point(n, m));glFlush();}}
}//画线之间的点
void setPoint(GLint x,GLint y) {glBegin(GL_POINTS);glColor3f(249, 216, 118);//glVertex2f(x, y);//指定顶点的值flag[(int)(x )][(int)(y )] = 1;glEnd();
}void MidPoint() {//将点的信息放到line中保存vector<Point> line;//第一部分连接点 4line.push_back(Point(240, 150));line.push_back(Point(255, 150));line.push_back(Point(255, 150));line.push_back(Point(265, 165));line.push_back(Point(250, 165));line.push_back(Point(265, 165));line.push_back(Point(240, 150));line.push_back(Point(250, 165));第2部分连接点 22line.push_back(Point(200, 185));line.push_back(Point(215, 185));line.push_back(Point(200, 185));line.push_back(Point(200, 220));line.push_back(Point(200, 220));line.push_back(Point(215, 220));line.push_back(Point(215, 210));line.push_back(Point(215, 220));line.push_back(Point(215, 185));line.push_back(Point(215, 190));line.push_back(Point(215, 190));line.push_back(Point(305, 190));line.push_back(Point(305, 185));line.push_back(Point(305, 190));line.push_back(Point(305, 185));line.push_back(Point(325, 185));line.push_back(Point(325, 185));line.push_back(Point(325, 220));line.push_back(Point(310, 220));line.push_back(Point(325, 220));line.push_back(Point(310, 210));line.push_back(Point(310, 220));line.push_back(Point(215, 210));line.push_back(Point(310, 210));第3部分连接点  36line.push_back(Point(180,240));line.push_back(Point(240, 240));line.push_back(Point(180, 240));line.push_back(Point(180, 250));line.push_back(Point(240, 240));line.push_back(Point(250, 225));line.push_back(Point(250, 225));line.push_back(Point(270, 225));line.push_back(Point(260, 240));line.push_back(Point(270, 225));line.push_back(Point(260, 240));line.push_back(Point(345, 240));line.push_back(Point(180, 250));line.push_back(Point(235, 250));line.push_back(Point(250, 250));line.push_back(Point(290, 250));line.push_back(Point(210, 290));line.push_back(Point(235,250));line.push_back(Point(210, 290));line.push_back(Point(230, 300));line.push_back(Point(190, 340));line.push_back(Point(230, 300));line.push_back(Point(190, 340));line.push_back(Point(195, 350));line.push_back(Point(195, 350));line.push_back(Point(245, 310));line.push_back(Point(245, 310));line.push_back(Point(320, 340));line.push_back(Point(320, 340));line.push_back(Point(325, 330));line.push_back(Point(265, 300));line.push_back(Point(325, 330));line.push_back(Point(265, 300));line.push_back(Point(310, 250));line.push_back(Point(310, 250));line.push_back(Point(345, 250));line.push_back(Point(345, 240));line.push_back(Point(345, 250));第四部分连接点 4line.push_back(Point(235, 285));line.push_back(Point(250, 250));line.push_back(Point(235, 285));line.push_back(Point(250, 290));line.push_back(Point(250, 290));line.push_back(Point(290, 250));//中点画线法for (int i = 0; i < line.size() - 1; i += 2) {double x0, y0, x1, y1;x0 = line[i].x;y0 = line[i].y;x1 = line[i + 1].x;y1 = line[i + 1].y;double A = y0 - y1;double B = x1 - x0;double k = -1 * (A / B);double t;double d;//强制起点在终点左侧,如果不是的话,则交换两点;if (x1 < x0) {t = x1;x1 = x0;x0 = t;t = y1;y1 = y0;y0 = t;}//斜率0=<k<=1if (k >= 0 && k <= 1) {d = (2 * A + B);while (x0 != x1) {setPoint(x0, y0);if (d <= 0) {x0 += 1;y0 += 1;d += (2 * (A + B));}else {x0++;d += (2 * A);}//glFlush();}}//斜率大于1if (k > 1) {d = (A + 2 * B);while (y0 != y1) {setPoint(x0, y0);if (d < 0) {y0 += 1;d += (2 * B);}else {y0 += 1;x0 += 1;d += (2 * (A + B));}//glFlush();}}//斜率大于等于-1 小于0时if (k >= -1 && k < 0) {d = (2 * A - B);while (x0 != x1) {setPoint(x0, y0);if (d < 0) {x0 += 1;d += (2 * A);}else {x0 += 1;y0 -= 1;d += (2 * (A - B));}//glFlush();}}//斜率小于-1时if (k < -1) {d = (int)(A - 2 * B);while (y0 != y1) {setPoint(x0, y0);if (d < 0) {y0 -= 1;x0 += 1;d += (2 * (A - B));}else {y0 -= 1;d -= (2 * B);}//glFlush();}}}//调用种子填充setPixel(210, 200);Flood(210,200);setPixel(245, 155);Flood(245, 155);setPixel(181, 241);Flood(181, 241);
}void display() {circleMidpoint(250, 250, 120);MidPoint();//glFlush();
}int main(int argc, char** argv) {glutInit(&argc, argv);//初始化glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//设置绘制模式glutInitWindowPosition(400, 150); //设置窗口的位置glutInitWindowSize(winwidth, winheight);glutCreateWindow("绘制并填充”安“"); //创建窗口并赋予titleinit();glutDisplayFunc(display);glutMainLoop();}

结果:

【OpenGL C++】画一个空心汉字和一个圆,并填充汉字(中点画线法,中点画圆法,种子填充法)相关推荐

  1. 输入一个菱形的内高和外高,画出一个空心菱形

    欢迎交流,共同进步. 题目为:已知内层和外层菱形的高度,输出一空心菱形 使用自己的语言描述:使用C语言画出一个菱形,输入上三角高内层菱形为L1,外高为L2,输入需要保证数值为正整数,且为奇数. 此处我 ...

  2. opengl如何画出一个球_少儿美术绘画教程:毛线球

    小朋友们,你们平时画画有没有遇到过没有灵感的时候,面对画纸却不知道画些什么呢?今天我们来介绍一种创意思维,叫发散性思维.以一个毛线球为出发点.通过毛线球,我们可以想到圆球,通过圆球我们可以想到圆形. ...

  3. ROC曲线是通过样本点分类概率画出的 例如某一个sample预测为1概率为0.6 预测为0概率0.4这样画出来,此外如果曲线不是特别平滑的话,那么很可能存在过拟合的情况...

    ROC和AUC介绍以及如何计算AUC from:http://alexkong.net/2013/06/introduction-to-auc-and-roc/ ROC(Receiver Operat ...

  4. oc 画一个圆弧_UG建模一个蜗杆的方法,纯手工建模无插件

    上次我们画了一个蜗杆,今天就来建模一个涡轮模型,也是非常简单. 这次还是无尺寸的随意建模,做出这么一个涡轮,来看看建模方法吧! 1 首先在XY平面上绘制一个直径100的圆,上下拉伸10mm 2 对圆柱 ...

  5. lisp画弯箭头_在CAD中直接画箭头的命令的一个方法

    在CAD中直接画箭头的命令的一个方法!!! 众所周知,在天正中可直接绘制箭头,而在AutoCAD中不得.最近我发现一个在命令行直接输入命令就可画出你想要的尺寸的箭头的方法,具体实施如下: 1.首先拷贝 ...

  6. 把一个用阿拉伯数字表示的正整数转换成汉字大写表示

    一个面试题,考查面试者的逻辑思维能力,考虑的问题很多,把一个用阿拉伯数字表示的正整数转换成汉字大写表示 这里代码没有考虑非法输入,但如果是面试.最好跟面试官交流清楚,展现你考虑问题全面,写出的代码鲁棒 ...

  7. 一个汉字属于一个字符吗?

    是 计算机中无论什么数据,都是二进制,字符是根据编码表把字节解码成字符,英文字符都是字母,所以一个字节足以表示,而我天朝文字博大精深,一个字节表示不了,所以在GBK中用两个字节来表示一个字符(当然在其 ...

  8. 下面是以十六进制格式存储的一个 UDP 首部:~~~TCP连接使用1000字节的窗口值,而上一次的确认号是22001~~那么下一个报文段的序号是否就是 x + 1 呢?在本题中列出的 8 种情况下,画

    5-10 试说明运输层中伪首部的作用 用于计算运输层数据报校验和 5-11 某个应用进程使用运输层的用户数据报UDP,然而继续向下交给IP层后,又封装成IP数据报.既然都是数据报,可否跳过UDP而直接 ...

  9. 猜灯谜_全排列板子题(A 村的元宵节灯会上有一迷题: 请猜谜 × 请猜谜 = 请边赏灯边猜 小明想,一定是每个汉字代表一个数字,不同的汉字代表不同的数字。 请你用计算机按小明的思路算一下,然后)

    题目描述 A 村的元宵节灯会上有一迷题: 请猜谜 × 请猜谜 = 请边赏灯边猜 小明想,一定是每个汉字代表一个数字,不同的汉字代表不同的数字. 请你用计算机按小明的思路算一下,然后提交"请猜 ...

最新文章

  1. stackoverflow国内被墙的打开办法
  2. linux非lvm分区在线扩容,怎么给不是LVM的根分区扩容
  3. Django (auth模块、User对象、用户认证、线上-用户认证)
  4. java游戏怎么导入jme3,Java Camera.getProjectionMatrix方法代码示例
  5. Linux疑难杂症解决方案100篇(二十)-万字长文带你读懂正则表达式(建议收藏)
  6. python psycopg2_如何在Python上用“pip”安装psycopg2?
  7. org.hibernate.InvalidMappingException: Could not parse mapping document from resource
  8. JAVA入门级教学之(整数型)
  9. Web前端笔记-element ui中table中禁止换行,使用...进行省略
  10. 木兰编程语言重现:引用本地木兰模块;模拟凑十法加法
  11. 理解点击屏幕的事件响应---对UIView的hitTest: withEvent: 方法的理解
  12. linux php源码安装mysql_linux源码安装mysql5.7
  13. nvm装node npm
  14. css如何将图片调成合适大小,如何利用CSS自动调整图片的大小
  15. 雅思作文模板.html,雅思写作模板必看范文
  16. 云服务赛道竞速,谁是云背后的力量?
  17. studio one机架效果包
  18. 快速得到Word2007的Docx或Docm文档中的图片
  19. flash 元件修改父级界面里面的元件属性
  20. SpringCloud 第八期 Sentinel 熔断限流

热门文章

  1. 中国地质大学计算机学院保研率,北京高校保研率、考研率排行榜
  2. 重庆微企获5000万元风投-平板电脑和手机菜单系统-家庭智能信息终端
  3. 马云为何放得下辛苦创立的“阿里帝国”?
  4. the security of smart contract- 2
  5. 如何修正步行动画中的膝跳问题(Knee Popping Issue)
  6. Topaz Video Enhance Al for mac(视频无损放大软件)
  7. makefile文件:编译工程文件
  8. 2017年的最后一天
  9. 对未来的一些规划和想法
  10. C语言大数相乘(整形)