2013-02-27 51 views
0

我正在嘗試創建一個像程序一樣的繪畫,並且我正在實現一個存儲桶填充工具。我存儲了所有已繪製的點,並使用Graphics2D的drawLine來繪製實際的線條,所以我不想存儲所有的點填充(所以我不想做洪水填充)。如何在Java中創建一個桶填充?

對於桶填充,到目前爲止,我已經使用BufferedImage來填寫不在我列表中但仍在繪製的點。

我想要做的一件事就是隻存儲最外面的點,並且比我可以使用Graphics2D的fillPolygon使用這些點。唯一的問題是,我不知道如何找到這些點。

我被困在這裏,所以有沒有人有任何想法?

+0

在行之間使用碰撞點。如果沒有人返回一個細分市場,並且如果有一個細分市場則轉到另一個細分市場。繼續添加這些多邊形。將邊緣作爲分段。 – 2013-02-27 02:58:29

+0

我現在已經意識到,這不會奏效,因爲中間可能會有一種顏色,我不想畫這些。我仍然對此感到好奇,但我不會再使用它了。 – 2013-02-27 03:02:02

+0

您可以從您生成的多邊形中移除多邊形。這會更困難,或者您可以記錄該多邊形並使用它來生成更多的分段以避免重疊。 – 2013-02-27 03:03:25

回答

5

有可能是實現這一目標的方式不同,就個人而言,我會充分利用2D圖形形狀API一堆...

enter image description here

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.RenderingHints; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.geom.Path2D; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class BucketFill { 

    public static void main(String[] args) { 
     new BucketFill(); 
    } 

    public BucketFill() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private List<Point> points; 

     public TestPane() { 
      points = new ArrayList<Point>(25); 

      addMouseListener(new MouseAdapter() { 
       @Override 
       public void mouseClicked(MouseEvent e) { 
        points.add(e.getPoint()); 
        repaint(); 
       } 
      }); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 

      if (points.size() > 0) { 

       Graphics2D g2d = (Graphics2D) g.create(); 
       g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); 
       g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
       g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); 
       g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE); 
       g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); 
       g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 
       g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 
       g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); 

       List<Point> proxy = new ArrayList<>(points); 

       Path2D.Double path = new Path2D.Double(); 
       Point p = proxy.remove(0); 
       path.moveTo(p.getX(), p.getY()); 
       while (proxy.size() > 0) { 
        p = proxy.remove(0); 
        path.lineTo(p.getX(), p.getY()); 
       } 

       g2d.setColor(Color.RED); 
       g2d.fill(path); 
       g2d.setColor(Color.BLACK); 
       g2d.draw(path); 
       g2d.dispose(); 

      } 
     } 
    } 
} 

更新與fillPolygon

您可以用fillPolygon代替Shape實現,只需刪除對形狀的引用,然後使用類似下面的代碼。

List<Point> proxy = new ArrayList<>(points); 
int[] xPoints = new int[proxy.size()]; 
int[] yPoints = new int[proxy.size()]; 
int nPoints = proxy.size(); 

int index = 0; 
while (proxy.size() > 0) { 
    Point p = proxy.remove(0); 
    xPoints[index] = p.x; 
    yPoints[index] = p.y; 
    index++; 
} 

g2d.setColor(Color.RED); 
g2d.fillPolygon(xPoints, yPoints, nPoints); 
g2d.setColor(Color.BLACK); 
g2d.drawPolygon(xPoints, yPoints, nPoints); 

這將生成什麼是已知的閉合多邊形(即,你可以看到所有的線加起來)。

enter image description here

可以實現使用Shape通過調用while-looppath.closePath(),它的畫前。

更新了多個多邊形

enter image description here

在很大程度上將歸結爲你考慮一下多邊形以及如何存儲這些值,但是你可以使用一個Area並從中減去相交的多邊形...

public class BucketFill { 

    public static void main(String[] args) { 
     new BucketFill(); 
    } 

    public BucketFill() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private List<List<Point>> points; 

     public TestPane() { 
      points = new ArrayList<>(25); 

      MouseAdapter ma = new MouseAdapter() { 
       @Override 
       public void mousePressed(MouseEvent e) { 
        List<Point> newShape = new ArrayList<>(25); 
        newShape.add(e.getPoint()); 
        points.add(newShape); 
       } 

       @Override 
       public void mouseReleased(MouseEvent e) { 
       } 

       @Override 
       public void mouseDragged(MouseEvent e) { 
        List<Point> newShape = points.get(points.size() - 1); 
        newShape.add(e.getPoint()); 
        repaint(); 
       } 
      }; 

      addMouseListener(ma); 
      addMouseMotionListener(ma); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 

      if (points.size() > 0) { 

       Graphics2D g2d = (Graphics2D) g.create(); 
       g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); 
       g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
       g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); 
       g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE); 
       g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); 
       g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 
       g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 
       g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); 

       g2d.setColor(Color.BLUE); 
       List<Shape> shapes = new ArrayList<>(25); 
       for (List<Point> subPoints : points) { 

        if (subPoints.size() > 0) { 

         List<Point> proxy = new ArrayList<>(subPoints); 

         Path2D path = new Path2D.Float(); 
         Point startPoint = proxy.remove(0); 
         path.moveTo(startPoint.x, startPoint.y); 
         for (Point p : proxy) { 
          path.lineTo(p.x, p.y); 
         } 
         path.closePath(); 
         shapes.add(path); 
         path = null; 

        } 

       } 

       for (Shape master : shapes) { 
        Area area = new Area(master); 
        for (Shape inner : shapes) { 
         if (inner != master) { 
          area.subtract(new Area(inner)); 
         } 
        } 
        g2d.setColor(Color.RED); 
        g2d.fill(area); 
        g2d.setColor(Color.BLACK); 
        g2d.draw(area); 
       } 

       g2d.dispose(); 

      } 
     } 
    } 
} 
+0

如果點中有一個洞,該怎麼辦?這是用戶輸入,因此可能不一定是完整的多邊形。 – 2013-02-27 03:00:44

+0

再次使用'moveTo' ... – MadProgrammer 2013-02-27 03:05:18

+0

@Legend這正是我剛剛意識到的。謝謝你的答案。 – 2013-02-27 03:08:43

相關問題