c++实现种子填充算法与扫描线算法

前言

默认您已经配置好相关环境。
如若没有,可以自行搜索“EasyX”下载安装。
本教程主要从代码方面讲解算法的实现。
至于理论部分还请大家自行搜索其他文章。(该类文章非常多)

种子填充算法

演示视频
c++实现种子填充算法与扫描线算法_第1张图片
核心代码

void FloodFILL(int x, int y, int bodercolor, int newcolor)
{
	int color = getpixel(x,y);//获取该点的颜色
	if (color != bodercolor && color != newcolor)//该点不是边界点/该点颜色未发生改变
	{
		putpixel(x, y, newcolor);//更改该点颜色为新颜色
		//递归向四个方向调用该函数
		FloodFILL(x, y + 1, bodercolor, newcolor);
		FloodFILL(x, y - 1, bodercolor, newcolor);
		FloodFILL(x - 1, y, bodercolor, newcolor);
		FloodFILL(x + 1, y, bodercolor, newcolor);
	}
}

完整代码

#include
#include
#include
void FloodFILL(int x, int y, int bodercolor, int newcolor)
{
	int color = getpixel(x,y);
	if (color != bodercolor && color != newcolor)
	{
		putpixel(x, y, newcolor);
		FloodFILL(x, y + 1, bodercolor, newcolor);
		FloodFILL(x, y - 1, bodercolor, newcolor);
		FloodFILL(x - 1, y, bodercolor, newcolor);
		FloodFILL(x + 1, y, bodercolor, newcolor);
	}
}


int main()
{
	initgraph(640, 480);
	setcolor(BLUE);
	moveto(80, 80);
	lineto(280, 160);
	lineto(520, 0);
	lineto(520, 220);
	lineto(280, 400);
	lineto(80, 320);
	lineto(80, 80);
	FloodFILL(280, 200, BLUE, RED);
	_getch();
	closegraph();
	return 0;
}

PS:如果该代码运行时报错,共两种情况:1.未配置EASYX 2.递归次数过多超出最大栈上限
自行百度这两种问题就可以解决啦~

扫描线算法

个人这个原始版本实现的稍微有点啰嗦,优化的空间很大。
希望可以带给大家一点思路,剩下的完善就交给你们自己啦。
演示效果
c++实现种子填充算法与扫描线算法_第2张图片
首先,将线段作为一个类,进行声明

class Line
{
public:
	Line(int x1, int y1, int x2, int y2) :Start_x(x1), Start_y(y1), End_x(x2), End_y(y2) 
	{ 
		k = float(End_y - Start_y) / float(End_x - Start_x); 
		moveto(x1, y1);
		lineto(x2, y2);
	}
	//y=kx+b,然后通过反函数,通过y的值获得x的值
	float getX(int y)
	{
		if (Start_y < End_y && (y<Start_y || y>End_y))
			return 0;
		else if (Start_y > End_y && (y > Start_y || y < End_y))
			return 0;
		float x = Start_x + float(y - Start_y) / k;
		return x;
	}
private:
	int Start_x;
	int Start_y;
	int End_x;
	int End_y;
	float k;
};

//以演示图的效果来看,就是将线段的点的纵坐标从上到下排序
void Sort(float S[],int y)
{
	int i, j,num=0;
	for (i = 0; i < 6; i++)
	{
		if (S[i] != 0)
			num++;
	}
	for (i = 0; i < 6; i++)
	{
		for (j = 0; j < 5; j++)
		{
			if (S[j] < S[j + 1])
			{
				float temp = S[j];
				S[j] = S[j + 1];
				S[j + 1] = temp;
			}
		}
	}
	if (num == 2)
	{
		int Ex = int(S[0]);
		int Sx = int(S[1]);
		for (int x = Sx; x <= Ex; x++)
			PointFill(x, y, RED);
	}
	else if (num == 3)
	{
		int Ex = int(S[0]);
		int Sx = int(S[2]);
		for (int x = Sx; x <= Ex; x++)
			PointFill(x, y, RED);
	}
	else if (num == 4)
	{
		int Ex, Sx,x;
		Ex = int(S[0]);
		Sx = int(S[1]);
		for (x = Sx; x <= Ex; x++)
			PointFill(x, y, RED);
		Ex = int(S[2]);
		Sx = int(S[3]);
		for (x= Sx; x <= Ex; x++)
			PointFill(x, y, RED);
	}
	else if(num==6)
	{
		int Ex, Sx,x;
		Ex = int(S[0]);
		Sx = int(S[1]);
		for (x = Sx; x <= Ex; x++)
			PointFill(x, y, RED);
		Ex = int(S[2]);
		Sx = int(S[3]);
		for (x = Sx; x <= Ex; x++)
			PointFill(x, y, RED);
		Ex = int(S[4]);
		Sx = int(S[5]);
		for (x = Sx; x <= Ex; x++)
			PointFill(x, y, RED);
	}
}

核心代码

//六条线段(自行定义
void ScanLines(int y,Line l1,Line l2,Line l3,Line l4,Line l5,Line l6)
{
	float S[6] = { 0 };
	if (y < 400)
	{
		S[0] = l1.getX(y);
		S[1] = l2.getX(y);
		S[2] = l3.getX(y);
		S[3] = l4.getX(y);
		S[4] = l5.getX(y);
		S[5] = l6.getX(y);
		Sort(S, y);
		Sleep(10);
		ScanLines(y + 1, l1, l2, l3, l4, l5, l6);
	}
}

完整代码

#include
#include
#include
#include
void PointFill(int x, int y,int newcolor)
{
	putpixel(x, y, newcolor);
}

class Line
{
public:
	Line(int x1, int y1, int x2, int y2) :Start_x(x1), Start_y(y1), End_x(x2), End_y(y2) 
	{ 
		k = float(End_y - Start_y) / float(End_x - Start_x); 
		moveto(x1, y1);
		lineto(x2, y2);
	}
	float getX(int y)
	{
		if (Start_y < End_y && (y<Start_y || y>End_y))
			return 0;
		else if (Start_y > End_y && (y > Start_y || y < End_y))
			return 0;
		float x = Start_x + float(y - Start_y) / k;
		return x;
	}
private:
	int Start_x;
	int Start_y;
	int End_x;
	int End_y;
	float k;
};

void Sort(float S[],int y)
{
	int i, j,num=0;
	for (i = 0; i < 6; i++)
	{
		if (S[i] != 0)
			num++;
	}
	for (i = 0; i < 6; i++)
	{
		for (j = 0; j < 5; j++)
		{
			if (S[j] < S[j + 1])
			{
				float temp = S[j];
				S[j] = S[j + 1];
				S[j + 1] = temp;
			}
		}
	}
	if (num == 2)
	{
		int Ex = int(S[0]);
		int Sx = int(S[1]);
		for (int x = Sx; x <= Ex; x++)
			PointFill(x, y, RED);
	}
	else if (num == 3)
	{
		int Ex = int(S[0]);
		int Sx = int(S[2]);
		for (int x = Sx; x <= Ex; x++)
			PointFill(x, y, RED);
	}
	else if (num == 4)
	{
		int Ex, Sx,x;
		Ex = int(S[0]);
		Sx = int(S[1]);
		for (x = Sx; x <= Ex; x++)
			PointFill(x, y, RED);
		Ex = int(S[2]);
		Sx = int(S[3]);
		for (x= Sx; x <= Ex; x++)
			PointFill(x, y, RED);
	}
	else if(num==6)
	{
		int Ex, Sx,x;
		Ex = int(S[0]);
		Sx = int(S[1]);
		for (x = Sx; x <= Ex; x++)
			PointFill(x, y, RED);
		Ex = int(S[2]);
		Sx = int(S[3]);
		for (x = Sx; x <= Ex; x++)
			PointFill(x, y, RED);
		Ex = int(S[4]);
		Sx = int(S[5]);
		for (x = Sx; x <= Ex; x++)
			PointFill(x, y, RED);
	}
}


void ScanLines(int y,Line l1,Line l2,Line l3,Line l4,Line l5,Line l6)
{
	float S[6] = { 0 };
	if (y < 400)
	{
		S[0] = l1.getX(y);
		S[1] = l2.getX(y);
		S[2] = l3.getX(y);
		S[3] = l4.getX(y);
		S[4] = l5.getX(y);
		S[5] = l6.getX(y);
		Sort(S, y);
		Sleep(10);
		ScanLines(y + 1, l1, l2, l3, l4, l5, l6);
	}
}


int main()
{
	initgraph(640, 480);
	setcolor(BLUE);
	float S[6] = { 0 };
	Line l1(80, 80, 280, 160);
	Line l2(280, 160, 520, 0);
	Line l3(520, 0, 520, 220);
	Line l4(520, 220, 280, 400);
	Line l5(280, 400, 80, 320);
	Line l6(80, 320, 80, 80);
	ScanLines(0, l1, l2, l3, l4, l5, l6);
	PointFill(280, 200,RED);
	_getch();
	closegraph();
	return 0;
}

你可能感兴趣的:(c/c++)