使用Python在控制台绘制圆形

6
我想在控制台中使用字符而不是像素绘制一个圆,为此我需要知道每行有多少像素。输入直径后,您需要输出图片每行的像素宽度列表。
例如:
输入:7
输出:[3, 5, 7, 7, 7, 5, 3]

enter image description here

输入:12

输出:[4, 8, 10, 10, 12, 12, 12, 12, 10, 10, 8, 4]

enter image description here

这怎么实现?


1
请阅读 https://stackoverflow.com/help/how-to-ask 。您尝试过什么吗?除非您能展示出您所尝试的并解释您遇到了哪些问题,否则我们无法开始帮助您!您知道如何在控制台中打印输出吗?您知道如何循环吗?您已经安装了Python吗?您理解这个问题吗?您是想像问题标题所说的那样“画一个圆”,还是“输出每行将使用多少字符来画一个圆”? - JeffUK
3个回答

3
这提醒我在混合零基和一基计算时要小心。在这种情况下,我必须考虑到for循环是以零为基础的,但直径除以2的商是以1为基础的。否则,图形会超过或低于1。
顺便说一句,当我匹配了您关于“7”的答案时,我没有得到完全相同的“12”情况下的图形:
注意-使用Python 3.9.6测试。
pixels_in_line = 0
pixels_per_line = []

diameter = int(input('Enter the diameter of the circle: '))

# You must account for the loops being zero-based, but the quotient of the diameter / 2 being
# one-based. If you use the exact radius, you will be short one column and one row.
offset_radius = (diameter / 2) - 0.5

for i in range(diameter):
    for j in range(diameter):
        x = i - offset_radius
        y = j - offset_radius
        if x * x + y * y <= offset_radius * offset_radius + 1:
            print('*', end='  ')
            pixels_in_line += 1
        else:
            print(' ', end='  ')
    pixels_per_line.append(pixels_in_line)
    pixels_in_line = 0
    print()

print('The pixels per line are {0}.'.format(pixels_per_line))

7 的输出结果:

Enter the diameter of the circle: 7
      *  *  *        
   *  *  *  *  *     
*  *  *  *  *  *  *  
*  *  *  *  *  *  *  
*  *  *  *  *  *  *  
   *  *  *  *  *     
      *  *  *        
The pixels per line are [3, 5, 7, 7, 7, 5, 3].

12 的输出:

Enter the diameter of the circle: 12
               *  *                 
         *  *  *  *  *  *           
      *  *  *  *  *  *  *  *        
   *  *  *  *  *  *  *  *  *  *     
   *  *  *  *  *  *  *  *  *  *     
*  *  *  *  *  *  *  *  *  *  *  *  
*  *  *  *  *  *  *  *  *  *  *  *  
   *  *  *  *  *  *  *  *  *  *     
   *  *  *  *  *  *  *  *  *  *     
      *  *  *  *  *  *  *  *        
         *  *  *  *  *  *           
               *  *                 
The pixels per line are [2, 6, 8, 10, 10, 12, 12, 10, 10, 8, 6, 2].

太棒了!恭喜。我建议使用if x ** 2 + y ** 2 <= offset_radius ** 2 + 1:代替if x * x + y * y <= offset_radius * offset_radius + 1:。另外,您可以将所有的*放在一个字符串中(用'\n'连接行),并一次性打印该字符串。不需要打印每个像素,并且不需要在循环内计算每个*的数量(可以使用list.count('*')方法进行计数)。我认为这将是更清晰的代码,只需三个步骤:(1)生成字符串,(2)打印字符串,(3)统计字符串中每行的“像素”数量并打印报告。 - Yuri Khristich

3

根据Rob的解决方案所有功劳归Rob!),我已经成功地为12x12像素网格调整了代码:

diameter = 12

radius = diameter / 2 - .5
r = (radius + .25)**2 + 1

result = ''

for i in range(diameter):
    y = (i - radius)**2
    for j in range(diameter):
        x = (j - radius)**2
        if x + y <= r:
            result = result + '*  '
        else:
            result = result + '   '
    result = result + '\n'

print(result)

result = result.split('\n')[:-1]
pixels_per_line = [x.count('*') for x in result]

print(f'The pixels per line are {pixels_per_line}.')

输出:

            *  *  *  *              
      *  *  *  *  *  *  *  *        
   *  *  *  *  *  *  *  *  *  *     
   *  *  *  *  *  *  *  *  *  *     
*  *  *  *  *  *  *  *  *  *  *  *  
*  *  *  *  *  *  *  *  *  *  *  *  
*  *  *  *  *  *  *  *  *  *  *  *  
*  *  *  *  *  *  *  *  *  *  *  *  
   *  *  *  *  *  *  *  *  *  *     
   *  *  *  *  *  *  *  *  *  *     
      *  *  *  *  *  *  *  *        
            *  *  *  *              

The pixels per line are [4, 8, 10, 10, 12, 12, 12, 12, 10, 10, 8, 4].

如果您需要圆形内部的空白区域,只需进行最小更改即可:

diameter = 7

radius = diameter / 2 - .5
r = (radius + .25)**2 + 1
r_min = (radius - 1)**2 + 1 # <-------- here

result = ''

for i in range(diameter):
    y = (i - radius)**2
    for j in range(diameter):
        x = (j - radius)**2
        if r_min <= x + y <= r: # <----- here
            result = result + '*  '
        else:
            result = result + '   '
    result = result + '\n'

print(result)

输出:

      *  *  *        
   *  *     *  *     
*  *           *  *  
*                 *  
*  *           *  *  
   *  *     *  *     
      *  *  *        

            *  *  *  *              
      *  *  *        *  *  *        
   *  *                    *  *     
   *                          *     
*  *                          *  *  
*                                *  
*                                *  
*  *                          *  *  
   *                          *     
   *  *                    *  *     
      *  *  *        *  *  *        
            *  *  *  *              

@Ilya 如果你接受 Rob 的答案,那是公平的。他做了大部分的工作。 - Yuri Khristich

0
你可以这样做。这是基于圆的公式 x^2 + y^2 等于半径,而任何在内部的点都小于半径。
import math
radius = 10
for i in range(-radius,radius+1):
    for j in range(-radius, radius +1):
        if radius-1 <= math.sqrt(i**2 + j**2) <= radius:
            print("*",end = " ")
        else:
            print(" ", end = ' ')
    print()

输出如下
                       *                         
                * * * * * * * * *                 
            * *                   * *             
          *                           *           
        *                               *         
      *                                   *       
    *                                       *     
    *                                       *     
  *                                           *   
  *                                           *   
  *                                           *   
  *                                           *   
* *                                           * * 
  *                                           *   
  *                                           *   
  *                                           *   
  *                                           *   
    *                                       *     
    *                                       *     
      *                                   *       
        *                               *         
          *                           *           
            * *                   * *             
                * * * * * * * * *                 
                        * 

如果你移除大于的条件
radius = 12
for i in range(-radius,radius+1):
    for j in range(-radius, radius +1):
        if math.sqrt(i**2 + j**2) <= radius:
            print("*",end = " ")
        else:
            print(" ", end = ' ')
    print()

输出

                       *                         
                * * * * * * * * *                 
            * * * * * * * * * * * * *             
          * * * * * * * * * * * * * * *           
        * * * * * * * * * * * * * * * * *         
      * * * * * * * * * * * * * * * * * * *       
    * * * * * * * * * * * * * * * * * * * * *     
    * * * * * * * * * * * * * * * * * * * * *     
  * * * * * * * * * * * * * * * * * * * * * * *   
  * * * * * * * * * * * * * * * * * * * * * * *   
  * * * * * * * * * * * * * * * * * * * * * * *   
  * * * * * * * * * * * * * * * * * * * * * * *   
* * * * * * * * * * * * * * * * * * * * * * * * * 
  * * * * * * * * * * * * * * * * * * * * * * *   
  * * * * * * * * * * * * * * * * * * * * * * *   
  * * * * * * * * * * * * * * * * * * * * * * *   
  * * * * * * * * * * * * * * * * * * * * * * *   
    * * * * * * * * * * * * * * * * * * * * *     
    * * * * * * * * * * * * * * * * * * * * *     
      * * * * * * * * * * * * * * * * * * *       
        * * * * * * * * * * * * * * * * *         
          * * * * * * * * * * * * * * *           
            * * * * * * * * * * * * *             
                * * * * * * * * *                 
                        *     

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接