使用Bresenham的圆算法在Java中生成椭圆

时间:2017-02-04 00:45:50

标签: java swing ellipse bresenham

我正在尝试创建一个基于GUI的程序,该程序使用网格和Bresenham的圆算法绘制椭圆。但是,我有两个问题。一个是我无法让panel_grid刷新,以便将r的新值传递给GridComponent,并使用新的radius重新绘制椭圆。第二个问题是我设法让代码生成一个圆圈,但我无法弄清楚如何修改它来生成椭圆。有人可以一步一步地向我解释我将如何解决这两个问题?提前谢谢。

public class GUI extends JFrame {

    private int r = 100;

    public GUI(){
        JFrame frame = new JFrame("Bresenham’s Ellipse Algorithm");
        frame.setIconImage(Toolkit.getDefaultToolkit().getImage(GUI.class.getResource("/com/sun/java/swing/plaf/windows/icons/TreeLeaf.gif")));
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(600, 600));
        frame.setMinimumSize(new Dimension(440, 400));
        JPanel panel = new JPanel();

        JLabel label = new JLabel("Input the Dimensions of the Ellipse");
        label.setFont(new Font("Sinhala Sangam MN", Font.PLAIN, 16));
        JPanel panel_inst = new JPanel();
        panel_inst.setPreferredSize(new Dimension(550, 30));
        panel_inst.add(label);

        panel.add(panel_inst);

        JPanel panel_1 = new JPanel();
        JLabel w = new JLabel("Radius");
        JTextField width = new JTextField(10);
        JPanel panel_grid = new JPanel();
        JButton draw = new JButton("Draw");
        draw.setPreferredSize(new Dimension(80, 25));

        draw.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {                
               r = Integer.parseInt(width.getText());
               panel_grid.revalidate();
               panel_grid.repaint();
            }
        });
        panel_1.add(w); 
        panel_1.add(width); 
        panel_1.add(draw);    

        panel.add(panel_1);

        panel_grid.setBackground(Color.white);
        panel_grid.setPreferredSize(new Dimension(550, 450));
        GridComponent grid = new GridComponent(r);
        panel_grid.add(grid);
        panel.add(panel_grid);

        frame.pack();
        frame.setVisible(true);
        frame.setContentPane(panel);
      }


    public class GridComponent extends JComponent{
        int r;
        public GridComponent(int r){
            this.r = r;
            setPreferredSize(new Dimension(550, 450));
        }

        public void paintComponent(Graphics g){

           //Draw Grid 
            Graphics2D g2 = (Graphics2D) g;
            int width = 54;
            int height = 44;
            int size = 10;
            for( int i = 0; i < width; i ++){
                for( int j = 0; j < height; j++){
                    Rectangle grid = new Rectangle( 0 + i * size, 0 + j * size, size, size);
                    g2.draw(grid);
                }
            }
            g.setColor(Color.black);
            g2.fillOval((int)Math.floor((width*size)/2)-3,(int)Math.floor((height*size)/2-6)+3, 5, 5);
            g2.drawLine(0, (int)Math.floor((height*size)/2)-1, (int)Math.floor((width*size)), (int)Math.floor((height*size)/2)-1);
            g2.drawLine((int)Math.floor((width*size/2))-1, 0, (int)Math.floor((width*size)/2)-1, (int)Math.floor((height*size)));


           //Draw Ellipse using algo
            int a = (int)Math.floor((height*size/2));//(int)Math.floor((width*15/2));
            int b = (int)Math.floor((width*size/2));// (int)Math.floor((height*15/2));

            int x = r, y = 0, d = 3 - 2*r;
            g2.setColor(Color.red);
             // x is initially r, x will be same as y at 45(degree) angle
            while(y <= x) {

                // Eight way symmetry of circle
                g2.drawString("+", x + b, y + a);
                g2.drawString(".", y + b, x + a); 
                g2.drawString("+", (-1)*y + b, x + a);
                g2.drawString(".", (-1)*x + b, y + a);
                g2.drawString("+", (-1)*x + b, (-1)*y + a);
                g2.drawString(".", (-1)*y + b, (-1)*x + a);
                g2.drawString("+", y + b, (-1)*x + a);
                g2.drawString(".", x + b, (-1)*y + a);

                if(d < 0) // move Up = d + Up + 2  
                   d = d + 4*y + 6;
                else { // move Left = d + Left + 2
                   d = d - 4*(x - y) + 10;
                  //Since we've started at the right hand side of the circle
                   x = x - 1;
                }

                // Since we have started at top of the circle
                y = y + 1;      
            } 
        }
        private int side;

    }


}

1 个答案:

答案 0 :(得分:1)

从...开始

将半径的setter添加到GridComponent

public void setR(int r) {
    this.r = r;
    repaint();
}

然后...

更改您的ActionListener以与您的GridComponent互动,并将其称为“设置方法”

GridComponent grid = new GridComponent(r);
draw.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        r = Integer.parseInt(width.getText());
        grid.setR(r);
    }
});

这将回答你问题的第一部分。

第二部分更难,我不会尝试生成代码,除此之外,你需要两个值,你需要一个宽度和高度半径

但是,Bresenham's circle/ellipse drawing algorithm可能会提供洞察力