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

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

/**
* 作者:老谢
* 最后修改日期:2006.4.14
* Email:[email protected]
* 功能描述:
* 图形填充算法之
* 扫描线种子填充算法;
**/
/**
* 该程序还需要一个存储 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;
}

你可能感兴趣的:(程序设计)