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的油漆桶功能.算法的原理很简单,就 ...
随机推荐
- 小程序 跳转web-view 点击左上角返回需要点击2次才能返回
小程序 跳转web-view 点击左上角返回需要点击2次才能返回 再html页面引入js即可解决 <script type="text/javascript" src=& ...
- 000 装docker
直接参考别人的文章,经过验证,没有问题,需要网络. URL: https://www.cnblogs.com/qgc1995/archive/2018/08/29/9553572.html 我是虚拟机 ...
- 003 spring boot访问静态资源与重定向
今天被问到重定向的问题,后续又引起了静态资源路径配置的问题,在这里做一个总结,当然,顺便添加默认访问index.html. 一:默认访问 1.默认路径 在springboot中静态资源的映射文件是在r ...
- PHP过狗webshell编写过程
0x1 先上图: 0x2 编写过程 这里必须强调一下我内心的感觉,小阔爱前两天也研究了过狗的一句话了,然后我突然觉得大家都在进步,我研究点啥呢?不如也试试以前因为觉得自己不懂代码,而不会研究的免杀sh ...
- Flutter Wrap 组件实现流布局
Wrap 可以实现流布局,单行的 Wrap 跟 Row 表现几乎一致,单列的 Wrap 则跟 Row 表 现几乎一致.但 Row 与 Column 都是单行单列的,Wrap 则突破了这个限制,main ...
- 【转】Python 代码批量抓取免费高清图片!
import requests from bs4 import BeautifulSoup import random import time from fake_useragent import U ...
- centos6环境远程执行shell脚本报错not a valid identifier的问题处理
# 通过jenkins的apache用户rsync同步php代码到远程服务器报错如下: SSH: EXEC: STDOUT/STDERR from command [/bin/sh /usr/loca ...
- ubuntu 关于curses头文件问题
执行编译gcc -o badterm badterm.c -lcurses后报错情报如下:term.h: 没有那个文件或目录curses.h: 没有那个文件或目录很明显,程序找不到term.h和cur ...
- 007-guava 缓存
一.概述 Guava Cache与ConcurrentMap很相似,但也不完全一样.最基本的区别是ConcurrentMap会一直保存所有添加的元素,直到显式地移除.相对地,Guava Cache为了 ...
- ByteBuf使用实例
之前我们有个netty5的拆包解决方案(参加netty5拆包问题解决实例),现在我们采用另一种思路,不需要新增LengthFieldBasedFrameDecoder,直接修改NettyMessage ...