【问题标题】:How to print out a hollow circle in c using just characters/symbols如何仅使用字符/符号在 c 中打印出一个空心圆圈
【发布时间】:2021-03-02 14:59:01
【问题描述】:

给定用户圆的半径,程序应使用等式 (x^2+y^2=r^2) 打印出圆。

它有效,但我没有得到任何东西:

  1. 为什么圆的点这么少,有没有办法让更多的点?
  2. 为什么它看起来更像椭圆/椭圆?

代码:

#include <stdio.h>
#include <stdlib.h>
void display(int r){
    int x,y;
    // x and y representing coordinates on an imaginary cartisian plane 
    for(x=-r;x<=r;x++)
    {  
        printf("\t\t\t");//some tabs to make it kinda "centered"
        for(y=-r;y<=r;y++)
        {
            /*if the coordinate:(x,y) is a point of the equation x^2+y^2=r^2 prints the char:*, if 
            not leaves that space empty*/
            if( x*x+y*y == r*r) 
                printf("*");
            else
                printf(" ");
        }
        printf("\n");
    }
}
int main(){
    int r;
    printf("Enter radius:");
    scanf("%d",&r);
    display(r);
    return 0;
}

【问题讨论】:

  • “圆圈的每个字符” - 嗯?一定是错过了几何课……
  • (1) 点数只能与r 指定的一样多。 (2) 大概是因为您终端中的字符比它们的宽度高。
  • @mkrieger1 有没有办法解决第一个问题?
  • 提示:用if (x * x + y * y - r * r &lt; 1)替换你的条件,看看会发生什么。
  • 您可能想查看 brasenham 的圆光栅化算法...here you go

标签: c math terminal geometry


【解决方案1】:

为什么圆的点这么少,有没有办法让更多的点?

原因是您无法表示小数部分,您在终端中处理整数和字符。您可以将 r 乘以 4(小心溢出)并减小终端的 fontSize 以实现此结果。

为什么它看起来更像椭圆/椭圆?

终端中的字符高度大于宽度。原因是能够舒适地阅读它们,并且可能还与 16/9 分辨率有关。

您可以通过调整方程式再次获得所需的输出...但此时您可能只想使用图形库!除非你有一些 ASCII 艺术...

_____  // I used 4 dash horizontally and 3 vertically.
_   _
_____

【讨论】:

    【解决方案2】:
    1. 条件x*x + y*y == r*r 仅在xyr 描述直角三角形的边长时才满足。对于整数,只有 3,4,5 和 5,12,13 等“毕达哥拉斯三元组”满足该条件。

      允许x*x + y*y 落在以r*r 为中心的范围内,例如,在 (r-½)² 和 (r) 之间,可以绘制更多点>+½)²。

      因为 (r-½)² = r²-r+¼,并且 (r+ ½)² = r²+r+¼,为简单起见,我们可以忽略 ¼,并使用范围 r*r-rr*r+r

    #include <stdio.h>
    #include <stdlib.h>
    void display(int r){
        int x,y;
        int xsq, ysq;
        int rsq = r*r;
        // x and y representing coordinates on an imaginary cartisian plane 
        for(x=-r;x<=r;x++)
        {  
            xsq = x*x;
            printf("\t\t\t");//some tabs to make it kinda "centered"
            for(y=-r;y<=r;y++)
            {
                /*if the coordinate:(x,y) is a point of the equation x^2+y^2=r^2 prints the char:*, if 
                not leaves that space empty*/
                int ysq = y*y;
                int dsq = xsq + ysq;
                if( dsq > rsq - r && dsq < rsq + r)
                    printf("*");
                else
                    printf(" ");
            }
            printf("\n");
        }
    }
    int main(){
        int r;
        printf("Enter radius:");
        scanf("%d",&r);
        display(r);
        return 0;
    }
    

    输入/输出:

    $ circle
    Enter radius:10
                                   *******
                                 **       **
                                *           *
                               *             *
                              *               *
                             *                 *
                             *                 *
                            *                   *
                            *                   *
                            *                   *
                            *                   *
                            *                   *
                            *                   *
                            *                   *
                             *                 *
                             *                 *
                              *               *
                               *             *
                                *           *
                                 **       **
                                   *******
    

    考虑到 (r-½)² 和 (r+½)² 展开式忽略的 ¼,条件可以从 dsq &gt; rsq - r &amp;&amp; dsq &lt; rsq + r 更改到dsq &gt; rsq - r &amp;&amp; dsq &lt;= rsq + r。这会稍微改变一些半径的输出。

    1. 圆形看起来被拉伸了,因为字体使用了非正方形的矩形网格。

    【讨论】:

      【解决方案3】:

      首先,默认情况下字符的纵横比为 1:2,因此为避免出现椭圆形,您必须每点打印 2 个字符。

      并且还要填补点之间的空白,您必须插入这些空白 这是一个简单的解决方案:

      #include <stdio.h>
      #include <stdlib.h>
      void display(int r)
      {
          int x, y;
          // x and y representing coordinates on an imaginary cartisian plane
          for (x = -r; x <= r; x++)
          {
              printf("\t\t\t"); //some tabs to make it kinda "centered"
              for (y = -r; y <= r; y++)
              {
                  if (abs(x * x + y * y - r * r) < r - 1)
                      printf("**");
                  else
                      printf("--");
              }
              printf("\n");
          }
      
          for (x = -r; x <= r; x++)
          {
              printf("\t\t\t"); //some tabs to make it kinda "centered"
              for (y = -r; y <= r; y++)
              {
                  printf("%s%d", (abs(x * x + y * y - r * r) > 10 ? " " : "  "), abs(x * x + y * y - r * r));
              }
              printf("\n");
          }
      }
      int main()
      {
          int r;
          printf("Enter radius:");
          scanf("%d", &r);
          display(r);
          return 0;
      }
      
      Enter radius:6
                                      **********        
                                    **          **      
                                  **              **    
                                **                  **  
                              **                      **
                              **                      **
                              **                      **
                              **                      **
                              **                      **
                                **                  **  
                                  **              **    
                                    **          **      
                                      **********   
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-15
        • 2021-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多