打印出一个 ASCII 圆和轴

Print out an ASCII circle and axes

此程序在笛卡尔平面中打印一个圆。

输入为:半径、圆心坐标 (cx,cy) 以及我们要打印圆的字符。

如果圆上的点与坐标轴重合,则点优先。我在方法 drawCircle 中写了打印轴的条件,但是图像失真了...

我有什么问题...有人可以帮我找出我的错误吗?

这是我的整个程序(有问题的方法是最后一个,drawCircle):

public class Circle {
  public static void main(String[] args) {
    System.out.println(onCircle(1, 2, 3, 4, 5));

    drawCircle(1, 3, 3, '*');
    drawCircle(3, 3, 3, '*');
    drawCircle(5, 10, 12, '*');
  }

  //Question 1A
  public static boolean onCircle(int radius, int cx, int cy, int x, int y) {
    //default answer is false, but if the
    //inequality holds then it is set to true
    boolean isDrawn = false;
    if (Math.pow(radius,2)<=(Math.pow((x-cx),2)+Math.pow((y-cy),2))
        && (Math.pow((x-cx),2)+Math.pow((y-cy),2))<=(Math.pow(radius,2)+1)) {
      isDrawn = true;
    }
    return isDrawn;
  }

  //Question 1B
  public static void verifyInput(int radius, int cx, int cy) {
    //if radius is negative, display error message
    if (radius <= 0) {
      throw new IllegalArgumentException(
                "The radius of the circle must be a positive number.");
    }
    //if the center of the circle with radius 'radius' causes the circle
    //to 'overflow' into other quadrants, display error message
    if ((cx - radius) < 0 || (cy - radius) < 0) {
      throw new IllegalArgumentException(
                "the circle with requested parameters does not fit " +
                "in the quadrant. Consider moving the center of the " +
                "circle further from the axes.");
    }
  }

  //Question 1C
  public static void drawCircle(int radius, int cx, int cy, char symbol) {
    verifyInput(radius, cx, cy);
    //set the values for extension of the axes (aka how long are they)
    int xMax = cx + radius + 1;
    int yMax = cy + radius + 1;
    for (int j = yMax; j >= 0; j--) {
      for (int i = 0; i <= xMax; i++) {
        //set of if-block to print the axes
        if (i == 0 && j == 0) {
          System.out.print('+');
        } else if (i == 0) {
          if (j == yMax) {
            System.out.print('^');
          }
          if (j != yMax && onCircle(radius, cx, cy, i, j) == false) {
            System.out.print('|');
          }
        } else if (j == 0) {
          if (i == xMax) {
            System.out.print('>');
          }
          if (i != xMax && onCircle(radius, cx, cy, i, j) == false) {
            System.out.print('-');
          }
        }

        //if block to print the circle
        //verify for each coordinate (i,j)
        //in the quadrant if they are on circle
        //if =true print symbol, if =false print empty character
        if (onCircle(radius, cx, cy, i, j) == true) {
          System.out.print(symbol);
        } else {
          System.out.print(' ');
        }
      }
      System.out.println();
    }
  }
}

这是我得到的:

false
^      
|  *** 
|  * * 
|  *** 
|      
+ - - - - > 
^        
|  ***   
|        
*     * 
*     * 
*     * 
|        
+ - ***- - > 
^                 
|         ***     
|       *     *   
|      *       *  
|                 
|     *         * 
|     *         * 
|     *         * 
|                 
|      *       *  
|       *     *   
|         ***     
|                 
|                 
|                 
|                 
|                 
|                 
+ - - - - - - - - - - - - - - - > 

正如你所看到的,第一个和第三个圆很好,但是与轴重叠的那个被扭曲了。

您缺少 3 个 continue 语句。 查看您的 drawCircle 方法的修订版:

public static void drawCircle(int radius, int cx, int cy, char symbol) {
    verifyInput(radius, cx, cy);

    //set the values for extension of the axes (aka how long are they)
    int xMax = cx + radius + 1;
    int yMax = cy + radius + 1;

    for (int j = yMax; j >= 0; j--) {
        for (int i = 0; i <= xMax; i++) {
            //set of if-block to print the axes
            if (i == 0 && j == 0) {
                System.out.print('+');
                continue;
            } else if (i == 0) {
                if (j == yMax) {
                    System.out.print('^');
                }
                if (j != yMax && onCircle(radius, cx, cy, i, j) == false) {
                    System.out.print('|');
                    continue;
                }
            } else if (j == 0) {
                if (i == xMax) {
                    System.out.print('>');
                }
                if (i != xMax && onCircle(radius, cx, cy, i, j) == false) {
                    System.out.print('-');
                    continue;
                }
            }

            //if block to print the circle
            //verify for each coordinate (i,j)
            //in the quadrant if they are on circle
            //if =true print symbol, if =false print empty character
            if (onCircle(radius, cx, cy, i, j) == true) {
                System.out.print(symbol);
            } else {
                System.out.print(' ');
            }
        }
        System.out.println();
    }
}

实际上在调试时,您的 onCircle 方法获取 x=0y=4cx=3cy=3:

您有:

Math.pow(radius=3, 2) = 9
Math.pow((x - cx), 2) = 9
Math.pow((y - cy), 2) = 1

因此

Math.pow(radius, 2) <= Math.pow((x - cx), 2) + Math.pow((y - cy), 2)

returns

然后:

(Math.pow((x-cx),2) = 9
 Math.pow((y-cy),2)) = 1
(Math.pow(radius,2)+1)) = 10

因此

(Math.pow((x-cx),2)+Math.pow((y-cy),2)) <= (Math.pow(radius,2)+1))

returns 也

因此onCircle(radius,cx,cy,i,j)returnstrue对于这个坐标

这就是绘制符号的原因。你需要改进你的算法!

以原点为圆心的一般方程:

Java中可以这样实现:

i*i + j*j == r*r

但是在整数坐标系的情况下,你必须这个方程以某种方式使圆的所有点反映在这个坐标系中:

(int) Math.sqrt(i*i + j*j) == r

如果r=8,则圆和轴如下所示:

r=8
        * * * * * * * * *         
      * *       *       * *       
    *           *           *     
  *             *             *   
* *             *             * * 
*               *               * 
*               *               * 
*               *               * 
* * * * * * * * * * * * * * * * * 
*               *               * 
*               *               * 
*               *               * 
* *             *             * * 
  *             *             *   
    *           *           *     
      * *       *       * *       
        * * * * * * * * *         

Try it online!

int r = 8;
System.out.println("r=" + r);
IntStream.rangeClosed(-r, r)
        .peek(i -> IntStream.rangeClosed(-r, r)
                .mapToObj(j -> i == 0 || j == 0 ||
                        (int) Math.sqrt(i*i + j*j) == r ?
                        "* " : "  ")
                .forEach(System.out::print))
        .forEach(i -> System.out.println());

另请参阅: