2013-02-27 55 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

相关问题