首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >快速绘制任意的点集合

快速绘制任意的点集合
EN

Stack Overflow用户
提问于 2016-06-07 20:58:19
回答 2查看 58关注 0票数 0

我正在编写一个省道应用程序,并实现了一个省道板,它被绘制为一个BufferedImage。

在呈现省道板时,我首先遍历BufferedImage的坐标,并计算它驻留的“段”。我把它包装成一个DartboardSegment,它基本上只是一个点的集合,有少量额外的结构(它对应于板上的数字,等等)。

目前,要实际渲染飞镖板,我将每个点单独绘制,如下所示:

代码语言:javascript
复制
    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);
    }

显然这需要一些时间。这不是一个不可容忍的数量(~2-3的油漆面积500×500),但我想消除这种‘滞后’,如果我可以。在我的应用程序的其他领域中,我遇到了其他方法(例如Graphics.fillRect()),它们要快得多。

我已经看到在Graphics类上有一个fillPolgyon()方法,但是我不认为我能够轻易地将我的片段转换成多边形,因为它们的形状是不同的(例如,三重的形状,一个用于牛头的圆圈……)。在java中是否有更快的方法一次绘制任意的点数组,而不是单独遍历和绘制?

我想要编写的代码如下:

代码语言:javascript
复制
    for (DartboardSegment segment : allSegments)
    {
        Color colour = DartboardUtil.getColourForSegment(segment);
        Polgyon poly = segment.toPolygon();

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

回答 2

Stack Overflow用户

发布于 2016-06-08 05:20:04

我不认为我能轻易地把我的片段转换成多边形,因为它们的形状是不同的(例如,三重的形状,一个圆的牛眼.)

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

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

代码语言:javascript
复制
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();
            }
        });
*/
    }
}
票数 1
EN

Stack Overflow用户

发布于 2016-06-07 21:10:29

经过进一步的挖掘,我认为解决这一问题的一个办法是做以下工作。这并不是最整洁的,但我认为它会成功的:

代码语言:javascript
复制
    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);

不过,我愿意接受更好的建议!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37689244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档