我是一名业余程序员,目前正在研究 Think Java Book 第二版中的练习 C.2 (page 348 of the PDF) 。本练习的目标是修改名为 Mickey.java 的程序。这样就会显示以下内容:
我的代码如下:
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:
当我 < 2 时:
但是,当 i < 3 时,输出不会按计划进行:
话虽如此,您是否可以向我提供有关代码的反馈,告诉我在编写程序时做错了什么?我知道网上有这个练习的答案,但我觉得最好看看我目前做错了什么,以便从中学习。
谢谢,
最佳答案
您没有提供该任务所需的精度...
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,因为hx
是int
。
返回,绘制时将圆平移 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/