绘制随机圆圈,以红色着色任何不与另一个圆圈相交的圆圈

时间:2016-08-28 23:21:45

标签: java arrays swing geometry jpanel

我有一个Java Swing分配,具有以下目标:

  1. 当程序启动时,它会绘制20个未填充的圆圈,每个圆圈的半径和位置随机确定。
  2. 如果圆的周边线不与任何其他圆相交,则以红色绘制圆的轮廓。如果它与至少另一个圆相交,则以黑色绘制。
  3. 添加一个JButton,每次按下它,都会创建一组新的圆圈,如上所述。
  4. 我已经完成了上面的目标#1和#3,但我对目标#2感到难过。

    在我介绍代码之前,让我先了解一下背后的数学知识。圆圈不能与另一个圆相交的方式有两种:

    1. 圆相距太远而不能共享周边点,即它们的中心之间的距离大于它们的半径之和(d> r1 + r2)。 Example
    2. 一个圆完全在另一个圆内,并且它们的周长不接触,即它们的中心之间的距离小于它们的半径之间的差(d <| r1-r2 |)。 Example
    3. 到目前为止我得到了什么:

      1. 要比较圆圈,它们必须在绘制之前指定,所以我使用for循环在数组中为中心坐标(int [] x,int [] y)和半径(double []存储20个值]半径)。
      2. 接下来,我使用嵌套的for循环迭代数组并比较两个圆,除非将圆与自身进行比较(索引j =索引k)。如果圆相交,则g.setColor(Color.RED)。如果没有,请g.setColor(Color.BLACK)。
      3. 当我执行我的代码时,没有任何重叠的圆圈正确地涂成红色。但是,一些重叠的圆圈也是红色的。我假设它们在绘制时是非重叠,但之后相交。如何修复代码以及时解决这种差异? (问题区域位于底部附近,在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;
                    }
                }
            }
        }
        

1 个答案:

答案 0 :(得分:2)

你在循环内的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]);
        }
}
相关问题