我正在尝试创建一个基于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;
}
}
答案 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可能会提供洞察力