JAVA实现种子填充算法
种子填充算法原理在网上很多地方都能找到,这篇是继上篇扫描线算法后另一种填充算法,直接上实现代码啦0.0
我的实现只是实现了种子填充算法,但是运行效率不快,如果大佬有改进方法,欢迎和我交流,谢谢!
最后还是贴个截图(先在面板里点击点,鼠标移出面板填充):
package PolygonScanningAndFilling;
public class location {
public int x;
public int y;
}
package PolygonScanningAndFilling; import java.util.ArrayList;
import java.util.Iterator;
import java.util.Stack;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException; public class SeedFulling extends JPanel { static int X0;
static int Y0;
static int X1;
static int Y1;
static int a[]=new int [10]; //保存点击的10个x坐标
static int b[]=new int [10]; //保存点击的10个y坐标
static int index=0;
static int time=0;
static int time2=0;
static boolean add;
ArrayList<Point>allPoint=new ArrayList<Point>();
ArrayList<Point>drawPoint=new ArrayList<Point>();
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.addMouseListener(new MouseAdapter() {
public void mouseExited(MouseEvent e) {
time++;
repaint(); }
public void mouseClicked(MouseEvent e) {
allPoint.clear();
if(e.getButton() == e.BUTTON1) {
add=true;
if(index!=0)
{
for(int i=0;i<index;i++)
{
if(a[i]==e.getX()&&b[i]==e.getY())
add=false;
}
}
if(add)
{ a[index]=e.getX();
b[index]=e.getY(); System.out.println("坐标为("+a[index]+","+b[index]+")");
index++; //frame.setVisible(true);
repaint();
System.out.print(time2);
if(time2==0)
time2++;
}
} // if(e.getButton() == e.BUTTON3)
// {
//
// }
} }); Graphics2D g2d = (Graphics2D)g; int Ymax=0;
for(int i=0;i<b.length;i++)
{
if(Ymax<b[i])
Ymax=b[i];
}
// System.out.println("Ymax"+Ymax); /*
* 画出多边形
*/
if(time2!=0)
{ int Sum=0;
for(;Sum<=index;Sum++) {
if(Sum==index-1)
{
drawLine(a[Sum], b[Sum], a[0],b[0],g2d); break;
}
else
{
drawLine(a[Sum], b[Sum], a[Sum+1],b[Sum+1],g2d); } }
}
/*
* 得到边界点
*/ if(time!=0) {
boolean spanNeedFill;
location l=new location();
l.x=a[0]+10;
l.y=b[0]+10;
Stack<location> stack=new Stack<location>(); //将第一个点压入栈
stack.push(l);
int a=0;
while(!stack.empty())
{
a++;
System.out.print("第"+a+"次");
location lo=stack.pop();
int x=lo.x;
int y=lo.y;
if(a>50)
{ System.out.println("开始画上时x"+x);
System.out.println("开始画上时y"+y);
}
// System.out.print("y"+y); while(!allPoint.contains(new Point(x,y))&&!drawPoint.contains(new Point(x,y)))
{
//System.out.print(x);
drawPoint.add(new Point(x,y));
//System.out.println("需画点"+x+","+y);
x++;
} int xr=x-1;
x=lo.x-1;
while(!allPoint.contains(new Point(x,y))&&!drawPoint.contains(new Point(x,y)))
{
drawPoint.add(new Point(x,y));
//System.out.println("需画点"+x+","+y);
//g2d.drawString(".", x,y);
x--;
} int xl=x+1;
//处理上面的扫描线
x=xl;
y=y+1; while(x<=xr) { spanNeedFill=false;
while(!allPoint.contains(new Point(x,y))&&!drawPoint.contains(new Point(x,y)))
{
spanNeedFill=true;
x++; //System.out.println("上扫描线边界为"+x);
}
if(spanNeedFill)
{
//System.out.print("入栈1"); location lc=new location();
lc.x=x-1;
lc.y=y;
stack.push(lc);
//System.out.println("入栈1,此时 x="+lc.x);
//System.out.println("入栈1,此时 y="+lc.y);
spanNeedFill=false; }
while(allPoint.contains(new Point(x,y))||drawPoint.contains(new Point(x,y))&&x<=xr)
x++;
} //下扫描线
x=xl;
y=y-2;
while(x<=xr)
{
spanNeedFill=false;
while(!allPoint.contains(new Point(x,y))&&!drawPoint.contains(new Point(x,y)))
{
spanNeedFill=true;
x++;
}
if(spanNeedFill)
{
//System.out.print("入栈2");
lo.x=x-1;
lo.y=y;
stack.push(lo);
System.out.print("入栈2");
spanNeedFill=false; }
while(allPoint.contains(new Point(x,y))||drawPoint.contains(new Point(x,y))&&x<=xr)
x++; }
}
for(int i=0;i<drawPoint.size();i++)
{
//System.out.println("画的y"+p.y);
Point p=drawPoint.get(i);
System.out.println("画的x"+p.x+"画的y"+p.y);
g2d.drawString(".",p.x,p.y); }
} } private static void createAndShowGUI() {
JFrame frame = new JFrame(); frame.setLocationRelativeTo(null); frame.setLayout(null);
JPanel jp=new JPanel();
frame.setVisible(true); frame.setContentPane(new SeedFulling()); frame.setSize(600, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} public void drawLine(int x0,int y0,int x1,int y1,Graphics2D g) {
int x = x0;
int y = y0; int w = x1 - x0;
int h = y1 - y0; int dx1 = w < 0 ? -1: (w > 0 ? 1 : 0);
int dy1 = h < 0 ? -1: (h > 0 ? 1 : 0); int dx2 = w < 0 ? -1: (w > 0 ? 1 : 0);
int dy2 = 0; int fastStep = Math.abs(w);
int slowStep = Math.abs(h);
if (fastStep <=slowStep) {
fastStep= Math.abs(h);
slowStep= Math.abs(w); dx2= 0;
dy2= h < 0 ? -1 : (h > 0 ? 1 : 0);
}
int numerator = fastStep>> 1; for (int i = 0; i <=fastStep; i++) { g.drawString(".", x, y);
Point p=new Point(x,y);
allPoint.add(p);
numerator+= slowStep;
if (numerator >=fastStep) {
numerator-= fastStep;
x+= dx1;
y+= dy1;
}else {
x+= dx2;
y+= dy2;
}
}
} public static void main(String[] args) throws IOException { createAndShowGUI(); }
}


JAVA实现种子填充算法的更多相关文章
- Atitit Seed-Filling种子填充算法attilax总结
Atitit Seed-Filling种子填充算法attilax总结 种子填充的原理,4联通与8联通区域的选择.. 三个队列 waitProcessPixList tempPixList Proces ...
- 种子填充算法描述及C++代码实现
项目需要看了种子填充算法,改进了算法主要去除面积小的部分.种子填充算法分为两种,简单的和基于扫描线的方法,简单的算法如下描述(笔者针对的是二值图像): (1)从上到下,从左到有,依次扫描每个像素: ( ...
- openGL实现图形学扫描线种子填充算法
title: "openGL实现图形学扫描线种子填充算法" date: 2018-06-11T19:41:30+08:00 tags: ["图形学"] cate ...
- CGA填充算法之种子填充算法
CGA填充算法之种子填充算法 平面区域填充算法是计算机图形学领域的一个很重要的算法,区域填充即给出一个区域的边界 (也可以是没有边界,只是给出指定颜色),要求将边界范围内的所有象素单元都修改成指定的颜 ...
- UVA 572 -- Oil Deposits(DFS求连通块+种子填充算法)
UVA 572 -- Oil Deposits(DFS求连通块) 图也有DFS和BFS遍历,由于DFS更好写,所以一般用DFS寻找连通块. 下述代码用一个二重循环来找到当前格子的相邻8个格子,也可用常 ...
- [计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(二)
上一节链接:http://www.cnblogs.com/zjutlitao/p/4116783.html 前言: 在上一节中我们已经大致介绍了该软件的是什么.可以干什么以及界面的大致样子.此外还详细 ...
- Open gl 的不规则图形的4联通种子递归填充和扫描线种子递归填充算法实现
实验题目:不规则区域的填充算法 实验目的:验证不规则区域的填充算法 实验内容:利用VC与OpenGL,实现不规则区域的填充算法. 1.必做:实现简单递归的不规则区域填充算法. 2.选做:针对简单递归算 ...
- [OpenGL] 不规则区域的填充算法
不规则区域的填充算法 一.简单递归 利用Dfs实现简单递归填充. 核心代码: // 简单深度搜索填充 (四连通) void DfsFill(int x, int y) { || y < || x ...
- 图像处理之泛洪填充算法(Flood Fill Algorithm)
泛洪填充算法(Flood Fill Algorithm) 泛洪填充算法又称洪水填充算法是在很多图形绘制软件中常用的填充算法,最熟悉不过就是 windows paint的油漆桶功能.算法的原理很简单,就 ...
随机推荐
- Java hashCode与equals学习
1.关于Object类的equals方法的特点 a) 自反性: x.equals(x) 应该返回true b) 对称性: x.equals(y)为true,那么y.equals(x) 也为true c ...
- 使用注解@Slf4j简化Logger的初始化
一.是不是厌倦了 private final static Logger logger = LoggerFactory.getLogger(Application.class); 的拷贝和修改? 二. ...
- python脚本使用源码安装不同版本的python
# coding=utf-8 import os import sys # 判断是否是root用户 if os.getuid() == 0: pass else: print('当前用户不是root用 ...
- RestSHarp
异步扩展: public static class RestClientExtensions { private static Task<T> SelectAsync<T>(t ...
- 0.9.0.RELEASE版本的spring cloud alibaba sentinel限流、降级处理实例
先看服务提供方的,我们在原来的sentinel实例(参见0.9.0.RELEASE版本的spring cloud alibaba sentinel实例)上加上限流.降级处理,三板斧只需在最后那一斧co ...
- k8s记录-kubeadm安装(二)(转载)
kubeadm安装安装环境(vm6.5下虚拟机3台,centos 7.4):master:10.20.0.191Node1:10.20.0.192Node2:10.20.0.193 1.安装虚拟机,配 ...
- Laya的资源加载
白鹭中的资源加载,可以单个去加载.但是更多是通过资源组加载的. 比如进入登录界面,则加载登录资源组的资源.销毁登录界面,则卸载登录模资源. //加载登录模块资源组 RES.loadGroup(&quo ...
- 123457123456#0#----com.ppGame.ChengYu43--前拼后广--成语caicaicai_pp
com.ppGame.ChengYu43--前拼后广--成语caicaicai_pp
- LeetCode_278. First Bad Version
278. First Bad Version Easy You are a product manager and currently leading a team to develop a new ...
- Meta标签中的http-equiv属性
http-equiv顾名思义,相当于http的文件头作用,它可以向浏览器传回一些有用的信息,以帮助正确和精确地显示网页内容,与之对应的属性值为content,content中的内容其实就是各个参数的变 ...