2017-02-04 65 views
-2

我想創建一個基於GUI的程序,它使用網格和Bresenham的圓形算法繪製橢圓。但是,我有兩個問題。一個是我無法獲得panel_grid刷新,以便將新的r值傳遞給GridComponent,並使用新的半徑重新繪製橢圓。第二個問題是,我設法讓代碼生成一個圓,但我無法弄清楚如何修改它來生成一個橢圓。有人可以一步一步向我解釋我將如何解決這兩個問題嗎?提前致謝。使用Bresenham的圓形算法在Java中生成橢圓

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

開始由...

添加爲半徑的二傳手您GridComponent

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

則...

更改ActionListener與您GridComponent和互動稱它爲setter方法

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可能會提供一個洞察