好多天沒去上圖形學的課了,今天聽說要交幾個圖形學的算法實現程序,就花了將近一天的時間終於將程序調試通過了,可是到了實驗室,才知道老師根本沒時間檢查。哎,白寫了^_^.說笑了,其實不寫怎麼能真正理解算法的真諦呢。現在將程序貼出來,以備將來有學弟學妹之用。(其實如果只是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;
}