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]

“彩虹”由四个重叠的半圆组成。外圈为红色(Color.RED),中间为绿色(Color.GREEN),内圈为洋红色(Color.MAGENTA)。最里面的半圆与背景颜色相同。

按照下面的说明填写 Rainbow.java 中的空白。

  1. 启动彩虹项目。

  2. 在文件顶部的类声明之前添加一个带有您的姓名的完整注释标题。

  3. 向 Rainbow 类添加 Color 类型的私有最终字段 skyColor 的声明,初始化为 Color.CYAN(天空的颜色)。在 Rainbow 的构造函数中,将窗口的背景设置为 skyColor 而不是 Color.WHITE。

  4. 在paint 方法中,声明表示环中心坐标的局部整数变量xCenter 和yCenter。分别将它们初始化为内容窗格的 1/2 宽度和 3/4 高度(向下)。(回想一下,Java 中图形坐标的原点位于内容窗格的左上角,y 轴指向下方。)不要插入来自窗口尺寸的固定数字。

  5. 声明一个表示最大(红色)半圆半径的局部变量 largeRadius,并将其初始化为宽度的 1/4。

  6. 一个方法调用 g.fillArc(x, y, size, size, from, degree) (带有所有整数参数)绘制一个圆的扇区。x 和 y 是矩形(在本例中为正方形)左上角的坐标,椭圆(逻辑上)内接在该矩形中;size 是正方形的边(和圆的直径);from 是弧的起点,以度为单位(水平直径的最东端为 0),度(正数)是弧的度量,逆时针方向。在paint方法中添加一个语句来绘制最大(红色)的半圆。测试你的程序。

  7. 添加语句以显示中等(绿色)和小(洋红色)半圆。洋红色半圆的半径应为高度的 1/4。绿色的半径应该是红色半圆半径和洋红色半圆半径的几何平均值(乘积的平方根),四舍五入到最接近的整数。(对 Math.sqrt(x) 的调用返回 x 的平方根的值,一个双精度值。)重新测试你的程序。

  8. 添加语句以显示背景(“天空”)颜色的最内半圆以完成彩虹。对这个半圆的颜色使用 skyColor 常量。选择天空颜色半圆的半径,使中间(绿色)环的宽度是红色和品红色环宽度的算术平均值。

  9. 测试你的程序。

  10. 提交您完成的程序并运行输出。您的运行输出(彩虹图片)可以通过捕获屏幕输出(Alt-PrintScrn),将其粘贴到图形程序(例如 MS Paint)中,然后将图像保存到您的 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 函数的一些事情。

参数是:

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

int x 和 int y 表示您正在绘制的弧的左上角的坐标。您的代码未居中的原因是您绘制弧线的方式。

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 * height 是您分配的要求。

对评论中的所有问题感到抱歉,希望这能解决问题。

于 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 回答