2016-08-28 37 views
4

我有以下目標一個Java Swing的分配:繪製隨機圈,紅色的任何圈着色不相交另一個圈子

  1. 程序啓動時,它吸引20個空心圓,半徑和位置每個隨機確定。
  2. 如果圓的周長線不與任何其他圓相交,請用紅色繪製圓的輪廓。如果它至少與另一個圓相交,則將其繪製爲黑色。
  3. 添加一個JButton,每次按它時,都會創建一組新的圓形,如上所述。

我已經完成了上面的目標#1和#3,但是我被困在了目標#2上。

在介紹代碼之前,讓我先了解一下它背後的數學。有兩種方法的圓不能相交另一個圓:

  1. 圓圈相隔太遠共享周邊點,即它們的中心之間的距離小於其半徑之和大於(d> R1 + R2)。 Example
  2. 一個圓完全位於另一個圓的內側,它們的周長不接觸,即它們中心之間的距離小於它們的半徑之差(d < | r1 - r2 |)。 Example

我已經走到這一步:

  1. 比較圓,他們必須指定繪製之前他們,所以我用一個for循環存儲在陣列20個值中心座標(int [] x,int [] y)和半徑(double []半徑)。
  2. 接下來,我使用嵌套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; 
      } 
     } 
    } 
} 
+3

由於這是一個作業,我只給出提示。將識別圓形重疊和標記圓圈重疊真/假(步驟2)的邏輯分開,完全繪製顏色邊界(步驟3)。不要試圖一起做第2步和第3步。 – paisanco

+2

這種分離的例子見[這裏](http://stackoverflow.com/a/8616169/230513)。 – trashgod

+2

*「我已經完成了上面的目標#1和#3,但是我被困在了目標#2上。「*假設沒有限制*如何確定交叉點,我建議使用*** easy ***方式。請參閱[使用複雜形狀的碰撞檢測](http://stackoverflow.com/a/14575043/418556)爲一個工作示例。 –

回答

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]); 
     } 
}