opengl 区域填充之种子填充线扫描法
青岚影视 www.qldyy.net
在事先画好的一个区域内,使用区域填充之种子填充线扫描法将其填充完毕。同时带有鼠标和键盘事件,并添加了菜单。对于存在的改变窗口大小程序会出现问题还没有很好的解决,只是仅仅将窗口大小固定住了,不能随意改变大小。不对的地方,还请大家多多指正,希望与大家多交流哦。
#include <GL/glut.h>
#include <stdio.h>
//#include <conio.h>
//#include <dos.h>
#include <windows.h>
const int length = 3;
const int coord = 2;
const int num = 10;
int stack_top;
int stack[10000];
int fill = 0; /* fill flag */
// 长宽比受到限制,就现在而言只能是宽要大于长,原因有两个,
//一个为(画点)原点位置不正确,另一个是围城区域的线条宽度太小
int Wheight = 200;
int Wwidth = 200;
int control = 0;
typedef float Color[length];
typedef int POI[coord];
Color newColor = {1.0f, 1.0f, 0};
// 背景颜色
Color oldColor = {1.0f, 0, 0};
// 函数调用前至少要先声明,或者直接定义到掉用地之前
int stackPop()
{
int val;
val = stack[stack_top];
stack_top = stack_top-1;
return val;
}
void stackPush(int p_xy)
{
stack_top += 1;
stack[stack_top] = p_xy;
}
int isStackEmpty()
{
if(stack_top>0)
return 1;
else
return 0;
}
void setStackEmpty()
{
int i;
for(i=0; i<=stack_top; i++)
stack[i]=0;
stack_top=0;
}
//画点函数
void setPixel(float x, float y, Color color)
{
glBegin(GL_POINTS);
glColor3f(color[0], color[1], color[2]);
glVertex2f(x, y);
glEnd();
}
//颜色判定函数,颜色相同的话返回1,不相同的话则返回0
int judgeColor(float x, float y, Color color)
{
Color tmp;
int res = 1;
glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT, tmp);
for (int i = 0; i < length; i++)
{
if(color[i] != tmp[i])
{
res = 0;
//printf("%f,%f",x,y);
}
}
return res;
}
// 填充函数(从最下侧向上填充)
void floodFill(int x, int y, Color newColor, Color oldColor, int dir){
int xl, xr, x0, xnextspan;
bool spanNeedFill;
//将栈清空
setStackEmpty();
//种子入栈
stackPush(x);
stackPush(y);
while(isStackEmpty() != 0)
{
//栈顶出栈,注意出栈顺序
y = stackPop();
x = stackPop();
//printf("nihao1");
setPixel(x, y, newColor);
x0 = x+1;
while(judgeColor(x0,y,oldColor) == 1) //向右填充
{
//printf("nihao2");
setPixel(x0,y,newColor);
x0++;
}
xr = x0-1; //最右元素
x0 = x-1; //恢复到起始元素
while(judgeColor(x0,y,oldColor) == 1) //向左填充
{
setPixel(x0, y, newColor);
x0--;
}
xl=x0+1; //最左元素
//处理下面一条扫描线
x0=xl;
y=y+dir;
if (isStackEmpty() == 0)
{
}
// 从最左到最右均无oldColor元素将不再压栈
while (x0<=xr)
{
spanNeedFill=FALSE;
while (judgeColor(x0,y,oldColor) == 1)
{
if (spanNeedFill==FALSE)
spanNeedFill=TRUE;
x0++;
}
// 将元素压栈
if(spanNeedFill)
{
if (x0==xr)
{
stackPush(x0);
stackPush(y);
}
else
{
stackPush(x0-1);
stackPush(y);
}
spanNeedFill=FALSE;
}
xnextspan=x0;
// 立即跳出循环
while(judgeColor(x0,y,oldColor)!=1 && x0<xr) x0++;
// 如果是最边上的
if (xnextspan==x0)
x0++;
}
}
}
void drawLine()
{
glBegin(GL_LINE_LOOP);
glVertex2i(130, 130);
glVertex2i(60, 130);
glVertex2i(60, 10);
glVertex2i(130, 10);
glEnd();
glFlush();
}
// 界面刷新
void refresh()
{
glClearColor(1.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
drawLine();
}
void myDisplay(void)
{
glClearColor(1.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
// 单色方式
glShadeModel(GL_FLAT);
// 设置点的大小
//glPointSize(100.0f);
// 设置视口
//glViewport(1.0f, 1.0f, 600, 400);
glOrtho(-0.5f, Wwidth, -0.5f, Wheight, -200, 200);
// 设置点的颜色
glColor3f(0.0, 1.0f, 0.0f);
glLineWidth(2);
//glBegin(GL_POINTS);
// 绘制“点”的原点是在窗口正中间
drawLine();
//glPopAttrib();
}
// 鼠标左键事件
void mouse(int btn, int state, int x, int y)
{
// x,y为窗口左上角为原点的鼠标位置
if(btn==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
{
floodFill(x, Wheight-y, newColor, oldColor, 1);
floodFill(x, Wheight-y, newColor, oldColor, -1);
printf("开始填充");
//printf("%d,\t%d",x,y);
}
}
// 鼠标右键事件
void right_menu(int id)
{
if(id == 2) exit(0);
else if (id == 0)
{
floodFill(61, 129, newColor, oldColor, -1);
printf("开始绘制");
}
else{
// myDisplay();
refresh();
}
}
// 键盘事件
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
// Esc键退出
exit(0);
break;
default:
break;
}
}
/*
//换算比例
void changeSize(int w, int h) {
// 防止除数即高度为0
// (你可以设置窗口宽度为0).
if(h == 0)
h = 1;
float ratio = 1.0* w / h;
// 单位化投影矩阵。
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// 设置视口大小为增个窗口大小
glViewport(0, 0, w, h);
// 设置正确的投影矩阵
gluPerspective(45,ratio,1,1000);
//下面是设置模型视图矩阵
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,5.0, 0.0,0.0,-1.0,0.0f,1.0f,0.0f);
}*/
void main()
{
int f_menu;
int gMainHandle;
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowSize(Wwidth, Wheight);
glutInitWindowPosition(100, 150);
gMainHandle = glutCreateWindow("Seed Fill");
glutSetWindow(gMainHandle);
HWND hwnd = FindWindow(NULL,"Seed Fill");
if( hwnd )
{
LONG style;
style = GetWindowLong(hwnd,GWL_STYLE);
style &= ~WS_THICKFRAME;
SetWindowLong(hwnd,GWL_STYLE,style);
}
f_menu = glutCreateMenu(right_menu);
glutAddMenuEntry("开始",0);
glutAddMenuEntry("清空",1);
glutAddMenuEntry("退出",2);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutDisplayFunc(&myDisplay);
//换算比例
//glutReshapeFunc(NULL);
glutMainLoop();
}
转载于:https://www.cnblogs.com/yxfcnbg/archive/2012/11/15/2772502.html
opengl 区域填充之种子填充线扫描法相关推荐
- 13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)
♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥ ...
- 【Algorithm】种子填充算法
转载:https://www.cnblogs.com/icmzn/p/5065306.html [平面区域填充算法]是计算机图形学领域的一个很重要的算法,区域填充即给出一个区域的边界 (也可以是没有边 ...
- 【OpenGL C++】画一个空心汉字和一个圆,并填充汉字(中点画线法,中点画圆法,种子填充法)
内容:画一个空心汉字和一个圆 设计一个画任意直线和圆的算法,可选所学的任一图形扫描转换算法(中点或bresenham算法),不能使用任何画线/画圆的API: 使用画线算法实现空心汉字的绘制,汉字必须为 ...
- 计算机图形学E4——OpenGL 区域种子填充
其他计算机图形学实验见 链接 系统递归栈太慢了,用stack或者queue会好一点,本质一样,都是bfs //DFS 系统递归栈//#include<iostream> //#includ ...
- 多边形区域填充算法--扫描线种子填充算法
分享一下我老师大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow http://bl ...
- 区域填充:扫描线种子填充和剖面线填充
#include "stdio.h" #include "graphics.h" #include "malloc.h" #include ...
- 连通域分析之种子填充法
一.连通域 需要了解连通域和两遍扫描法的可以看连通域分析之两遍扫描法(Two-Pass)这篇博文.我在里面已经介绍过了连通域的两种定义,这里就不再介绍.在此文中仍以4-邻域为例. 二.种子填充(区域填 ...
- c语言 连通域算法 递归,VC++ 6.0编写计算机图形学中的种子填充算法,想用递归的八向连通域,求助!...
VC++ 6.0编写计算机图形学中的种子填充算法,想用递归的八向连通域,求助!0 填充函数代码如下: void CComputerGraphicsView::PolygonFill2()//区域填充函 ...
- matlab中种子填充算法
因为作业要求用简单种子填充和线扫描填充,所以在网上找了一个用matlab写的简单种子填充算法. https://www.cnblogs.com/tiandsp/archive/2012/12/06/2 ...
最新文章
- MongoDB 3.4 复制集全量同步改进
- javascript去除首尾空白字符
- python三角形判断白盒测试的代码_进化的测试 软件测试,自动化测试,白盒测试,Python...
- Java调试器–权威的工具列表
- Python Configparser模块读取、写入配置文件
- Jackson第一篇【JSON字符串、实体之间的相互转换】
- Deal with relational data using libFM with blocks
- tcpdump高级过滤
- dhuacm出题网站搭建
- 6种摆脱百度竞价恶意点击的技巧
- VSCode无法跳转到外部函数定义
- xp安全模式下如何修复计算机,xp系统如何进入安全模式|进入安全模式修复系统...
- 安卓获取及监听手机网络状态
- XMind之快速上手
- psn请验证您不是机器人_PS4无法登陆PSN的解决办法
- 它来啦,它来啦!三子棋小游戏来啦!!!
- 2014-2015 少年辛苦终身事,莫向光阴惰寸功
- java中的this的用法_java中this的用法
- Memcache是什么
- 关于如何设置 Linux 的 IP配置
热门文章
- python具有伪代码的本质吗_Python的优点之一是具有伪代码的本质。( )_学小易找答案...
- C语言中return的各种用法
- html文档的基本类型,HTML(网页的文档类型介绍)
- 网络营销理论模型_网络营销:课堂笔记(第四章下)
- 光纤交换机产品功能介绍
- 工业级光纤收发器和协议转换器有什么区别呢?
- 百兆工业交换机与千兆工业交换机如何计算码率?
- 【渝粤教育】国家开放大学2018年春季 8634-22TAndroid智能手机编程 参考试题
- 【渝粤题库】广东开放大学 标准法律法规 形成性考核
- [渝粤题库]陕西师范大学《幼儿园社会教育》作业