种子填充算法多用于计算机对图形的处理。例如ps中填充区域一样。当我们要填充某一块区域,首先我们要让电脑识别出你要填充的每个像素点,种子算法通过给定种子的坐标获取该像素的颜色值,通过对比颜色信息来判断周围的像素是否是我们要选择的。
接下来我们用一个字符数组来代表我们的图片,*号的点则是我们要选中的像素,选择后我们则将他改成#。
第一种:四向填充
我们没给定一个种子,我们则只获取左、上、右、下四个点。通过递归或循环处理所有的点。但是用递归会存在递归的深度问题,当我们的图片足够大时,Java虚拟机就会报出栈溢出的错误!
所以我们选取循环+队列的方式。我们都知道队列有个特性:先进先出!当我们根据种子点获取周围四个点加入队列,下一次循环则从队列头部去除一个点作为下一次的种子,并删除他,依次这样循环直到队列大小为零则停止。
Demo1.COL、Demo1.ROW为定义字符数组的行列
/**
* 四向
* @param seed
*/
public void DemoFill4(Point se) {
Point seed = se;
do {
//左
if(0<=(seed.x-1)&&(seed.x-1)<Demo1.ROW&&0<=(seed.y)&&(seed.y)<Demo1.COL&&!point[seed.x-1][seed.y].equals(c)) {
point[seed.x-1][seed.y] = c;
queue.offer(new Point(seed.x-1,seed.y));
}
//上
if(0<=(seed.x)&&(seed.x)<Demo1.ROW&&0<=(seed.y-1)&&(seed.y-1)<Demo1.COL&&!point[seed.x][seed.y-1].equals(c)) {
point[seed.x][seed.y-1] = c;
queue.offer(new Point(seed.x,seed.y-1));
}
//右
if(0<=(seed.x+1)&&(seed.x+1)<Demo1.ROW&&0<=(seed.y)&&(seed.y)<Demo1.COL&&!point[seed.x+1][seed.y].equals(c)) {
point[seed.x+1][seed.y] = c;
queue.offer(new Point(seed.x+1,seed.y));
}
//下
if(0<=(seed.x)&&(seed.x)<Demo1.ROW&&0<=(seed.y+1)&&(seed.y+1)<Demo1.COL&&!point[seed.x][seed.y+1].equals(c)) {
point[seed.x][seed.y+1] = c;
queue.offer(new Point(seed.x,seed.y+1));
}
if(queue.size()>0) {
point[seed.x][seed.y] = c;
Point s = (Point) queue.poll();
point[s.x][s.y] = c;
seed = s;
}else {
return;
}
}while(true);
}
为了提高算法的性能,则可以在加入周围点的同时也改变周围点。
第二种:八向填充 八向填充和四向不同的地方就是他选取了八个方向的点主要是解决边角问题。
/**
* 八向
* @par