使用Python Turtle绘制圆圈而无需圆形函数

5 投票
6 回答
17804 浏览
提问于 2025-04-29 20:25

我有一个学校的作业:

制作一个雪人,不能使用海龟库里的 circle 函数。

雪人应该在蓝色的背景上,身体要用白色填充。

雪人的轮廓要用黑色。

雪人的身体由三个填充的圆圈组成。

每个圆圈的边框宽度要是3个像素。

最下面的圆圈半径要是100个像素。

中间的圆圈半径要是70个像素。

最上面的圆圈半径要是40个像素。

每个圆圈要正好在下面的圆圈上面(除了最下面的圆圈,可以放在任何地方)。

圆圈之间不能有空隙。

给雪人画上嘴巴、眼睛和鼻子(帽子是可选的)。

确保有两只树枝手臂,每只手上至少要有两个手指。

到目前为止,我做了这个,但在继续之前,我似乎无法把圆圈画好。
而且,我也不知道怎么给圆圈上色或者怎么画眼睛的点。请帮帮我,这是我第一次编程。

import turtle                               # allows us to use turtle library
wn = turtle.Screen()                        # allows us to create a graphics window
wn.bgcolor("blue")                          # sets gtaphics windows background color to blue
import math                                 # allows us to use math functions
quinn = turtle.Turtle()                     # sets up turtle quinn
quinn.setpos(0,0)
quinn.pensize(3)
quinn.up()

# drawing first circle middle
quinn.forward(70)
quinn.down()
quinn.left(90)

# calculation of cicumference of a circle
a = (math.pi*140.00/360)

#itineration for first circle
for i in range (1,361,1):
    quinn.left(a)
    quinn.forward (1)

# drawing second circle bottom
quinn.up()
quinn.home()
quinn.right(90)
quinn.forward(70)
quinn.left(90)
quinn.down()

b = (math.pi*200.00/360)

for i in range (1,361,1):
    quinn.right(b)
    quinn.forward(1)

# drawing third circle head top

quinn.up ()
quinn.goto(0,70)
quinn.right(90)
quinn.down()

c =(math.pi*80/360)

for i in range (1,361,1):
    quinn.left(c)
    quinn.forward(1)

wn.exitonclick()
暂无标签

6 个回答

0

你可以创建一个函数,这个函数需要两个参数,分别是 fd 和 left。

我这里给你一个我写的例子。

from turtle import *
speed(100000)
for i in range(360):
    fd(2)
    left(1)

这里是计算的过程:在一个范围内进行的循环次数,除以 fd 和 left 的和。 这就是我得到的一个近似值。所以你应该能够创建一个这样的函数。

1

从数学的角度来看,你可以使用 math 库里的 sincos 函数来绘制圆形。

一旦圆形绘制出来后,可以使用 turtle.begin_fill()turtle.end_fill() 方法来填充这个圆形 (虽然我同意在编程中,这种方法更实用)

from turtle import Turtle
from math import sin, cos, radians

def draw_circle(radius, x, y, color="light blue", line_width=3):
    c = Turtle(visible=False)
    c.width(3)
    c.penup()
    c.goto(x + radius, y)
    c.pendown()
    c.color("black", color)
    c.begin_fill()
    # Circle drawing starts here
    for i in range(1, 361):
        c.goto(radius * cos(radians(i)) + x,
               radius * sin(radians(i)) + y)
    # Circle drawing ends here
    c.end_fill()
draw_circle(100, 0, -100)

正如在 这个回答中提到的,你可以使用 turtle.dot() 方法在屏幕上画一个点,笔的宽度就是这个点的直径。

还有另一种方法可以做到这一点,但相比于 dot 方法,这种方法不太实用。不过我还是提一下,看看其实有很多不同的解决办法:

from turtle import Turtle

def draw_circle(radius, x, y, color="light bue", line_width=3):
    c = Turtle(visible=False)
    c.penup()
    c.goto(x, y)
    c.pendown()
    # Circle drawing starts here
    c.width(radius * 2 + line_width)
    c.forward(0)
    c.color(color)
    c.width(radius * 2 - line_width)
    c.forward(0)
    # Circle drawing ends here

draw_circle(100, 0, -100)

所以 turtle.dot() 相当于 turtle.forward(0) (还有 turtle.backward(0)turtle.goto(turtle.pos())turtle.setpos(turtle.pos()) 等等)

输出结果:

在这里输入图片描述

1

大多数关于“没有海龟的圆形函数”的解决方案都是自己写一个和海龟的圆形函数相似的东西。但其实还有另外两种方法可以用海龟画出轮廓和填充的圆。

一种方法是使用同心的

turtle.color('black')
turtle.dot(200 + 3)
turtle.color('white')
turtle.dot(200 - 3)

记住,dot()是用直径来表示的,而circle()是用半径来表示的:

enter image description here

不过,我更喜欢用印章的方法来解决这些问题:

''' Build a Snowman without turtle circle function '''

from turtle import Turtle, Screen

# The snowman’s body should be made of 3 filled circles.

# The bottom circle should have a radius of 100 pixels.
# The middle circle should have a radius of 70 pixels.
# The top circle should have a radius of 40 pixels.

RADII = (100, 70, 40)

STAMP_SIZE = 20

# The snowman should be on a blue background
screen = Screen()
screen.bgcolor('blue')

quinn = Turtle('circle')
quinn.setheading(90)
quinn.up()

# The outline of the snowman should be in black, and should be drawn filled with white.
quinn.color('black', 'white')

for not_first, radius in enumerate(RADII):

    if not_first:
        quinn.forward(radius)

    # The outline of each circle should be 3 pixels wide.
    quinn.shapesize((radius * 2) / STAMP_SIZE, outline=3)

    quinn.stamp()

    # Each circle should be centered above the one below it
    # There should be no gap between the circles.
    quinn.forward(radius)

# Give the snowman eyes

quinn.shapesize(15 / STAMP_SIZE)
quinn.color('black')
quinn.backward(3 * RADII[-1] / 4)

for x in (-RADII[-1] / 3, RADII[-1] / 3):
    quinn.setx(x)
    quinn.stamp()

# Give the snowman a mouth, and a nose (a hat is optional).

pass

# Make sure to include two stick-arms and at least two fingers on each hand.

pass

quinn.hideturtle()

screen.exitonclick()

这个想法是,你把海龟的光标调整到你需要的样子,然后在屏幕上拍个快照,然后再把它调整到下一个你需要画的东西。

enter image description here

1

抱歉没有给出解释。

第一部分是拉马努金对圆周率的近似计算,但这个方法不是很好,因为它需要大约30万次循环才能得到圆周率的近似值,而且只精确到小数点后5位。这就是这一部分:

    r += (1 / k) * (-1)**i
    pi = (4 * (1 - r))

接下来我使用圆的周长:

t.forward(2*5*pi)

最后,我让小乌龟顺时针走20步。

import turtle 
t = turtle.Turtle()
t.right(90)
t.penup()
t.goto(100, 0)
t.pendown()

i = 0
r = 0
k = 3

while i <= 360:
    r += (1 / k) * (-1)**i
    pi = (4 * (1 - r))
    t.write(pi)
    t.forward(2*5*pi)
    t.right(20)

    i += 1
    k += 2

turtle.done()
2

下面是一个示例函数,用来画一个填充蓝色的圆:

def draw_circle(radius):    
    turtle.up()
    turtle.goto(0,radius) # go to (0, radius)
    turtle.begin_fill() # start fill
    turtle.down() # pen down
    turtle.color('blue')
    times_y_crossed = 0
    x_sign = 1.0
    while times_y_crossed <= 1:
        turtle.forward(2*math.pi*radius/360.0) # move by 1/360
        turtle.right(1.0)
        x_sign_new = math.copysign(1, turtle.xcor())        
        if(x_sign_new != x_sign):
            times_y_crossed += 1
        x_sign = x_sign_new
    turtle.up() # pen up
    turtle.end_fill() # end fill.
    return

接下来,你可以修改上面的函数,添加参数来设置圆心的位置(x,y):

def draw_circle(radius, x, y):    
    turtle.up()
    turtle.goto(x,y+radius) # go to (x, y + radius)
    turtle.begin_fill() # start fill
    turtle.down() # pen down
    turtle.color('blue')
    times_y_crossed = 0
    x_sign = 1.0
    while times_y_crossed <= 1:
        turtle.forward(2*math.pi*radius/360.0) # move by 1/360
        turtle.right(1.0)
        x_sign_new = math.copysign(1, turtle.xcor())        
        if(x_sign_new != x_sign):
            times_y_crossed += 1
        x_sign = x_sign_new
    turtle.up() # pen up
    turtle.end_fill() # end fill.
    return

你也可以很简单地添加点,比如:

turtle.goto(-20,10)
turtle.color('red')
turtle.dot(20)
turtle.goto(40,10)
turtle.dot(20)

把这些放在一起:

import turtle
import math

def draw_circle(radius, x, y):    
    turtle.up()
    turtle.goto(x,y+radius) # go to (0, radius)
    turtle.begin_fill() # start fill
    turtle.down() # pen down
    turtle.color('blue')
    times_y_crossed = 0
    x_sign = 1.0
    while times_y_crossed <= 1:
        turtle.forward(2*math.pi*radius/360.0) # move by 1/360
        turtle.right(1.0)
        x_sign_new = math.copysign(1, turtle.xcor())        
        if(x_sign_new != x_sign):
            times_y_crossed += 1
        x_sign = x_sign_new
    turtle.up() # pen up
    turtle.end_fill() # end fill.
    return


draw_circle(100, 10, 10)
turtle.goto(-20,10)
turtle.color('red')
turtle.dot(20)
turtle.goto(40,10)
turtle.dot(20)
turtle.pen(shown=False)
turtle.done()

你应该尝试自己完成作业的剩余部分哦.. ;)

撰写回答