第7课 几何拼贴画——海龟绘图
7.1 海龟绘图初步
海龟绘图(Turtle Graphics)是 Python 语言内置的绘图模块,是早期的 LOGO 编程语言在 Python 语言中的实现。使用这个模块绘图时,可以把屏幕当成一块画布,通过控制一个小三角形(或小海龟)的画笔在画布上移动,从而在它前进的路径上绘制出图形。这和 Scratch 中画笔的功能类似。
turtle 模块提供一套用于绘图的函数,在使用之前要先导入 turtle 模块。打开 IDLE 环境,在 Python Shell 窗口中使用 import 语句导入 turtle 模块:
>>> import turtle准备就绪,先来画一条直线吧。输入下面一行代码:
>>> turtle.fd (100)这时会出现一个标题为 Python Turtle Graphics 的窗口,在窗口中央有一个小三角形图标向右移动并画出一条直线,如图1所示。如果看不到这个窗口,可能是被Python Shell窗口遮挡住了。

图1 在海龟绘图窗口画一条直线
在海龟绘图中,默认的方向是正东(向右),并且画笔的默认状态是落笔,因此,这个代码执行时会在屏幕上让画笔向右移动 100 个像素并画出一条直线。
在代码 turtle.fd(100) 中,turtle 是模块名,fd是函数名,两者之间有一个点号(・)o 也就是以“模块名.函数名(参数)”的形式调用模块中的函数。
在后面的内容中,将会频繁调用 turtle 模块中的函数,因此,我们需要换一种更便捷的方式,即不通过模块名而直接调用模块中的函数。 把 IDLE 环境关闭后重新打开,在 Python Shell 窗口输入下面的代码:
>>> from turtle import *
fd(100)
>>>使用 from turtle import * 语句导入 turtle 模块后,就可以直接调用该模块中的函数,不再需要指定模块名。上面的代码也画岀了和图7-1 一样的直线。
接下来,将介绍海龟绘图中的画布坐标系统、画笔运动控制、画笔设置等
- 相对运动 在海龟绘图中,提供一些函数用于控制画笔的前进、旋转和方向。例如,fd() 函数让画笔前进,bk() 函数让画笔后退,left()函数让画笔向左转,right() 函数让画笔向右转,seth() 函数用来设定画笔的前进方向。 关闭 IDLE 环境并重新打开,在 Python Shell 窗口中输入下面的代码:
>>> from turtle import *
>>> fd(100)
>>> left(45)
>>> bk(200)
>>> right(45)
>>> fd(100)上面的代码执行时,画笔在画布上的移动过程为:先向右前进 100 像素,再向左转 45°,接着后退 200 像素,再向右转45°,最后再前进100像素。由于画笔默认是落笔状态,于是画布上就留下一个Z字形的痕迹。
上面代码中的几个函数也支持使用负值参数。例如 fd(-100) 表示后退 100 像素,bk(-200) 表示前进 200 像素,left(-45) 表示向右转45°,right(-45) 表示向左转45°。
试一试
控制画笔在画布上前进、后退、向左转或向右转,画出H字形的痕迹。
在海龟绘图中,可以使用 seth() 函数设定画笔的前进方向。关闭 IDLE 环境并重新 打开,在 Python Shell 窗口输入下面的代码:
>>> from turtle import *
>>> seth(90)
>>> fd(100)这儿行代码执行后,画笔的方向会旋转 90°,再向上移动并画出一条直线。 在海龟绘图中,默认工作在标准模式下,以正东方向(向右)作为0°,并按逆时针方向旋转,各个方向对应的角度如图2所示。

- 绝对运动
在海龟绘图中,画布坐标系统的原点 (0,0) 位于画布正中央。使用 goto() 函数,可以将画笔精确地移动到画布上的某个坐标位置。
关闭 IDLE 环境并重新打开,在 Python Shell 窗口中输入下面的代码:
>>> from turtle import *
>>> goto(150,100)在上面的代码中,调用 goto() 函数时用的两个参数 z 坐标和 y 坐标分别为 150 和 100 ,这使画笔从初始坐标 (0,0) 移动到坐标 (150,100) 。如图3所示。

- 画布和画笔设置
在海龟绘图中,如果要清除画布上的内容,不需要每次都重启 IDLE 环境,使用turtle 模块提供的 reset() 函数即可。在 Python Shell 窗口中输入下面的代码:
>>> reset()执行这个函数后,将会清除画布上的所有内容,并使画笔恢复初始状态。
如果只想清除画布内容,而保留画笔的当前状态,可用 clear() 函数,代码如下:
>>> clear()在海龟绘图中,up() 函数让画笔抬起,down() 函数让画笔落下;使用 pensize()函数设定画笔的大小,使用 pencolor() 函数设置画笔的颜色,画笔的默认颜色为黑色。在 Python Shell 窗口中输入下面的代码:
>>> reset()
>>> fd(50);tp();fd(50);down()
>>> pensize(5);pencolor('Red');fd(50)
>>> ht()这几行代码执行后,会出现一条黑色的细线段和一条红色的粗线段。
小技巧:在Python语言中,用分号作分隔符把多个语句写在一行,使代码更紧凑。
使用 pencolor() 函数时,参数可以用英文颜色码(如:'red'、'yellow’、'blue'等)或者是十六进制的颜色码(如:'#b0ccf9')。
使用 ht() 函数能隐藏画笔图标,使用 st() 函数能显示画笔图标。
7.2 画几何图形
经过前面的准备,接下来介绍一些简单的儿何图形的画法
- 使用相对运动方式画三角形
>>> reset();ht()
>>> seth(45);fd(100);right(90);fd(100);home()上面代码运行后,将在画布上画岀一个底角为 45°的等腰直角三角形。home() 函数的作用是回到画布中心,相当于调用 goto(0,0) 函数。使用这个方法也可以画岀多边形。
- 使用绝对运动方式画三角形
>>> reset();ht()
>>> goto(100,100);goto(200,0);goto(0,0)上面代码运行后,画笔将通过三角形的3个顶点在画布上画岀一个三角形。使用这个方法也可以画出多边形。
- 使用颜色填充图形
在海龟绘图中,可用指定颜色填充绘制的图形。在 Python Shell 窗口中输入下面代码:
>>> reset();ht()
>>> pencolor('Red')
>>> fillcolor('Blue1')
>>> begin_fill()
>>> goto(100,100);goto(200,0);goto(0,0)
>>> end_fill()上面代码运行后,将得到一个边框为红色、内部填充为蓝色的三角形。在 begin_fill() 函数和 end_fill() 函数之间绘制一个图形,当执行到 end_fill()时就会使用 fillcolor() 函数指定的颜色填充图形。
另外,使用 color() 函数时,可以分别或同时指定画笔颜色和填充颜色。例如,通过调用color('red','blue')函数,设置画笔颜色为红色,填充颜色为蓝色。
如果只指定一个参数,那么将设置画笔颜色和填充颜色为相同的颜色。例如,通过调 用 color('blue') 函数,把画笔颜色和填充颜色都设置为蓝色。
试一试
使用相对运动和绝对运动两种方式画出正方形,并使用红色进行填充。
- 画圆或多边形
在海龟绘图中,circle()函数可以用来画圆,或者画圆的内切正多边形。
- 以指定半径画圆。如果半径是正数,则沿逆时针方向画;如果是负数,则沿顺时 针方向画。在Python Shell窗口中输入下面代码:
>>> reset()
>>> circle(50)
>>> circle(-50)上面代码执行后,画笔位于画布的中心 circle(50) 函数将使画笔沿逆时针方向移动一周,circle(-50)函数将使画笔沿顺时针方向移动一周,最后画岀半径为50像素的两个圆形,两者上下排列,呈8字形。
- 以指定半径和弧度画圆。调用circle()函数时,使用第2个参数指定圆的弧度。 在Python Shell窗口中输入F面代码:
>>> reset()
>>> circle(50,180)
>>> circle(-50,180)上面代码执行后,从画布中心开始,circle(50,180)函数让画笔沿着逆时针方向移动 半周;接着,circle( —50,180)函数使画笔沿着顺时针方向继续移动半周,最终画出半径为 50像素的两个半圆,两者上下排列,呈S形。
(3)以指定半径画圆的内切正多边形。在调用circleO函数时,使用参数steps指定 内切正多边形的边数。在Python Shell窗口中输入下面代码:
>>> reset()
>>> circle(50,steps=3)在上面代码中,circleO函数的steps参数为3,将会在一个半径为50像素的圆内画一 个内切正三边形(等边三角形),如[图4]中的第1个图。这里要注意参数steps的写法。
如果分别以 4、6、12、24 作为参数 steps 的值,使用circle()函数可以画出图4中其他的图形。可见,steps 值越大,多边形就越逼近于圆。

图4 画圆的内切多边形
- 画点
使用 dot() 函数时,将用指定直径和颜色画一个圆点。在 Python Shell 窗口中输入下面代码:
>>> reset()
>>> dot(20,'Green')执行上面代码,将以画笔当前位置为圆心,画岀一个直径为 20 像素的绿色圆点。如果不指定大小,则在画笔大小 + 4 和画笔大小 * 2之间取最大值作为圆点的直径。如果不指定颜色,则使用画笔颜色。
7.3 创意绘画
如图5所示,在这幅美丽的儿何拼贴画中,使用一些简单的儿何图形画出了太阳、草地、栅栏、绿树、房子和炊烟等元素。请仔细观察这幅画是由哪些儿何图形构成的,然后也来创作一幅吧。

图5 几何拼贴画
提示:在前面学习海龟绘图时,是在 Python Shell 窗口中输入和运行代码。因为代码量很少,且不需要建立文件存储源代码,感觉比较方便。而下面要编写的绘画程 序的代码很多,应该使用 Python 编辑器来编写代码,并将源代码保存到文件中,这样 才能方便地对代码进行编辑操作。打开IDLE环境,新建一个 Python 编辑器窗口,以“几何拼贴画.py”作为文件名将空白源文件保存到本地磁盘上,然后开始编写 Python 代码。
- 准备工作,即导入 turtle 模块、隐藏海龟图标、调整绘图速度。
from turtle import *
ht()
# 调整绘图速度,取值:slowest,slow,normal,fast,fastest
speed('normal')- 画大地。
# 大地,画一条长为800像素的线段,画笔大小为50像素,填充颜色为'LightGreen'
pensize(50);pencolor('LightGreen')
up();goto(-400,-200);down();goto(400,-200)- 画栅栏。栅栏可分解为1条横线和4条竖线,依次画出。
# 画栅栏。栅栏可分解为1条横线和4条竖线,依次画出
pensize(20);pencolor('GoldEnrod')
up();goto(-400,-150);down();goto(400,-150)
up();goto(-250,-200);down();goto(-250,-100)
up();goto(-100,-200);down();goto(-100,-100)
up();goto(30,-200);down();goto(30,-100)
up();goto(300,-200);down();goto(300,-100)- 画树。树可分解为树干和树冠,依次画出。
# 画树。树可以分解为树干和树冠,依次画出
pensize(30);pencolor('Olive')
up();goto(-150,-200)
down();goto(-150,-120)
# 树冠,分别以半径为80,60和40画出园内切正 3 边形,填充颜色为 'ForestGreen'
pensize(1);pencolor('ForestGreen')
up();goto(-80,-120);down()
begin_fill();seth(60);circle(80,steps = 3);end_fill()
up();goto(-95,-50);down()
begin_fill();seth(60);circle(60,steps = 3);end_fill()
up();goto(-110,0);down()
begin_fill();seth(60);circle(40,steps = 3);end_fill()- 画房子。房子可分解为墙体、房顶、窗户、门和烟囱等,依次画出。
# 房子的墙体,画一个边长为200像素的正方形,填充颜色为 'RoyalBlue'
pensize(1);color('ROyalBlue')
up();home();fd(70);right(90);down()
begin_fill()
fd(200);left(90)
fd(200);left(90);fd(200)
end_fill()
# 烟囱,换一条长为90像素的线段,画笔大小为30像素,填充颜色为'DimGray'
pensize(30);pencolor('DimGray')
up();goto(230,30);down();goto(230,120)
# 房顶,画一个底角为30°、腰为200像素的等腰三角形,填充颜色为 'DeepPink'
pensize(1);color('DeepPink')
up();home();down()
begin_fill();left(30)
fd(200);right(60)
fd(200);home();end_fill()
# 窗户,画一个半径为50像素的圆的内切正4边形,填充颜色为 'Violent'
color('Violet')
up();goto(160,-90);down()
begin_fill();seth(45)
circle(50,steps=4);end_fill()
# 门,画一个长为120像素、宽60像素的长方形,填充颜色为 'Chocol'
color('Chocolate')
up();goto(250,-200);down()
seth(90)
begin_fill()
fd(120);left(90)
fd(60);left(90)
fd(120);left(90)
fd(60);end_fill()- 画炊烟和太阳。
# 炊烟,画三个依次变小的圆点,填充颜色为 'AliceBlue'
up();goto(250,160);dot(30,'AliceBlue')
goto(270,200);dot(20,'AliceBlue')
goto(300,220);dot(10,'AliceBlue')
# 画太阳,画一个80像素的圆点,填充颜色 'Gold'
goto(-260,250);dot(80,'Gold')注意:上面代码采用多行写法,以牺牲可读性换取减少排版篇幅。在实际编程时,应在不降低代码可读性的前提下适当采用多行写法。将上述代码编辑妥当并保存,然后运行程序,就会画出如图5所示的一幅图画。这个案例的代码很长,但都是由简单的指令顺序叠加的,只要细心就能够完成。在编程时,建议每完成一个步骤就保存代码并运行,看看效果是否实现。如果出现错误,也能及时修正。