2

私はこれについて率直になります。これは宿題ですが、誰かが私を正しい方向に導き、コードの一部がどのように機能するかを説明してくれますか?指示はコードと質問の下にあります。

これはこれまでの私のコードです:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Rainbow extends JPanel
{
  // Declare skyColor:
     private final Color skyColor = Color.CYAN;

  public Rainbow()
  {
    setBackground(skyColor);
  } 
  // Draws the rainbow.
  public void paintComponent(Graphics g)
  {
super.paintComponent(g);
int width = getWidth();    
int height = getHeight();

// Declare and initialize local int variables xCenter, yCenter
// that represent the center of the rainbow rings:
int xCenter = width/2;
int yCenter = (height * 3) /4;

// Declare and initialize the radius of the large semicircle:
  int largeRadius = width/4;

g.setColor(Color.RED);

// Draw the large semicircle:
 g.fillArc(xCenter,yCenter,largeRadius,height,0,180);
// Declare and initialize the radii of the small and medium
// semicircles and draw them:
int smallRadius = height/4;
 g.setColor(Color.MAGENTA);

 g.fillArc(xCenter,yCenter,width,height,0,180);
 int mediumRadius = (int) Math.sqrt(smallRadius * largeRadius);
 g.setColor(Color.GREEN);
 g.fillArc(xCenter,yCenter,width,height,0,180);


// Calculate the radius of the innermost (sky-color) semicircle
// so that the width of the middle (green) ring is the
// arithmetic mean of the widths of the red and magenta rings:


// Draw the sky-color semicircle:
 g.fillArc(xCenter,yCenter,width,height,0,180);
  }

  public static void main(String[] args)
  {
JFrame w = new JFrame("Rainbow");
w.setBounds(300, 300, 300, 200);
w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = w.getContentPane();
c.add(new Rainbow());
w.setVisible(true);
   }
}

私の質問:fillArcはどのように正確に機能しますか。パラメータに何が含まれるかは理解していますが、各アークが互いに異なるようにするにはどうすればよいですか?アークごとに1つの色をどのように設定しますか?そうしようとすると、最後に最も近い色が表示され、他の色が上書きされてしまいました。コーディングを続けると、おそらくもっと増えるでしょう。

これらは方向性でした:

![ここに画像の説明を入力してください] [1]

「虹」は、4つの重なり合う半円で構成されています。外輪は赤(Color.RED)、中輪は緑(Color.GREEN)、内輪はマゼンタ色(Color.MAGENTA)です。最も内側の半円は背景と同じ色です。

以下の手順に従って、Rainbow.javaの空欄に記入してください。

  1. Rainbowプロジェクトを開始します。

  2. ファイルの先頭にあるクラス宣言の前に、自分の名前を含む完全なコメントヘッダーを追加します。

  3. Rainbowクラスに、Color.CYAN(空の色)に初期化されたColorタイプのプライベート最終フィールドskyColorの宣言を追加します。Rainbowのコンストラクターで、ウィンドウの背景をColor.WHITEではなくskyColorに設定します。

  4. paintメソッドで、リングの中心の座標を表すローカル整数変数xCenterおよびyCenterを宣言します。コンテンツペインの幅1/2と高さ3/4(下)にそれぞれ初期化します。(Javaのグラフィック座標の原点は、コンテンツペインの左上隅にあり、y軸が下を向いていることを思い出してください。)ウィンドウの寸法から固定数を差し込まないでください。

  5. 最大(赤)の半円の半径を表すローカル変数largeRadiusを宣言し、幅の1/4に初期化します。

  6. g.fillArc(x、y、size、size、from、degrees)(すべての整数引数を使用)を呼び出すメソッドは、円の扇形を描画します。xとyは、楕円が(論理的に)内接する長方形(この場合は正方形)の左上隅の座標です。サイズは正方形の辺(および円の直径)です。fromは度単位の円弧の開始点(水平直径の最東端に0があります)であり、度(正の数)は反時計回りに進む円弧の測定値です。ペイントメソッドにステートメントを追加して、最大の(赤の)半円を描画します。プログラムをテストします。

  7. ステートメントを追加して、中(緑)と小(マゼンタ)の半円を表示します。マゼンタの半円の半径は、高さの1/4にする必要があります。緑の半径は、赤の半円の半径とマゼンタの半円の半径の幾何平均(積の平方根)で、最も近い整数に丸められている必要があります。(Math.sqrt(x)を呼び出すと、xの平方根の値であるdoubleが返されます。)プログラムを再テストします。

  8. 虹を完成させるために、背景(「空」)の色の最も内側の半円を表示するステートメントを追加します。この半円の色にはskyColor定数を使用します。真ん中(緑)のリングの幅が赤とマゼンタのリングの幅の算術平均になるように、空の色の半円の半径を選択します。

  9. プログラムをテストします。

  10. 完成したプログラムを送信し、出力を実行します。画面出力(Alt-PrintScrn)をキャプチャし、それをグラフィックプログラム(MSペイントなど)に貼り付けてから、画像をEclipseプロジェクトディレクトリに保存することで、実行出力(虹の画像)を含めることができます。

    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Container;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class Rainbow extends JPanel
    {
      //Declare skyColor:
        private final Color skyColor = Color.CYAN;
    
      public Rainbow()
    {
    setBackground(skyColor);
    }
    
     // Draws the rainbow.
    public void paintComponent(Graphics g)
     {
    super.paintComponent(g);
    int width = getWidth();    
    int height = getHeight();
    
    // Declare and initialize local int variables xCenter, yCenter
    // that represent the center of the rainbow rings:
    int xCenter = width/2;
    int yCenter = (height * 3) /4;
    
    // Declare and initialize the radius of the large semicircle:
      int largeRadius = width/4;
    
    g.setColor(Color.RED);
    
    // Draw the large semicircle:
     g.fillArc(xCenter - largeRadius,yCenter - largeRadius   ,largeRadius,largeRadius,0,180);
    // Declare and initialize the radii of the small and medium
    //semicircles and draw them:
     int smallRadius = height/4;
     int mediumRadius = (int) Math.sqrt(smallRadius * largeRadius);
     g.setColor(Color.GREEN);
     g.fillArc(xCenter-(largeRadius+mediumRadius)/2,yCenter-          (largeRadius+mediumRadius)/2,mediumRadius,mediumRadius,0,180);
     g.setColor(Color.MAGENTA);
     g.fillArc(xCenter-(largeRadius+smallRadius)/2,yCenter-(largeRadius+smallRadius)/2,smallRadius,smallRadius,0,180);
    
    
    
    
    // Calculate the radius of the innermost (sky-color) semicircle
    // so that the width of the middle (green) ring is the
    // arithmetic mean of the widths of the red and magenta rings:
       int skyRadius = (int)((2 * Math.sqrt(smallRadius * largeRadius)) - width/4);
    
    // Draw the sky-color semicircle:
     g.setColor(skyColor);
     g.fillArc(xCenter-skyRadius,yCenter-skyRadius,skyRadius,skyRadius,0,180);
    
     }
    
     public static void main(String[] args)
     {
    JFrame w = new JFrame("Rainbow");
    w.setBounds(300, 300, 300, 200);
    w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Container c = w.getContentPane();
    c.add(new Rainbow());
    w.setVisible(true);
     }
    }
    
4

3 に答える 3

7

fillArc()は、指定したパラメーターに基づいて円のセクションを塗りつぶします。たとえば、最初のアーク。

赤の塗りつぶし円弧(この場合は半円)を描画しています。

//Set the arc color
g.setColor(Color.RED);

// Draw the large semicircle:
g.fillArc(xCenter,yCenter,largeRadius,height,0,180);

サークル

fillArcがあります。それは虹のようには見えません。虹の形を作るには、その中に小さな弧を描く必要があります。あなたの場合、次は緑色です。したがって、色を緑に設定した後、fillArcを再度実行します。ただし、半径を少し縮小して、緑が赤のセクション全体をカバーしないようにしました。ここに画像の説明を入力してください

描画するときは上に描画するので、最初に緑を描画すると、赤で覆われることに注意してください。

次に、この中にもう一度別の円弧を描きますが、これを空の色(この場合は白)にします。これにより、最終的な虹の形が作成されます。したがって、fillArcを再度実行しますが、半径はわずかに小さく、色は白です。

虹!

そしてそこに、私たちは虹を描きました。

この美しい作品を中心に置くには、fillArc関数についていくつか理解する必要があります。

パラメータは次のとおりです。

public abstract void fillArc(int x,
           int y,
           int width,
           int height,
           int startAngle,
           int arcAngle)

intxとintyは、描画している円弧の左上隅の座標を表します。コードが中央に配置されない理由は、円弧の描画方法が原因です。

g.fillArc(xCenter - largeRadius,yCenter - largeRadius,largeRadius,largeRadius,0,180);
g.fillArc(xCenter-(largeRadius+mediumRadius)/2,yCenter-(largeRadius+mediumRadius)/2,mediumRadius,mediumRadius,0,180);
g.fillArc(xCenter-(largeRadius+smallRadius)/2,yCenter-(largeRadius+smallRadius)/2,smallRadius,smallRadius,0,180);

余分なものをいくつか取り出しました。(largeRadius + smallRadius)/ 2と(largeRadius + mediumRadius)/ 2をどのように引いているかわかりますか?これは、虹を中心から外すようにシフトしています。代わりに必要なものは次のとおりです。

g.fillArc(xCenter - largeRadius/2,yCenter - largeRadius,largeRadius,largeRadius,0,180);
    g.fillArc(xCenter-(mediumRadius)/2,yCenter-(largeRadius+mediumRadius)/2,mediumRadius,mediumRadius,0,180);
    g.fillArc(xCenter-(smallRadius)/2,yCenter-(largeRadius+smallRadius)/2,smallRadius,smallRadius,0,180);

これにより、虹が適切に中央に配置されます。これが理由です。

ここに画像の説明を入力してください

それは彼らが弧を描き始めるポイントです。虹全体を中央に配置する場合は、虹全体の幅の半分だけシフトします。したがって、赤い弧を中央に配置したい場合は、

xCenter - (largeRadius/2)

これはxスタートを左半分に設定しているためです。他のアークにはlargeRadiusを含めないでください。これは、これらのアークをこのポイントを中心に配置しているためです。したがって、個々の幅の半分だけシフトしたいので、x位置は次のようになります。

xCenter-(mediumRadius)/2
xCenter-(smallRadius)/2

Y軸を中心にすると動作が異なります。全体的な虹の高さはlargeRadiusの1/4であることを考慮する必要があります。コードはyCenter=3/4 * heightを使用しているため、少し変更されます。

これが私の解決策です

g.fillArc(xCenter - largeRadius/2,yCenter - largeRadius/2 + largeRadius/4 -height/4,largeRadius,largeRadius,0,180);
g.fillArc(xCenter-(mediumRadius)/2,yCenter-(mediumRadius)/2 + largeRadius/4 -height/4,mediumRadius,mediumRadius,0,180);
g.fillArc(xCenter-(smallRadius)/2,yCenter-(smallRadius)/2 + largeRadius/4 -height/4,smallRadius,smallRadius,0,180);

見てみましょう。xと同じ原理で、largeRadius / 2(およびそれぞれの半径)を減算しました。しかし、レインボー全体を下にシフトする必要があるため、largeRadius/4を追加しました。これは、それぞれの半径/ 2を引くと、虹が半円ではなく、まるで円全体であるかのように中央に配置されるだけだからです。

largeRadius / 4を追加すると、虹が全体の高さの半分だけ下にシフトし、半円の中心に正しく配置されます。最後に、height / 4を引くと、yCenterがheight / 2に変更されます。これは、3/4*高さが割り当ての要件であるためです。

コメントのすべての問題について申し訳ありませんが、これで問題が解決したことを願っています。

于 2012-10-04T00:57:20.710 に答える
2

あなたがアイデアを得ることができるように、私はあなたのコードの一部を修正しました。xCenterとyCenterは、fillArcメソッドで使用する必要のある座標ではなく、円の中心を表すことに注意してください。あなたが提供した指示はそれをかなりよく説明しています。私がここでしたことからアイデアを得て、残りを自分で理解することができます。

// First declare and initialize all radiuses
  int largeRadius = width/4;
  int smallRadius = height/4;
  int mediumRadius = (int) Math.sqrt(smallRadius * largeRadius);

//Then draw each arc in descending order from the largest one

g.setColor(Color.RED);

g.fillArc(xCenter-largeRadius,yCenter-largeRadius,largeRadius,largeRadius,0,180);

g.setColor(Color.GREEN);

g.fillArc(xCenter-(largeRadius+mediumRadius)/2,yCenter-(largeRadius+mediumRadius)/2,mediumRadius,mediumRadius,0,180);

g.setColor(Color.MAGENTA);

g.fillArc(xCenter-(largeRadius+smallRadius)/2,yCenter-(largeRadius+smallRadius)/2,smallRadius,smallRadius,0,180);

// Calculate the radius of the innermost (sky-color) semicircle

あなたのためにskyRadiusは考慮します:

  1. 赤の幅=大半径-中半径
  2. 緑の幅=中-小
  3. マゼンタの幅=小さい半径-スカイ半径

私が数学を正しく行った場合、次のようになります:skyRadius = smallRadius-2 *(mediumRadius-smallRadius)+ largeRadius-mediumRadius

int skRadius=smallRadius-2*(mediumRadius-smallRadius)+largeRadius-mediumRadius;
 g.setColor(skyColor);
 g.fillArc(xCenter-(largeRadius+skRadius)/2,yCenter-(largeRadius+skRadius)/2,skRadius,skRadius,0,180);
于 2012-10-04T01:41:58.960 に答える
-1

のはるかに単純な方程式skyRadiusは次のとおりです。

int skyRadius = largeRadius - 3 * mediumRadius + 3 * smallRadius;
于 2016-05-02T15:44:01.800 に答える