检查程序调试

时间:2013-10-04 13:00:02

标签: java graphics recursion

所以我完成了一个递归绘制线条的程序,它接受一个参数“n”来定义递归的深度。我有2个函数,一个绘制相对左边的线,另一个绘制相对正确的线。我测试了它似乎适用于前4个级别,但是然后这些线条变得太小而无法准确表示或者我的代码出现了问题,因为线条之间的中断似乎变得随意。希望有人可以测试我的代码,看看他们是否能找到问题所在。

以下图片深度为10。

编辑:修复了部分代码,但仍然需要帮助

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 个答案:

答案 0 :(得分:4)

我认为图形看起来不正确,因为所有漂亮的双值都是用离散像素近似,导致线段之间出现不必要的重叠(参见底部的编辑)。但是有关您的代码的一些评论:

1)您不需要drawLeftLinedrawRightLine方法,因为目前它们绘制的内容完全相同。由于您在每个步骤调用cantor两次(对于删除的内部三分之一的每一侧一次),因此对于必须绘制的每个线段,您只需调用cantor。因此,我会将所有绘图直接放入cantor方法。

2)由于y0y1都是相同的,我会将它们简化为一个y变量。

3)我会简化数学计算新的x0x1值到

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画布大小,画布缩放设置和线段端点舍入模式,您可以获得更好的画面(下面的代码生成的图片看起来大致正确到8级)

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

要以绝对正确的方式将所有内容显示到第十级,您需要宽度为3 ^ 9像素(19K像素)。对于等级9,其为3 ^ 8 = 6K。对于等级8,即3 ^ 7 = 2k,这就是为什么它看起来几乎正确,具有1.9K像素宽度和整数舍入。