Java 检查程序调试
所以我完成了一个递归绘制线条的程序,它使用一个参数“n”来定义递归的深度。我有两个函数,一个画相对左边的线,另一个画相对右边的线。我对它进行了测试,它似乎适用于前4个级别,但要么行太小,无法准确表示,要么我的代码有问题,因为行之间的中断似乎是任意的。希望有人能测试我的代码,看看他们是否能找到问题所在 下图深度为10 编辑:修复了部分代码,但仍需要帮助Java 检查程序调试,java,graphics,recursion,Java,Graphics,Recursion,所以我完成了一个递归绘制线条的程序,它使用一个参数“n”来定义递归的深度。我有两个函数,一个画相对左边的线,另一个画相对右边的线。我对它进行了测试,它似乎适用于前4个级别,但要么行太小,无法准确表示,要么我的代码有问题,因为行之间的中断似乎是任意的。希望有人能测试我的代码,看看他们是否能找到问题所在 下图深度为10 编辑:修复了部分代码,但仍需要帮助 public class Art { //draws the relatively left line public static void
public class Art
{
//draws the relatively left line
public static void drawLeftLine(double x0, double y0, double x1, double y1)
{
//define new x coordinate for line
//double x2 = (1/3.0)*(x1 - x0);
//color of line
StdDraw.setPenColor(StdDraw.BLUE);
//draw line by adding new x coord to original
StdDraw.line(x0, y0, x1, y1);
}
//draw relatively right line
public static void drawRightLine(double x0, double y0, double x1, double y1)
{
//define new x coord for line
//double x2 = (2/3.0)*(x1 - x0);
//color of line
StdDraw.setPenColor(StdDraw.BLUE);
//draw line by adding new x coord to original
StdDraw.line(x0, y0, x1, y1);
}
public static void cantor(int n, double x0, double y0, double x1, double y1)
{
if (n == 0)
return;
drawLeftLine(x0, y0, x1, y1);
drawRightLine(x0, y0, x1, y1);
y0 = y0 - 0.1;
y1 = y1 - 0.1;
cantor(n-1, x0, y0, x0 + ((x1 - x0))/3.0, y1); //left
cantor(n-1, (2.0/ 3) * (x1 - x0) + x0, y0, x1, y1); //right
}
public static void main(String[] args)
{
//change n into integer (depth)
int n = Integer.parseInt(args[0]);
//specify inital values for line
double x0 = 0;
double y0 = 0.9;
double x1 = 0.9;
double y1 = 0.9;
//recursive function cantor
cantor(n, x0, y0, x1, y1);
}
}
我认为该图形看起来不正确,因为所有漂亮的双精度值都被离散像素近似,导致线段之间出现不必要的重叠(请参见底部的编辑)。但是,对您的代码有一些评论: 1) 您不需要
drawLeftLine
和drawRightLine
方法,因为当前它们绘制的内容完全相同。因为在每个步骤中,您都要调用两次cantor
(删除的内部三分之一的每侧一次),所以对于必须绘制的每个线段,您都要调用一次cantor
。因此,我会将所有的绘图直接放入cantor
方法中
2) 由于y0
和y1
都是相同的,我将把它们简化为一个y
变量
3) 我将简化计算新的x0
和x1
值的数学,直到
double third = (x1 - x0) / 3;
cantor(n - 1, x0, x0 + third, y); // left
cantor(n - 1, x1 - third, x1, y); // right
4) 不是每次都将y
值递减0.1
,而是应该有一个全局变量来决定递减的量(否则,如果尝试n>10
,事情就会破裂)。此值只能设置为1.0/n
5) 您不需要每次绘制时都设置笔的颜色。您可以在main方法中只设置一次
6) StdDraw
已经在正在绘制的图片周围设置了边框,因此无需从0.9
开始坐标-您可以使用1
根据这些建议,代码如下所示:
private static double yIncrement;
public static void cantor(int n, double x0, double x1, double y) {
if (n == 0)
return;
StdDraw.line(x0, y, x1, y);
y = y - yIncrement;
double third = (x1 - x0) / 3;
cantor(n - 1, x0, x0 + third, y); // left
cantor(n - 1, x1 - third, x1, y); // right
}
public static void main(String[] args) {
//change n into integer (depth)
int n = Integer.parseInt(args[0]);
// specify inital values for line
double x0 = 0;
double x1 = 1;
double y = 1;
yIncrement = 1.0 / n;
StdDraw.setPenColor(Color.BLUE);
// recursive function cantor
cantor(n, x0, x1, y);
}
编辑:使用StdDraw
canvas size、canvas scaling设置和线段端点舍入模式,您可以获得稍微好一点的图片(下面的代码生成的图片在8级以下看起来基本正确)
要以绝对正确的方式显示到第十级的所有内容,您需要3^9像素(19K像素)的宽度。对于9级,这是3^8=6K。对于级别8,这是3^7=2k,这就是为什么它看起来几乎正确,具有1.9K像素宽度和整数舍入。我实际上不允许弄乱此项目的画布大小,但我将在几分钟内尝试实现这一点。这看起来很棒,而且听到这可能是一个图形错误也很棒。你就是那个人!非常感谢。
private static double yIncrement;
public static void cantor(int n, double x0, double x1, double y) {
if (n == 0)
return;
x0 = Math.ceil(x0);
x1 = Math.floor(x1);
StdDraw.line(x0, y, x1, y);
y = y - yIncrement;
double third = (x1 - x0) / 3;
cantor(n - 1, x0, x0 + third, y); // left
cantor(n - 1, x1 - third, x1, y); // right
}
public static void main(String[] args) {
// change n into integer (depth)
int n = Integer.parseInt(args[0]);
int width = 1920;
int height = 1080;
StdDraw.setCanvasSize(width, height);
// specify inital values for line
double x0 = 0;
double x1 = width;
double y = 1;
yIncrement = 1.0 / n;
StdDraw.setPenColor(Color.BLUE);
StdDraw.setXscale(0, width);
// recursive function cantor
cantor(n, x0, x1, y);
}