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

我必须打印一个圆(输入它的半径、圆心的坐标(cxcy)以及绘制它的字符)。

我为轴和圆编写了一系列 if 块。如果我单独使用它们,它们会很好地工作,但是当我将它们放在同一个方法中(我必须只有一种方法)时,它们会以一种不受欢迎的方式重叠。

注意:如果字符与轴重叠,则字符优先。

public static void drawCircle(int radius, int cx, int cy, char symbol) {
    // this method verifies that there are no negative
    // values involved (throws error/exception)
    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) {
                    System.out.println('|');
                }
            } else if (j == 0) {
                if (i == xMax) {
                    System.out.println('>');
                }
                if (i != xMax) {
                    System.out.print('-');
                }
            }

            // if block to print the circle
            if (onCircle(radius, cx, cy, i, j) == true) {
                System.out.print('*');
            } else {
                System.out.print(' ');
            }
        }
        // I'm not sure if I need to use the print here V
        // System.out.println()
    }
}

这是onCircle 方法。它验证每个i,j 是否在要绘制的圆的轮廓上。

public static boolean onCircle(int radius, int cx, int cy, int x, int y) {
    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;
}

这是我的输出(没有最后的打印语句):

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

这是我的输出(最后一个打印语句):

^

|
   ***
|
  *   *
|
  *   *
|
  *   *

+ - - - - -*-*-*- >

这是我应该得到的:

【问题讨论】:

    标签: java geometry ascii-art


    【解决方案1】:

    一般的圆方程

    Java中可以这样实现:

    (x-a)*(x-a) + (y-b)*(y-b) == r*r
    

    整数坐标系的情况下,可以像这样四舍五入

    (int) Math.sqrt((x-a)*(x-a) + (y-b)*(y-b)) == r
    

    如果半径r=12和圆心a=5,b=1,那么圆和轴看起来像这样:

    r=12,a=5,b=1
                        ^y                                        
                        |                                         
                        |                                         
                        | * * * * * * * * *                       
                      * *                   * *                   
                  * *   |                       * *               
                * *     |                         * *             
              * *       |                           * *           
              *         |                             *           
            *           |                               *         
            *           |                               *         
          *             |                                 *       
          *             |                                 *       
          *             |                                 *       
          *             |                                 *       
          *             |         *                       *       
    ------* ------------+---------------------------------* ---->x
          *             |                                 *       
          *             |                                 *       
          *             |                                 *       
            *           |                               *         
            *           |                               *         
              *         |                             *           
              * *       |                           * *           
                * *     |                         * *             
                  * *   |                       * *               
                      * *                   * *                   
                        | * * * * * * * * *                       
                        |                                         
                        |                                         
                        |                                         
    

    Try it online!

    // radius
    int r = 12;
    // center of the circle
    int a = 5, b = 1;
    // whitespace
    int s = 3;
    // print area
    int xMin = a-r-s, xMax = a+r+s;
    int yMin = b-r-s, yMax = b+r+s;
    
    // output an ASCII circle and axes
    System.out.println("r="+r+",a="+a+",b="+b);
    for (int y = yMax; y >= yMin; y--) {
        for (int x = xMin; x <= xMax; x++) {
            if ((int) Math.sqrt((x-a)*(x-a) + (y-b)*(y-b)) == r) {
                // circle
                System.out.print("* ");
            } else if (x == a && y == b) {
                // center of the circle
                System.out.print("* ");
            } else if (x == 0 && y == 0) {
                // origin of coordinates
                System.out.print("+-");
            } else if (x == 0) {
                // ordinate axis - y
                System.out.print(y == yMax ? "^y" : "| ");
            } else if (y == 0) {
                // abscissa axis - x
                System.out.print(x == xMax ? ">x" : "--");
            } else {
                // whitespace
                System.out.print("  ");
            }
        }
        // new line
        System.out.println();
    }
    

    另见:
    Print out an ASCII circle and axes
    Print out an ASCII circle of the specified width

    【讨论】:

      【解决方案2】:

      看起来格式问题是您有时使用System.out.println,而您应该使用System.out.printSystem.out.println 将结束当前行,因此每个输出行只能使用一次。因此,您应该只在外部 (j) 循环的末尾有一个空的 System.out.printlnstatement,并在程序的其余部分使用 System.out.print

      您还需要修复水平轴的打印,因为此时它将打印轴和圆,而不仅仅是圆。

      【讨论】:

        【解决方案3】:

        jwaddell 是对的,您的代码只需要像这样的 5 次小更新(参见 // &lt;-- 之类的评论):

        public static void drawCircle(int radius, int cx, int cy, char symbol) {
          // this method verifies that there are no negative
          // values involved (throws error/exception)
          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 (onCircle(radius, cx, cy, i, j) == true) { // <-- draw circle first
                System.out.print(symbol);  // <-- use param 'symbol' here
              } else if (i == 0 && j == 0) {
                System.out.print('+');
              } else if (i == 0) {
                if (j == yMax) {
                  System.out.print('^');
                }
                if (j != yMax) {
                  System.out.print('|'); // <-- don't print new line here
                }
              } else if (j == 0) {
                if (i == xMax) {
                  System.out.print('>'); // <-- don't print new line here
                }
                if (i != xMax) {
                  System.out.print('-');
                }
              } else {
                System.out.print(' ');
              }
            }
            System.out.println(); // <-- then add new line here
          }
        }
        

        您可以像这样优化onCircle

        public static boolean onCircle(int radius, int cx, int cy, int x, int y) {
          double distance2 = Math.pow((x - cx), 2) + Math.pow((y - cy), 2);
          double radius2 = Math.pow(radius, 2);
        
          return radius2 <= distance2 && distance2 <= (radius2 + 1.0d);
        }
        

        drawCircle(5, 10, 12, '&amp;'); 的结果符合预期:

        ^                
        |        &&&     
        |      &     &   
        |     &       &  
        |                
        |    &         & 
        |    &         & 
        |    &         & 
        |                
        |     &       &  
        |      &     &   
        |        &&&     
        |                
        |                
        |                
        |                
        |                
        |                
        +--------------->
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-06-17
          • 2016-12-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多