java - 如何在 GUI Java 程序中创建圆序列

标签 java user-interface graphics

我是一名业余程序员,目前正在研究 Think Java Book 第二版中的练习 C.2 (page 348 of the PDF) 。本练习的目标是修改名为 Mickey.java 的程序。这样就会显示以下内容:

The output of the program

我的代码如下:

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JFrame;

public class Exercise_Two extends Canvas {

    public static void main(String[] args) {

        JFrame frame = new JFrame("Exercise_Two");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Canvas canvas = new Exercise_Two();
        canvas.setSize(400, 400);
        canvas.setBackground(Color.white);
        frame.add(canvas);
        frame.pack();
        frame.setVisible(true);
    }

    public void paint(Graphics g) {
        Rectangle bb = new Rectangle(100, 100, 200, 200);
        Exercise_Two(g, bb);
    }


    /* Draws a circle given Graphics and Rectangle */
    public void boxOval(Graphics g, Rectangle bb) {   
        g.fillOval(bb.x, bb.y, bb.width, bb.height);
    }


    public void Exercise_Two(Graphics g, Rectangle bb) { 

        boxOval(g, bb); // Draws a circle whose center is in the middle of the screen  

        int hx = bb.width / 2;
        int hy = bb.height / 2;

        // Rectangle(x, y, width, height)
        Rectangle half = new Rectangle(bb.x, bb.y, hx, hy);

        half.translate(-hx / 2, -hy / 2);
        boxOval(g, half);

        half.translate(hx * 2, 0);
        boxOval(g, half);

        /* SOME NOTES TO REMEMBER:
         * - translate by a factor of 4, but set size by a factor of 2 */

        int circle = 4;
        int distance = 2;
        for (int i = 0; i < 3; i++ ) {

              System.out.println(distance);

            // The Set-up and making the first circle 
            half.translate(-(hx * distance), 0);

            hx /= 2; hy /= 2;
            half.translate(-hx / 2, -hy / 2);
            half.setSize(hx, hy);
            boxOval(g, half);

            // Making the other circles 
            for (int j = 0; j < circle - 1; j++) {
                 half.translate(hx * 2, 0);
                 boxOval(g, half);  
            }

            circle *= 2;
            distance *= 3;

        }

    }

}

我使用 for 循环 i 来确定米奇符号将显示多少次。当我将 for 循环设置为当 i < 1 或 i < 2 时结束时,代码似乎运行良好。

当我<1:

enter image description here

当我 < 2 时:

enter image description here

但是,当 i < 3 时,输出不会按计划进行:

enter image description here

话虽如此,您是否可以向我提供有关代码的反馈,告诉我在编写程序时做错了什么?我知道网上有这个练习的答案,但我觉得最好看看我目前做错了什么,以便从中学习。

谢谢,

最佳答案

您没有提供该任务所需的精度...

SOME NOTES TO REMEMBER: - translate by a factor of 4, but set size by a factor of 2

这会导致一些问题,假设我们的 width=100 并将其除以 2 乘以 4:

100 / (2*4) = 12.5

但计算出的值为12,因为hxint

返回,绘制时将圆平移 8 次,结果

8 * 12 = 96

所以你已经在交互 1 中丢失了 4 个像素

但是这 4 个像素还不可见,但是越远,错误就越大......

解决方案

提高计算精度:

double hx = bb.width / 2d; //provide double precision everywhere!
double hy = bb.height / 2d;

...
hx /= 2d; hy /= 2d; //provide double precision everywhere!
half.translate(-hx / 2d, -hy / 2d);
...

double circle = 4d;
double distance = 2d;

编程提示

一旦您以适当的精度提供了数学结果,您就必须再次将它们转回普通的Integer。这种技术称为类型转换,您可以使用方括号来实现此目的。

//high precision calculations with doubles
double hx = bb.width / 2d;
double hy = bb.height / 2d;

//less precise int values
int newWidth = (int)hx;  //use brackets to type cast from double to int
int newHeight = (int)hy; 
Rectangle half = new Rectangle(bb.x, bb.y, newWidth, newHeight);

在此过程中您可能会失去精度! int x = (int) 1.2; 将导致 x = 1 请记住这一点,并始终使用最高精度进行计算,并类型转换这些值仅用于打印(绘图)。

关于java - 如何在 GUI Java 程序中创建圆序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59350479/

相关文章:

java - SOAP 和需要 Java serialVersionUID

java - java字符串数组越界

c++ - 如何使用 D3DPT_TRIANGLESTRIP 基元类型在 DirectX 中绘制两个分离的矩形

java - 区分表格元素

java - 如何使用 kafka 轮询远程目录中的新文件

java - 哪个 LayOut Manager 最适合我的 GUI?

user-interface - 我应该有多少 FPS 来更新自定义进度条?

python - 在 Jython 中使用 JavaCV

c# - 在线程之间同步 VBO 的最佳方式

android - 在 Canvas 上用图形编号替换数字编号