您的位置:首页 > 其它

图形填充算法(扫描线种子填充算法)

2006-04-14 21:32 387 查看
好多天没去上图形学的课了,今天听说要交几个图形学的算法实现程序,就花了将近一天的时间终于将程序调试通过了,可是到了实验室,才知道老师根本没时间检查。哎,白写了^_^.说笑了,其实不写怎么能真正理解算法的真谛呢。现在将程序贴出来,以备将来有学弟学妹之用。(其实如果只是Copy来的程序,对自己真是没什么用,除了有时能瞒过老师,也许对成绩有帮助。仅此而已。)

/**
* 作者:老谢
* 最后修改日期:2006.4.14
* Email:do_while@sohu.com
* 功能描述:
* 图形填充算法之
* 扫描线种子填充算法;
**/
/**
* 该程序还需要一个存储 Point (点)结构的一个堆栈
* 和图形模式的初始化程序
* 这两个程序的实现程序在后面
**/

/*linescan.c*/

#include "graphics.h"
#include "dos.h"
#include "stdio.h"
#include "PStack.h"

/**
* 初始化扫描线
* (x,y)必须在图形的内部
**/
void initScan(PointStack *s,int x,int y)
{
Point p;

p.X = x;
p.Y = y;

push(s,p);

delay(4000);
}

/**
* 根据种子填充这一行,并且找到上下两行的种子,入栈
**/
void fillThisLine(PointStack *s,Point seed,color fillColor,color borderColor)
{
int curx = seed.X;
int cury = seed.Y;

int xr = 0;
int xl = 0;

int tag = 0; /*分别为区段的左右坐标值*/
Point point;

curx = seed.X;

/**
* 不是边界 也没有填充过,一直向右走
**/
while(getpixel(curx,cury) != borderColor &&
getpixel(curx,cury) != fillColor)
{
if(curx > 600)
{
printf("curx = %d",curx);
return;
}

curx++;
}

xr = --curx;

/**
* 开始向左填充
**/
while(getpixel(curx,cury) != borderColor &&
getpixel(curx,cury) != fillColor)
{
putpixel(curx,cury,fillColor);

if(curx <= 0)
{
/*坐标越界*/
printf("curx = %d /n",curx);
return;
}
curx--;
}

xl = ++curx;

/**
//从左边开始检查y-1这一行,直到遇到边界或者已经填充过的点,记录,作为种子
//继续检查直到检查到Xr;
**/
tag = 0;/*初始值必须是0*/
curx = xl;
while(curx <= xr)
{
/*发现空白并标记(tag = 1)*/
if(getpixel(curx,cury-1) != borderColor &&
getpixel(curx,cury-1) != fillColor)
{
tag = 1; /*有空白点*/
}
else
{
/**
* 有空白点才有种子
* 空白结束,保存种子,并清空标记
**/
if(tag == 1)
{
curx--;
point.X = curx;
point.Y = cury-1;
push(s,point);

/*一段空白只能有一个种子*/
tag = 0;
}
}
curx++;
}
if(tag == 1)
{
curx--;
point.X = curx;
point.Y = cury-1;
push(s,point);
}
/**
//从左边开始检查y+1这一行,直到遇到边界或者已经填充过的点,记录,作为种子
//继续检查直到检查到Xr;
**/
curx = xl;
tag = 0;/*初始值必须是0*/
while(curx <= xr)
{
/*发现空白并标记(tag = 1)*/
if(getpixel(curx,cury+1) != borderColor &&
getpixel(curx,cury+1) != fillColor)
{
tag = 1; /*有空白点*/
}
else
{
/**
* 有空白点才有种子
* 空白结束,保存种子,并清空标记
**/
if(tag == 1)
{
curx--;
point.X = curx;
point.Y = cury+1;
push(s,point);

/*一段空白只能有一个种子*/
tag = 0;
}
}
curx++;
}
if(tag == 1)
{

curx--;
point.X = curx;
point.Y = cury+1;
push(s,point);
}

}

/**
* 用指定颜色填充指定区域(并且指定所用的 stack)
**/
void fill(PointStack *s,color fillColor,color borderColor)
{
Point seed;

while(s->length > 0)
{
seed = pop(s);
fillThisLine(s,seed,fillColor,borderColor);
}
}

/**
* 应用实例
**/
int main()
{
Point p;

PointStack s;

initstack(&s);
init();

printf("Start!");
getch();
circle(200,200,100);
circle(200,200,30);
circle(200,150,25);
circle(200,170,20);
rectangle(150,210,250,250);

getch();

initScan(&s,245,201);
fill(&s,RED,WHITE);
destroy(&s);

initScan(&s,201,199);
fill(&s,GREEN,WHITE);
destroy(&s);

initScan(&s,201,151);
fill(&s,3,WHITE);
destroy(&s);

initScan(&s,201,139);
fill(&s,9,WHITE);
destroy(&s);

initScan(&s,249,249);
fill(&s,13,WHITE);
destroy(&s);

printf("Length of stackt:%d/n",s.length);
printf("Capacity of stackt:%d/n",s.capacity);

getch();
closegraph();
}

/*PStack.H*/
/*******************堆栈的声明******************************/
/**
* 定义一个存放Piont 结构的堆栈(动态数组实现)
**/
#ifndef POINTSTACK_H
#define POINTSTACK_H

#include "stdio.h"
#include "stdlib.h"

/**
* define the Point struct
**/
typedef struct
{
int X;
int Y;
}Point;
/**
*stack
**/
typedef struct
{
Point * head;
int length;
int capacity;
}PointStack;

/*========================*/
bool initstack(PointStack *s);
void destroy(PointStack *s);
void push(PointStack *s,Point p);
Point pop(PointStack *s);

#endif

/*PStack.c*/
/**
* 定义一个存放Piont 结构的堆栈(动态数组实现)
**/
#include "myhead.h"
#include "PStack.h"

/*当堆栈空时返回*/
Point NPoint;

/*初始化堆栈*/
bool initstack(PointStack * s)
{
NPoint.X = -1;
NPoint.Y = -1;

s->length = 0;
s->capacity = 20;

/*Capacity*/
s->head = (Point *)malloc(sizeof(Point)*20);
if(s->head == null)
{
printf("malloc error!");
exit(0);
}
return true;
}

void destroy(PointStack *s)
{
free(s->head);
s->length = 0;
s->capacity = 0;
}

void push(PointStack *s,Point p)
{
Point * temp;
int i;

if(s->length >= s->capacity)
{
temp = (Point *)malloc(sizeof(Point)*(s->capacity + 20));
if(temp != null)
{
/*success*/
for(i = 0;i < s->length;i++)
{
temp[i] = s->head[i];
}

s->capacity += 20;
free(s->head);
s->head = temp;
}
else
{
printf("malloc error!=n");
exit(0);
}
}

/*push*/
s->head[s->length] = p;
s->length++;
}

Point pop(PointStack *s)
{
Point temp;

if(s->length == 0)
{
return 0;
}
else
{
s->length--;
temp = s->head[s->length];
return temp;
}
}

/*myhead.c*/
/*图形模式初始化*/
int init()
{
int driver = DETECT,mode = 0;
initgraph(&driver,&mode,"E://tc//tc2");
return 1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: