C语言实现的扫描线种子填充算法
来源:互联网 发布:不来也不去好难唱 知乎 编辑:程序博客网 时间:2024/04/29 13:28
/***************************************************************
本程序实现区域填充功能,首先输入多边形顶点的个数,回车,
然后依次输入各顶点的坐标格式如下:100,123回车
一定要在中间用逗号隔开噢,输完最后一个点后,屏幕上会依次
画出各条边,最后填充满.
程序还不完善,比如颜色值应该用变量表示以易于修改,画多边形和求种子点
应该做成独立的函数等等,以后再做上吧,这是细节的问题
作者:曹欣
学号:2003378314
班级:计应0301
******************************************************************/
#include <graphics.h>
#include <stdio.h>
#include <alloc.h>
#include <dos.h>
#include <conio.h>
//creat a stack
struct stack_node
{
int x;
int y;
struct stack_node *next;
};
typedef stack_node stack_list;
typedef stack_list *link;
link stack = 0;
//push an element
void push(int xx,int yy)
{
link new_node;
new_node=(stack_list *)malloc(sizeof(stack_list));
new_node->x=xx;
new_node->y=yy;
new_node->next=stack;
stack=new_node;
}
//pop an element
void pop(int &xx,int &yy)
{
link top;
top=stack;
xx=stack->x;
yy=stack->y;
stack=stack->next;
free(top);
}
//fill the plot
void fill(int x,int y)
{
int x0,y0,xl,xr,xlold,xrold;/*x0,y0用来标记x,y的值,xl记录x的最左值,xr记录x的最右值*/
int go=0,go2=0;
int i=0;
push(x,y);//种子像素入栈
while(stack!=0)//如果栈不空则循环,stack==0表示栈空
{
go=0;//go 只是一个标记
pop(x,y);
putpixel(x,y,4);
x0=x+1;
while(getpixel(x0,y)!=4)//fill right 填充右边
{
putpixel(x0,y,4);
x0=x0+1;
}
xr=x0-1;//记录最右值
xrold=xr;//再记录一次最右值,以备后用
x0=x-1;
while(getpixel(x0,y)!=4)//fill right 填充左边
{
putpixel(x0,y,4);
x0=x0-1;
}
xl=x0+1;//记录最左值
xlold=xl;//再记录一次最左值,以备后用
y0=y+1;//go up 向上移一条扫描线
go2=0;//go2 也只是一个用来标记的变量
while(xr>xl&&go==0)//查找上一条线的最右值,并记录为xr
{
if(getpixel(xr,y0)==4)
{
xr=xr-1;
}
else
{
go=1;//若go=1这句执行的话就说明找到了最右值,并在while中的go==0中判断并退出while
}
}
while(xl<xr&&go2==0)//查找上一条线的最左值,并记录为xl
{
if(getpixel(xl,y0)==4)
xl=xl+1;
else
go2=1;//go2=1这句执行就说明找到了最左值,并在此while中的go2==0中退出while
}
if(go==1&&go2==1)//如果找到了最左值各最右值,则执行下面的语句
{
push(xr,y0);//先将上一条线上的最右点作为种子点入栈
for(i=xl;i<xr;i++)//从最左到最右循环,在每个连续区间上找一个种子点入栈
{
if(getpixel(i,y0)!=4)//如果不是边界点,什么也不做
{
}
else if(getpixel(i-1,y0)!=4)//如果是边界点,则看它左边的点是不是边界点,如果不是,则入栈
{
push(i-1,y0);
}
}
}
y0=y-1;//go down;//向下移一条扫描线
go=0;
go2=0;
xl=xlold;//还原最左,最右
xr=xrold;
while(xr>xl&&go==0)//找下一条线的最右
{
if(getpixel(xr,y0)!=4)
{
go=1;
}
else
{
xr--;
}
}
while(xl<xr&&go2==0)//找下一条线的最左
{
if(getpixel(xl,y0)!=4)
go2=1;
else
xl++;
}
if(go==1&&go2==1)//如果找到最左和最右,则执行
{
//push(xl,y0);
push(xr,y0);
for(i=xl;i<=xr;i++)
{
if(getpixel(i,y0)!=4)
{
}
else if(getpixel(i-1,y0)!=4)
{
push(i-1,y0);
}
}
}
}
}
void main()
{
void fill(int x,int y);
int gdriver,gmode;/*显示模式*/
int i,j;
int n,px,py,px0,py0,px1,py1;
int ya=0,yi=getmaxy();
printf("pleas input the number of the top points:");
scanf("%d",&n);
for(i=0;i<n;i++)//从键盘接受各顶点的坐标,依次入栈,并记录最大Y值和最小Y值
{
printf("please input the coordinate of the points--like:100,200 :");
scanf("%d,%d",&px,&py);
if(ya<py)
ya=py;//ya是最大Y值
if(yi>py)
yi=py;//yi是最小Y值
push(px,py);
}
detectgraph(&gdriver,&gmode);
initgraph(&gdriver,&gmode,"c:/bc31/bgi");
setbkcolor(0);
cleardevice();
setcolor(4);
pop(px0,py0);//输入的最后一个顶点出栈
px=px0;
py=py0;//记录最后一个顶点
//draw the plot
while(stack != 0)
{
pop(px1,py1);
line(px0,py0,px1,py1);
px0=px1;
py0=py1;
delay(500);
}
line(px0,py0,px,py);//依次画线,画出多边形
//画完多边形后,栈为空
//find the y value
j=(ya+yi)/2;//找Y的中间值,就是第一个种子点的Y值
i=0;
n=0;//记录入栈个数
//find the seed element
while(i<getmaxx()&&n!=2)//按X值从0到X最大值依次查找,并在入栈个数为2的时候退出
{
if(getpixel(i,j)==4)//如果是多边形上的点,则入栈,用n记录入栈的个数
{
push(i,j);
n=n+1;
}
i=i+1;//i是记录当前的X值
}
pop(i,j);//第二个交点出栈
pop(n,j);//第一个交点出栈,虽然覆盖了Y值,但这不重要,我们要的是X值
i=(i+n)/2;//现在i是我们要找的种子点的X值
//fill the plot
fill(i,j);//将种子点作为参数传入fill()方法
delay(1000);
outtextxy(100,410,"the red line was drawing,fill over");
getch();
closegraph();
}
#include <stdio.h>
#include <alloc.h>
#include <dos.h>
#include <conio.h>
//creat a stack
struct stack_node
{
int x;
int y;
struct stack_node *next;
};
typedef stack_node stack_list;
typedef stack_list *link;
link stack = 0;
//push an element
void push(int xx,int yy)
{
link new_node;
new_node=(stack_list *)malloc(sizeof(stack_list));
new_node->x=xx;
new_node->y=yy;
new_node->next=stack;
stack=new_node;
}
//pop an element
void pop(int &xx,int &yy)
{
link top;
top=stack;
xx=stack->x;
yy=stack->y;
stack=stack->next;
free(top);
}
//fill the plot
void fill(int x,int y)
{
int x0,y0,xl,xr,xlold,xrold;/*x0,y0用来标记x,y的值,xl记录x的最左值,xr记录x的最右值*/
int go=0,go2=0;
int i=0;
push(x,y);//种子像素入栈
while(stack!=0)//如果栈不空则循环,stack==0表示栈空
{
go=0;//go 只是一个标记
pop(x,y);
putpixel(x,y,4);
x0=x+1;
while(getpixel(x0,y)!=4)//fill right 填充右边
{
putpixel(x0,y,4);
x0=x0+1;
}
xr=x0-1;//记录最右值
xrold=xr;//再记录一次最右值,以备后用
x0=x-1;
while(getpixel(x0,y)!=4)//fill right 填充左边
{
putpixel(x0,y,4);
x0=x0-1;
}
xl=x0+1;//记录最左值
xlold=xl;//再记录一次最左值,以备后用
y0=y+1;//go up 向上移一条扫描线
go2=0;//go2 也只是一个用来标记的变量
while(xr>xl&&go==0)//查找上一条线的最右值,并记录为xr
{
if(getpixel(xr,y0)==4)
{
xr=xr-1;
}
else
{
go=1;//若go=1这句执行的话就说明找到了最右值,并在while中的go==0中判断并退出while
}
}
while(xl<xr&&go2==0)//查找上一条线的最左值,并记录为xl
{
if(getpixel(xl,y0)==4)
xl=xl+1;
else
go2=1;//go2=1这句执行就说明找到了最左值,并在此while中的go2==0中退出while
}
if(go==1&&go2==1)//如果找到了最左值各最右值,则执行下面的语句
{
push(xr,y0);//先将上一条线上的最右点作为种子点入栈
for(i=xl;i<xr;i++)//从最左到最右循环,在每个连续区间上找一个种子点入栈
{
if(getpixel(i,y0)!=4)//如果不是边界点,什么也不做
{
}
else if(getpixel(i-1,y0)!=4)//如果是边界点,则看它左边的点是不是边界点,如果不是,则入栈
{
push(i-1,y0);
}
}
}
y0=y-1;//go down;//向下移一条扫描线
go=0;
go2=0;
xl=xlold;//还原最左,最右
xr=xrold;
while(xr>xl&&go==0)//找下一条线的最右
{
if(getpixel(xr,y0)!=4)
{
go=1;
}
else
{
xr--;
}
}
while(xl<xr&&go2==0)//找下一条线的最左
{
if(getpixel(xl,y0)!=4)
go2=1;
else
xl++;
}
if(go==1&&go2==1)//如果找到最左和最右,则执行
{
//push(xl,y0);
push(xr,y0);
for(i=xl;i<=xr;i++)
{
if(getpixel(i,y0)!=4)
{
}
else if(getpixel(i-1,y0)!=4)
{
push(i-1,y0);
}
}
}
}
}
void main()
{
void fill(int x,int y);
int gdriver,gmode;/*显示模式*/
int i,j;
int n,px,py,px0,py0,px1,py1;
int ya=0,yi=getmaxy();
printf("pleas input the number of the top points:");
scanf("%d",&n);
for(i=0;i<n;i++)//从键盘接受各顶点的坐标,依次入栈,并记录最大Y值和最小Y值
{
printf("please input the coordinate of the points--like:100,200 :");
scanf("%d,%d",&px,&py);
if(ya<py)
ya=py;//ya是最大Y值
if(yi>py)
yi=py;//yi是最小Y值
push(px,py);
}
detectgraph(&gdriver,&gmode);
initgraph(&gdriver,&gmode,"c:/bc31/bgi");
setbkcolor(0);
cleardevice();
setcolor(4);
pop(px0,py0);//输入的最后一个顶点出栈
px=px0;
py=py0;//记录最后一个顶点
//draw the plot
while(stack != 0)
{
pop(px1,py1);
line(px0,py0,px1,py1);
px0=px1;
py0=py1;
delay(500);
}
line(px0,py0,px,py);//依次画线,画出多边形
//画完多边形后,栈为空
//find the y value
j=(ya+yi)/2;//找Y的中间值,就是第一个种子点的Y值
i=0;
n=0;//记录入栈个数
//find the seed element
while(i<getmaxx()&&n!=2)//按X值从0到X最大值依次查找,并在入栈个数为2的时候退出
{
if(getpixel(i,j)==4)//如果是多边形上的点,则入栈,用n记录入栈的个数
{
push(i,j);
n=n+1;
}
i=i+1;//i是记录当前的X值
}
pop(i,j);//第二个交点出栈
pop(n,j);//第一个交点出栈,虽然覆盖了Y值,但这不重要,我们要的是X值
i=(i+n)/2;//现在i是我们要找的种子点的X值
//fill the plot
fill(i,j);//将种子点作为参数传入fill()方法
delay(1000);
outtextxy(100,410,"the red line was drawing,fill over");
getch();
closegraph();
}
- C语言实现的扫描线种子填充算法
- 扫描线种子填充算法
- 扫描线种子填充算法
- Open gl 的不规则图形的4联通种子递归填充和扫描线种子递归填充算法实现
- 计算机图形学 - 扫描线种子填充算法
- 线性扫描+种子填充算法 实现区域填充
- 图形填充算法(扫描线种子填充算法)
- 区域填充_扫描线种子填充_广度优先算法种子填充
- 种子填充算法(简单和扫描线)
- 算法系列之十二:多边形区域填充算法--扫描线种子填充算法
- 算法系列之十二:多边形区域填充算法--扫描线种子填充算法
- 算法系列之十二:多边形区域填充算法--扫描线种子填充算法 .
- 算法系列之十二:多边形区域填充算法--扫描线种子填充算法
- 多边形区域填充算法--扫描线种子填充算法
- 多边形区域填充算法--扫描线种子填充算法
- 多边形区域填充算法--扫描线种子填充算法
- 区域填充:扫描线种子填充算法应用(类似魔术棒功能)
- 区域填充:扫描线种子填充和剖面线填充
- 历届奥斯卡最佳影片(1928-2003)
- 用分水岭算法实现图像分割 (祝勇)
- 英文月份的写法
- 先发一个
- 庆祝BLOG开通
- C语言实现的扫描线种子填充算法
- CoreJava Day 5
- 今天逛了一天街。。。
- Velocity脚本简明教程
- MFC与.NET互操作中的控件绑定和消息映射
- Wiki在企业信息化应用中崭露头角
- 女人一生"需要六个男人"
- 摘写的简单到非常的基于TCP的网络应用程序
- Windows 2000 下通过访问物理地址取主机唯一信息