JAVA实现种子填充算法

种子填充算法原理在网上很多地方都能找到,所以直接上实现代码啦0.0

我的实现只是实现了种子填充算法,但是运行效率会有点慢,如果大佬有改进方法,欢迎和我交流,谢谢!

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;    
     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();    
                
            }      
    });

        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);

        /*
         * 画出多边形
         */
             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]+5;
               l.y=b[0]+2;
             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.setContentPane(jp); 
    
        frame.setVisible(true);
          frame.addMouseListener(new MouseAdapter() {

                });
        jp.addMouseListener(new MouseAdapter() {
                
             
                public void mouseClicked(MouseEvent e) {
                    if(e.getButton() == e.BUTTON1)
                    {a[index]=e.getX();
                    b[index]=e.getY();
                    System.out.println("坐标为("+a[index]+","+b[index]+")");
                    index++;        
                    frame.setVisible(true);
                    }                    
                    if(e.getButton() == e.BUTTON3)
                    {                        
                        frame.setContentPane(new SeedFulling());
                        frame.setVisible(true);
                    }
                }
          
        }

                );
        
     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 boolean IsInLine(int x,int y)
    {
        for(int i=0;i<index-1;i++) {
            boolean pdline = (x - a[i]) * (b[i] - b[i+1]) <= ((a[i]-a[i+1])
                    * (y - b[i]));    
                if(pdline==true)
                {    
                    return true;
                }
        }
        if((x - a[index-1]) * (b[index-1] - b[0]) <=((a[index-1]-a[0])
                * (y - b[index-1])))
                return true;
        return false;
        
    }
    public static void main(String[] args) throws IOException {

        createAndShowGUI();
    
    }
}

最后还是贴个截图(先在面板里点击点,右键出现所需填充的轮廓,鼠标移出面板填充):

 

猜你喜欢

转载自www.cnblogs.com/xxsdbk/p/11842788.html