Python 同心圆

Python 同心圆,python,turtle-graphics,Python,Turtle Graphics,我真的被一项任务打扰了: 用户输入半径r,然后绘制圆,然后继续绘制另一个圆心相同但小于10 px的圆,直到半径为0。首先,让我们将圆近似为具有36条边/段的正多边形。 要画出给定半径r的形状,我们需要知道 每段的长度 每个线段之间要旋转的角度 为了计算长度,我们首先需要周长,即2πr,我们将圆周率近似为3.1415,给出 circumference = 2 * 3.1415 * radius 接下来,我们将其除以近似的分段数,得到 circumference = 2 * 3.1415 * ra

我真的被一项任务打扰了:
用户输入半径r,然后绘制圆,然后继续绘制另一个圆心相同但小于10 px的圆,直到半径为0。首先,让我们将圆近似为具有36条边/段的正多边形。 要画出给定半径r的形状,我们需要知道

每段的长度 每个线段之间要旋转的角度 为了计算长度,我们首先需要周长,即2πr,我们将圆周率近似为3.1415,给出

circumference = 2 * 3.1415 * radius
接下来,我们将其除以近似的分段数,得到

circumference = 2 * 3.1415 * radius
seg_lenght = circumferece/36
现在我们需要线段之间的角度差,或者外部角度。对于有n条边的正n多边形,这就是360/n,所以我们做360/36=10

现在,我们可以定义一个函数来生成线段长度并绘制圆:

def circle_around_point(radius):
    circumference = 2 * 3.1415 * radius 
    seg_length = circumference/36

    penup()         
    fd(radius)   #Move from the centre to the circumference
    right(90)    #Face ready to start drawing the circle
    pendown()

    for i in range(36): #Draw each segment
        fd(seg_length)
        right(10)

    penup()
    right(90)    #Face towards the centre of the circle
    fd(radius)   #Go back to the centre of the circle
    right(180)   #Restore original rotation
    pendown()
现在,对于同心圆:

def concentric_circles(radius):
    while radius > 0:
        circle_around_point(radius)
        radius -= 10

不清楚为什么@IbraheemRodrigues觉得有必要根据您的问题描述重新编码turtle的圆函数,但我们可以通过不重新发明轮子来简化他的解决方案:

def circle_around_point(turtle, radius):
    is_down = turtle.isdown()

    if is_down:
        turtle.penup()
    turtle.forward(radius)  # move from the center to the circumference
    turtle.left(90)  # face ready to start drawing the circle
    turtle.pendown()

    turtle.circle(radius)

    turtle.penup()
    turtle.right(90)  # face awary from the center of the circle
    turtle.backward(radius)  # go back to the center of the circle

    if is_down:
        turtle.pendown()  # restore original pen state

def concentric_circles(turtle, radius):
    for r in range(radius, 0, -10):
        circle_around_point(turtle, r)
圆的关键是当前位置位于圆的边缘,因此需要按半径移动位置,以使特定点成为圆的中心

但是,为了解决这个问题,我可能会从绘图切换到冲压,并通过这种方式来加速和简化代码:

import turtle

STAMP_SIZE = 20

radius = int(input("Please input a radius: "))

turtle.shape('circle')
turtle.fillcolor('white')

for r in range(radius, 0, -10):
    turtle.shapesize(r * 2 / STAMP_SIZE)
    turtle.stamp()

turtle.mainloop()
然而,当它炸掉一个小圆圈时,它会画出一个粗糙的圆圈:

为了解决这一问题,我可能会在上述两种解决方案之间进行折衷,并执行以下操作:

import turtle

radius = int(input("Please input a radius: "))

turtle.penup()
turtle.forward(radius)
turtle.left(90)
turtle.pendown()

turtle.begin_poly()
turtle.circle(radius)
turtle.penup()
turtle.end_poly()

turtle.addshape('round', turtle.get_poly())  # 'circle' is already taken

turtle.right(90)
turtle.backward(radius)

turtle.shape('round')
turtle.fillcolor('white')

for r in range(radius - 10, 0, -10):
    turtle.shapesize(r / radius)
    turtle.stamp()

turtle.mainloop()
这通过缩小一个较大的圆而不是扩大一个较小的圆来提高圆的质量:

其中,可以使用调用circle的steps=参数控制循环的质量

但是,如果我真的想最小化代码,同时保持高质量和高速度,我可能会:

import turtle

radius = int(input("Please input a radius: "))

for diameter in range(radius * 2, 0, -20):
    turtle.dot(diameter, 'black')
    turtle.dot(diameter - 2, 'white')

turtle.hideturtle()

turtle.mainloop()
点方法从中心而不是边缘绘制,使用直径而不是半径,仅绘制填充圆,似乎是我们解决此特定练习的最佳方案:


你为什么要重新发明海龟圈法?我在OP的问题中没有看到任何需要额外努力的地方。@cdlane My bad,没有意识到这个功能。我使用的练习让我创造了自己的功能。
import turtle

####     #####   #### Below class draws concentric circles. 

class Circle:

    def __init__(self, pen, cx, cy, radius):
        self.pen = pen
        self.cx = cx
        self.cy = cy
        self.radius = radius

    def drawCircle(self):
        self.pen.up()
        self.pen.setposition( self.cx, self.cy - self.radius )
        self.pen.down()
        self.pen.circle(self.radius)

    def drawConCircle(self, minRadius = 10, delta = 10):
        if( self.radius > minRadius ) :
            self.drawCircle()
            self.radius -= delta  # reduce radius of next circle
            self.drawConCircle()
 ####    End class circle #######

win = turtle.Screen()
win.bgcolor("white")
s = Circle( turtle.Turtle(), 0, 0, 200 )
s.drawConCircle()
win.exitonclick()