种子填充算法原理在网上很多地方都能找到,这篇是继上篇扫描线算法后另一种填充算法,直接上实现代码啦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实现种子填充算法的更多相关文章

  1. Atitit Seed-Filling种子填充算法attilax总结

    Atitit Seed-Filling种子填充算法attilax总结 种子填充的原理,4联通与8联通区域的选择.. 三个队列 waitProcessPixList tempPixList Proces ...

  2. 种子填充算法描述及C++代码实现

    项目需要看了种子填充算法,改进了算法主要去除面积小的部分.种子填充算法分为两种,简单的和基于扫描线的方法,简单的算法如下描述(笔者针对的是二值图像): (1)从上到下,从左到有,依次扫描每个像素: ( ...

  3. openGL实现图形学扫描线种子填充算法

    title: "openGL实现图形学扫描线种子填充算法" date: 2018-06-11T19:41:30+08:00 tags: ["图形学"] cate ...

  4. CGA填充算法之种子填充算法

    CGA填充算法之种子填充算法 平面区域填充算法是计算机图形学领域的一个很重要的算法,区域填充即给出一个区域的边界 (也可以是没有边界,只是给出指定颜色),要求将边界范围内的所有象素单元都修改成指定的颜 ...

  5. UVA 572 -- Oil Deposits(DFS求连通块+种子填充算法)

    UVA 572 -- Oil Deposits(DFS求连通块) 图也有DFS和BFS遍历,由于DFS更好写,所以一般用DFS寻找连通块. 下述代码用一个二重循环来找到当前格子的相邻8个格子,也可用常 ...

  6. [计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(二)

    上一节链接:http://www.cnblogs.com/zjutlitao/p/4116783.html 前言: 在上一节中我们已经大致介绍了该软件的是什么.可以干什么以及界面的大致样子.此外还详细 ...

  7. Open gl 的不规则图形的4联通种子递归填充和扫描线种子递归填充算法实现

    实验题目:不规则区域的填充算法 实验目的:验证不规则区域的填充算法 实验内容:利用VC与OpenGL,实现不规则区域的填充算法. 1.必做:实现简单递归的不规则区域填充算法. 2.选做:针对简单递归算 ...

  8. [OpenGL] 不规则区域的填充算法

    不规则区域的填充算法 一.简单递归 利用Dfs实现简单递归填充. 核心代码: // 简单深度搜索填充 (四连通) void DfsFill(int x, int y) { || y < || x ...

  9. 图像处理之泛洪填充算法(Flood Fill Algorithm)

    泛洪填充算法(Flood Fill Algorithm) 泛洪填充算法又称洪水填充算法是在很多图形绘制软件中常用的填充算法,最熟悉不过就是 windows paint的油漆桶功能.算法的原理很简单,就 ...

随机推荐

  1. Java 自动装箱/拆箱

    自动装箱/拆箱大大方便了基本类型(8个基本类型)数据和它们包装类的使用 自动装箱 : 基本类型自动转为包装类(int >> Integer) 自动拆箱: 包装类自动转为基本类型(Integ ...

  2. onenote架设在局域网服务器

    1.服务器端工作 1.1.在局域网服务器磁盘建个 文件夹,命名为 abc 1.2.右键共享,添加用户everyone 权限设置为可读写 不需要安装onenote 2.客户端工作 2.1.在客户端服务器 ...

  3. 阿里物联网平台(一)Windows系统+VS2017 模拟设备端接入

    https://blog.csdn.net/panwen1111/article/details/88365636 一.阿里物联网平台 平台地址:https://account.aliyun.com ...

  4. Hibernate Persistence Contexts

    Hibernate ORM 5.2.18.Final User Guidehttps://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/ ...

  5. PHP 输出两个指定日期之间的所有日期

    function printDates($start,$end){ $dt_start = strtotime($start); $dt_end = strtotime($end); while ($ ...

  6. Ionic4.x ion-infinite-scroll 上拉分页加载更多

    <ion-header> <ion-toolbar> <ion-title> Tab One </ion-title> </ion-toolbar ...

  7. Qt bug

    1.Qt5.2.1不支持QQuickwidget来承载qml 2.Qt5.12以及以上,不支持跨线程调用数据库连接 3.线程A不断产生sql语句,需要让两个数据库分别执行这个sql语句.所以在线程A中 ...

  8. linux记录-安装elk记录(参考博文)

    什么是ELK? 通俗来讲,ELK是由Elasticsearch.Logstash.Kibana .filebeat三个开源软件的组成的一个组合体,这三个软件当中,每个软件用于完成不同的功能,ELK 又 ...

  9. T-SQL_常用内置函数和操作

    作者:icyjiang 推荐:LinkEdu SELECT --从数据库表中检索数据行和列 INSERT --向数据库表添加新数据行 DELETE --从数据库表中删除数据行 UPDATE --更新数 ...

  10. centos配置/etc/mail.rc发邮件

    安装mailx: yum install mailx vi /etc/mail.rc set from=524755798@qq.comset smtp="smtps://smtp.qq.c ...