我有一个
Java Swing任务,具有以下目标:
>当程序启动时,它会绘制20个未填充的圆圈,每个圆圈的半径和位置随机确定.
>如果圆的周边线不与任何其他圆相交,则以红色绘制圆的轮廓.如果它确实与至少另一个圆相交,则以黑色绘制它.
>添加一个JButton,每次按下它,都会创建一组新的圆圈,如上所述.
我已经完成了上面的目标#1和#3,但我对目标#2感到困惑.
在我提出代码之前,让我理解它背后的数学.圆不能与另一个圆相交的方式有两种:
>圆相距太远而不能共享周边点,即它们的中心之间的距离大于它们的半径之和(d> r1 r2). Example.
>一个圆完全在另一个圆内,并且它们的周长不接触,即它们的中心之间的距离小于它们的半径之间的差(d
到目前为止我得到了什么:
>要比较圆,必须在绘制之前指定它们,因此我使用for循环在数组中为中心坐标(int [] x,int [] y)和半径(double [] radius)存储20个值).
>接下来,我使用嵌套的for循环迭代数组并比较两个圆,除非将圆与自身进行比较(索引j =索引k).如果圆相交,则g.setColor(Color.RED).如果没有,g.setColor(Color.BLACK).
当我执行我的代码时,没有任何重叠的圆圈正确地涂成红色.但是,一些重叠的圆圈也是红色的.我假设它们在绘制时没有重叠,但之后相交.如何修复代码以及时解决这种差异? (问题区域位于底部附近,在IntersectingCircles类中)
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JButton;
public class ButtonFrame extends JFrame
{
private final JButton resetButton = new JButton("Reset");
public ButtonFrame()
{
super("Drawing Random Circles");
setLayout(new BorderLayout());
IntersectingCircles intersectingCircles = new IntersectingCircles();
this.add(intersectingCircles, BorderLayout.CENTER);
this.add(resetButton, BorderLayout.SOUTH);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(1400, 1400);
ButtonHandler handler = new ButtonHandler();
resetButton.addActionListener(handler);
}
private class ButtonHandler implements ActionListener
{
@Override
public void actionPerformed(ActionEvent event)
{
reset();
}
}
public static void main(String[] args)
{
ButtonFrame buttonFrame = new ButtonFrame();
buttonFrame.setVisible(true);
}
public void reset()
{
ButtonFrame buttonFrame = new ButtonFrame();
buttonFrame.setVisible(true);
}
}
class IntersectingCircles extends JPanel
{
private static final JButton resetButton = new JButton("Reset Circles");
private static final JFrame frame = new JFrame("Intersecting Circles");
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
this.setBackground(Color.WHITE);
int[] x = new int[20];
int[] y = new int[20];
int[] diameter = new int[20];
double[] radius = new double[20];
for (int i = 0; i < 20; i++)
{
int xCoord = (int)(Math.random() * 600);
int yCoord = (int)(Math.random() * 600);
int circleSize = (int)(Math.random() * 550);
x[i] = xCoord;
y[i] = yCoord;
diameter[i] = circleSize;
radius[i] = circleSize / 2.0;
}
for (int j = 0; j < 20; j++)
{
for (int k = 0; k < 20; k++)
{
if (k != j)
{
if (((Math.sqrt((x[k] - x[j]) * (x[k] - x[j]) + (y[k] - y[j])
* (y[k] - y[j]))) > (radius[j] + radius[k])) ||
((Math.sqrt((x[k] - x[j]) * (x[k] - x[j]) + (y[k] - y[j])
* (y[k] - y[j]))) < (Math.abs(radius[j] - radius[k]))))
g.setColor(Color.RED);
else
g.setColor(Color.BLACK);
g.drawOval(x[j], y[j], diameter[j], diameter[j]);
}
else
continue;
}
}
}
}
最佳答案 你在循环中的if语句中有逻辑错误 – 你可以设置黑色然后恢复为其他一对圆圈的红色.可能的解决方案:
for (int j = 0; j < 20; j++)
{
g.setColor(Color.RED); //set non-intersect state
for (int k = j + 1; k < 20; k++) //avoid excessive work
{
if (intersect test)
{
g.setColor(Color.BLACK);
break; //can stop here
};
g.drawOval(x[j], y[j], diameter[j], diameter[j]);
}
}