【问题标题】:Some help on a Java program to draw a rainbowJava程序绘制彩虹的一些帮助
【发布时间】:2012-09-24 23:47:06
【问题描述】:

对此我会坦诚相待;这是一项家庭作业,但是有人可以指导我正确的方向并向我解释代码的某些部分应该如何工作吗?说明在代码和问题下方。

这是我目前的代码:

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. 启动 Rainbow 项目。

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

【问题讨论】:

  • 你截图上的颜色对比让我的眼睛很痛......
  • 您是否有不明白的具体问题?

标签: java swing draw background-color


【解决方案1】:

fillArc() 根据您给它的参数填充圆的一部​​分。例如你的第一条弧线。

您正在绘制填充弧,在本例中是一个半圆形,颜色为红色。

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

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

这就是我们的填充弧。那看起来一点也不像彩虹。为了得到彩虹的形状,我们必须在里面画一个更小的弧线。在你的情况下,下一个是绿色的。所以我们在将颜色设置为绿色后再次填充弧。但是我们将半径缩小了一点,所以绿色不会覆盖整个红色部分。

请记住,当我们绘制时,我们是在顶部绘制,所以如果您先绘制绿色,它会被红色覆盖。

然后我们再次在其中绘制另一条弧线,但将其设为天空的颜色(在本例中为白色)。这将创建最终的彩虹形状。所以我们再次填充圆弧,但半径稍小,颜色为白色。

在那里,我们画了一条彩虹。

为了使这个美丽的创作居中,我们必须了解有关 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 * 高度,因此对其进行了一些更改。

这是我的解决方案

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 * 高度是您的作业要求。

对 cme​​ts 中的所有问题感到抱歉,希望这能解决问题。

【讨论】:

  • xCenter 和 yCenter 的目的仅仅是定位屏幕上开始绘图的点吗?
  • 将 xCenter 和 yCenter 视为半圆所在的圆心。
  • 我完成了大部分彩虹,但我无法让最里面的部分适应条件:添加语句以显示背景颜色的最内半圆(“天空”)颜色以完成彩虹.使用 skyColor 常量作为这个半圆的颜色。选择天空颜色半圆的半径,使中间(绿色)环的宽度是红色和品红色环宽度的算术平均值。我将在问题中发布我更新的代码。
  • 其实我认为涵盖的其他答案必须绘制天空半径。
  • 感谢您的帮助。你知道为什么我运行程序时屏幕上的彩虹有点偏吗?这只是 int xCenter = width/2; 中的一个问题吗? ?我将函数更改为 xCenter = (width * 29)/48;并把它放在中心。然而,方向告诉我使用 1/2 宽度,并且不知何故,彩虹在中心使用 1/2 而不是另一个值。
【解决方案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);

【讨论】:

    【解决方案3】:

    skyRadius 的一个更简单的等式是:

    int skyRadius = largeRadius - 3 * mediumRadius + 3 * smallRadius;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-30
      • 1970-01-01
      • 1970-01-01
      • 2017-10-05
      • 1970-01-01
      相关资源
      最近更新 更多