2016-08-28 10 views
4

別の円と交差しない赤色に着色、ランダムな円を描く:Iは以下の目的のJava Swingの割り当てを持っているいずれかの円が

  1. プログラムが起動すると、それは半径位置と、20個の白丸を描きますランダムに決定される。
  2. 円の周線が他の円と交差しない場合は、円の輪郭を赤で描画します。少なくとも1つの他の円と交差する場合は、BLACKで描画します。
  3. JButtonを追加すると、そのたびに上記のように新しい一連の円が作成されます。

私は上記の目標1と3を完了しましたが、私は目標#2で困惑しています。

コードを提示する前に、その背後にある数学を理解しておきましょう。円は別の円を交差することができない2つの方法があります。

  1. 円の彼らの中心間の距離は、その半径の合計よりも大きい。すなわち、周囲のポイントを共有するために離れすぎている(D> R1 + r2)。 Example
  2. 1つの円は完全に別の円の内側にあり、その周囲は接触しません。つまり、中心間の距離は半径の差(d < | r1 - r2 |)よりも小さくなります。 Example

私がこれまで持っているもの:

  1. 円を比較するために、彼らは彼らが描画される前に、私はのための配列に20個の値を格納するためのループを使用し、指定する必要があります中心座標(int [] x、int [] y)と半径(double [] radius)です。
  2. 次に、ネストされたfor-loopsを使用して、配列全体を繰り返し、2つの円を比較しました。ただし、円がそれ自身(インデックスj = index 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で困惑しています。"*あなたが交差点をどのように決定するかについては制限がないと仮定して、***簡単な***方法を実行することをお勧めします。[複雑な形状による衝突検出](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]); 
     } 
} 
関連する問題