2016-06-07 27 views
0

我正在写一个飞镖应用程序,并且实现了一个绘制为BufferedImage的飞镖。快速绘制任意点集合

当渲染飞镖时,我首先迭代BufferedImage的坐标并计算它所在的'段'。我把它包装到一个DartboardSegment中,它基本上只是一个小点集合额外结构的数量(板上对应的数字等)。

目前,实际呈现飞镖盘我个人画的每个点,如下所示:

for (Point pt : allPoints) 
    { 
     DartboardSegment segment = getSegmentForPoint(pt); 
     Color colour = DartboardUtil.getColourForSegment(segment); 

     int rgb = colour.getRGB(); 
     int x = (int)pt.getX(); 
     int y = (int)pt.getY(); 
     dartboardImage.setRGB(x, y, rgb); 
    } 

显然,这需要一些时间。这不是一个无法容忍的数量(绘制500x500区域需要2-3秒),但是如果可以的话,我想消除这个“滞后”。在我的应用程序的其他领域,我遇到了更快的替代方法(如Graphics.fillRect())。

我见过在Graphics类上有一个fillPolgyon()方法,但是我不认为我可以很容易地将我的片段转换成多边形,因为它们的形状各不相同(例如三元组的形状,红心......)。在Java中有更快的方法来绘制一个任意的点数组,而不是循环遍历和单独绘制?

,我想编写的代码是一样的东西:

for (DartboardSegment segment : allSegments) 
    { 
     Color colour = DartboardUtil.getColourForSegment(segment); 
     Polgyon poly = segment.toPolygon(); 

     Graphics gfx = dartboardImage.getGraphics(); 
     gfx.setColor(colour); 
     gfx.fillPolygon(poly); 
    } 
+2

在时间绘画500由500个像素的一个像素的面积应大于2秒时间相当少(我的电脑上,填充其随机数据大约需要20ms)。因此,我怀疑你的问题不是用'dartboardImage.setRGB(x,y,rgb);'用'getSegmentForPoint()'或'DartboardUtil.getColourForSegment()'。你能告诉我们这些方法的代码吗? –

+0

它们本质上都是hashmap查找,除了第一次迭代时hashmap将被构建。 实施我描述的改变后,时间已经缩短到0.3秒,这就是所谓的相同的两种方法。不知道为什么你看不到相同的行为。 –

回答

0

更有点挖后,我认为一个解决办法是做到以下几点。这不是最好的,但我认为它会工作:

int i = 0; 
    for (int y=0; y<height; y++) 
    { 
     for (int x=0; x<width; x++) 
     { 
      Point pt = new Point(x, y); 
      DartboardSegment segment = getSegmentForPoint(pt); 
      Color colour = DartboardUtil.getColourForSegment(segment); 

      pixels[i] = colorToUse.getRGB(); 
      i++; 
     } 
    } 

    dartboardImage.setRGB(0, 0, width, height, pixels, 0, width); 

然而,我打开更好的建议!

+1

通过在循环内不创建一个新的'Point',可以提高速度:在循环外部声明它,并在内部循环中使用'pt.setLocation(x,y)'。 –

1

我不认为我可以轻松地将我的部分为多边形,因为它们的形状变化(例如三重的形状,为靶心了一圈......)

这里是东西可能会给你一些想法。

可以创建形状对象来表示飞镖盘的每个区域:

import java.awt.*; 
import java.util.*; 
import javax.swing.*; 
import java.awt.geom.*; 

public class Dartboard extends JPanel 
{ 
    private ArrayList<DartboardSegment> segments = new ArrayList<DartboardSegment>(); 
    private int size = 500; 
    private int radius = size/2; 
    private int border = 25; 
    private int doubleSize = size - (2 * border); 
    private int tripleSize = size/2; 
    private int thickness = 10; 

    public Dartboard() 
    { 
     createSegmentWedges(); 

     int innerRadius = size - (2 * border); 
     Shape outer = new Ellipse2D.Double(0, 0, size, size); 
     Shape inner = new Ellipse2D.Double(border, border, innerRadius, innerRadius); 
     Area circle = new Area(outer); 
     circle.subtract(new Area(inner)); 
     segments.add(new DartboardSegment(circle, Color.BLACK)); 

     createBullsEye(); 
    } 

    private void createSegmentWedges() 
    { 
     int angle = -99; 

     for (int i = 0; i < 20; i++) 
     { 
      // Create the wedge shape 

      GeneralPath path = new GeneralPath(); 
      path.moveTo(250, 250); 

      double radians1 = Math.toRadians(angle); 
      double x1 = Math.cos(radians1) * radius; 
      double y1 = Math.sin(radians1) * radius; 
      path.lineTo(x1 + 250, y1 + 250); 

      angle += 18; 
      double radians2 = Math.toRadians(angle); 
      double x2 = Math.cos(radians2) * radius; 
      double y2 = Math.sin(radians2) * radius; 
      path.lineTo(x2 + 250, y2 + 250); 

      path.closePath(); 

      Color wedgeColor = (i % 2 == 0) ? Color.BLACK : Color.WHITE; 
      segments.add(new DartboardSegment(path, wedgeColor)); 

      // Create the double/triple shapes 

      Color color = (i % 2 == 0) ? Color.RED : Color.GREEN; 
      createShape(doubleSize, path, color); 
      createShape(tripleSize, path, color); 
     } 
    } 

    private void createShape(int outerSize, GeneralPath path, Color color) 
    { 
     int outerOffset = (size - outerSize)/2; 
     int innerSize = outerSize - (2 * thickness); 
     int innerOffset = (size - innerSize)/2; 

     Shape outer = new Ellipse2D.Double(outerOffset, outerOffset, outerSize, outerSize); 
     Shape inner = new Ellipse2D.Double(innerOffset, innerOffset, innerSize, innerSize); 

     Area circle = new Area(outer); 
     circle.subtract(new Area(inner)); 
     circle.intersect(new Area(path)); 

     segments.add(new DartboardSegment(circle, color)); 
    } 

    private void createBullsEye() 
    { 
      int radius1 = 40; 
      int offset1 = (size - radius1)/2; 
      Ellipse2D.Double bullsEye1 = new Ellipse2D.Double(offset1, offset1, radius1, radius1); 
      segments.add(new DartboardSegment(bullsEye1, Color.GREEN)); 

      int radius2 = 20; 
      int offset2 = (size - radius2)/2; 
      Ellipse2D.Double bullsEye2 = new Ellipse2D.Double(offset2, offset2, radius2, radius2); 
      segments.add(new DartboardSegment(bullsEye2, Color.RED)); 
    } 

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

     Graphics2D g2d = (Graphics2D)g.create(); 

     for (DartboardSegment segment: segments) 
     { 
      g2d.setColor(segment.getColor()); 
      g2d.fill(segment.getShape()); 
     } 

    } 

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

    class DartboardSegment 
    { 
     private Shape shape; 
     private Color color; 

     public DartboardSegment(Shape shape, Color color) 
     { 
      this.shape = shape; 
      this.color = color; 
     } 

     public Shape getShape() 
     { 
      return shape; 
     } 

     public Color getColor() 
     { 
      return color; 
     } 
    } 


    private static void createAndShowGUI() 
    { 
     JFrame frame = new JFrame("DartBoard"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new Dartboard()); 
     frame.setLocationByPlatform(true); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(() -> createAndShowGUI()); 
/* 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       createAndShowGUI(); 
      } 
     }); 
*/ 
    } 
} 
+0

额定你为此付出的努力。 我已经编写了所有的触发逻辑来创建段,我只是没有创建完整的形状。我没有速度问题了,所以我不会在这里使用代码,但它肯定会为其他人寻找同样的东西提供有用的参考! –