Python乌龟同心圆

时间:2017-05-28 14:42:11

标签: python turtle-graphics

我真的受到任务的影响: 用户输入半径r然后乌龟绘制圆圈然后继续绘制另一个具有相同中心但小10 px的圆,直到半径为0

3 个答案:

答案 0 :(得分:0)

首先让我们将圆近似为具有36个边/段的正多边形。 要给出半径为 r 的形状,我们需要知道;

  1. 每个段的长度
  2. 每个段之间的转角
  3. 要计算长度,我们首先需要周长,即2πr(我们将近似pi为3.1415),给我们

    circumference = 2 * 3.1415 * radius
    

    接下来,我们将它除以我们接近的段数,给出

    circumference = 2 * 3.1415 * radius
    seg_lenght = circumferece/36
    

    现在我们需要段之间的角度差或外角。对于常规n-gon(具有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
    

答案 1 :(得分:0)

目前尚不清楚为什么@IbraheemRodrigues认为有必要根据您的问题描述重新编码龟的circle()函数,但我们可以通过不重新发明轮子来简化他的解决方案:

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)

circle()的关键是当前位置位于圆的边缘,因此您需要将您的位置移动半径,以使特定点成为圆的中心。

但是,为了解决这个问题,我可以从绘图切换到标记并以这种方式加速并简化代码:

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

然而,这引起了粗糙的圈子,因为它正在炸毁一个小圈子:

enter image description here

要解决这个问题,我可能会在上面的两个解决方案之间做出妥协并做:

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

这可以通过缩小大圆而不是放大小圆来提高圆的质量:

enter image description here

可以使用调用steps=的{​​{1}}参数来控制圈子的质量。

但是,如果我真的想在保持高质量和高速度的同时最大限度地减少代码,我可能会这样做:

circle()

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() 方法从中心而不是边缘绘制,使用直径而不是半径,仅绘制实心圆,并且似乎是此特定练习的最佳解决方案:

enter image description here

答案 2 :(得分:-1)

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