-2

I am trying to create a GUI based program which uses a grid and Bresenham’s Circle Algorithm to draw an ellipse. However, I am having two problems. One is that I am unable to get the panel_grid to refresh such that the new value of r is passed to the GridComponent and the ellipse is redrawn with the new radius. The second issue is that I managed to get the code to generate a circle, but I am unable to figure out how I would modify it to generate an ellipse instead. Can someone explain to me step by step how I would go about solving both these problems? Thanks in advance.

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;

    }


}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
k-Rocker
  • 147
  • 2
  • 9

1 Answers1

1

Start by...

Adding a setter for the radius to your GridComponent class

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

Then...

Change your ActionListener to interact with your GridComponent and call it's setter method

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

Which will answer the first part of your question.

The second part is more difficult and I'm not going to attempt to generate code, other then to say, you need two values, you need a width and height radius

But, Bresenham's circle/ellipse drawing algorithm might provide an insight

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366