【问题标题】:Print out an ASCII circle and axes打印出一个 ASCII 圆和轴
【发布时间】:2017-02-24 20:32:45
【问题描述】:

这个程序在笛卡尔平面上打印一个圆。

输入是:半径、圆心坐标 (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
^      
|  *** 
|  * * 
|  *** 
|      
+ - - - - > 
^        
|  ***   
|        
*     * 
*     * 
*     * 
|        
+ - ***- - > 
^                 
|         ***     
|       *     *   
|      *       *  
|                 
|     *         * 
|     *         * 
|     *         * 
|                 
|      *       *  
|       *     *   
|         ***     
|                 
|                 
|                 
|                 
|                 
|                 
+ - - - - - - - - - - - - - - - > 

如您所见,第 1 和第 3 圈很好,但与轴重叠的那圈变形了。

【问题讨论】:

    标签: java geometry ascii-art


    【解决方案1】:

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

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

    另见:Print out an ASCII star in java

    【讨论】:

      【解决方案2】:

      您缺少 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();
          }
      }
      

      【讨论】:

        【解决方案3】:

        实际上在调试时,您的 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)
        

        返回 true

        然后:

        (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))
        

        也返回 true

        因此onCircle(radius,cx,cy,i,j) 为该坐标返回true

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-06-17
          • 1970-01-01
          • 2020-03-31
          • 2017-04-27
          • 2016-12-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多