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