前言
turtle(海龟绘图) 是 Python 内置的图形库,它模拟一只海龟在画布上爬行,通过移动留下轨迹来绘制图案。虽然是教学工具,但 turtle 能创作出令人惊叹的艺术作品!本文从基础操作到复杂图形,系统讲解 turtle 绘图技巧。
入门基础
第一个海龟程序
import turtle
# 创建窗口和画笔
screen = turtle.Screen()
screen.title("我的第一个海龟程序")
screen.bgcolor("white")
pen = turtle.Turtle()
pen.shape("turtle") # 让画笔变成海龟形状
pen.color("blue")
pen.pensize(3)
# 画一个正方形
for _ in range(4):
pen.forward(100) # 前进 100 像素
pen.right(90) # 右转 90 度
pen.hideturtle() # 隐藏海龟
screen.mainloop() # 保持窗口打开
基本命令速查
| 命令 | 说明 |
|---|---|
forward(n) / fd(n) |
向前移动 n 像素 |
backward(n) / bk(n) |
向后移动 n 像素 |
right(angle) / rt(angle) |
向右旋转 angle 度 |
left(angle) / lt(angle) |
向左旋转 angle 度 |
goto(x, y) / setpos(x, y) |
移动到指定坐标 |
circle(radius, extent) |
画圆弧(extent 为角度) |
dot(size, color) |
画点 |
pensize(width) |
设置画笔粗细 |
pencolor(color) |
设置画笔颜色 |
fillcolor(color) |
设置填充颜色 |
begin_fill() / end_fill() |
开始/结束填充 |
undo() |
撤销上一步 |
reset() |
重置海龟状态 |
基础图形绘制
画螺旋线
import turtle
def draw_spiral():
screen = turtle.Screen()
screen.title("螺旋线")
screen.bgcolor("black")
pen = turtle.Turtle()
pen.speed(0) # 最快速度
pen.pensize(2)
colors = ["red", "yellow", "green", "cyan", "magenta", "orange"]
length = 5
for i in range(200):
pen.pencolor(colors[i % len(colors)])
pen.forward(length)
pen.left(91) # 稍大于 90° 产生螺旋效果
length += 2
pen.hideturtle()
screen.mainloop()
draw_spiral()
对称几何图案
import turtle
def draw_symmetric_pattern(sides=6, turns=24):
"""绘制对称几何图案"""
screen = turtle.Screen()
screen.title("对称几何图案")
screen.bgcolor("#1a1a2e")
pen = turtle.Turtle()
pen.speed(0)
pen.pensize(2)
colors = ["#e94560", "#f5c518", "#0f3460", "#16c79a", "#ff6b6b"]
for t in range(turns):
pen.pencolor(colors[t % len(colors)])
for _ in range(sides):
pen.forward(80)
pen.left(360 // sides)
pen.right(360 // turns)
pen.hideturtle()
screen.mainloop()
draw_symmetric_pattern(sides=8, turns=36)
多色渐变圆形
import turtle
import math
def draw_gradient_circles(count=36, radius=50):
"""绘制渐变色圆形组合"""
screen = turtle.Screen()
screen.title("渐变圆形")
screen.bgcolor("#0d1b2a")
screen.setup(600, 600)
pen = turtle.Turtle()
pen.speed(0)
pen.ht()
for i in range(count):
hue = i * 360 / count
r = int(128 + 127 * math.cos(math.radians(hue)))
g = int(128 + 127 * math.cos(math.radians(hue - 120)))
b = int(128 + 127 * math.cos(math.radians(hue - 240)))
color = f"#{r:02x}{g:02x}{b:02x}"
pen.pencolor(color)
pen.fillcolor(color)
pen.begin_fill()
pen.circle(radius)
pen.end_fill()
pen.rt(360 / count)
screen.mainloop()
draw_gradient_circles(36, 60)
分形图形
科赫雪花(Koch Snowflake)
import turtle
def koch_curve(t, order, size):
"""递归绘制科赫曲线"""
if order == 0:
t.forward(size)
return
segment_size = size / 3
# 第一部分
koch_curve(t, order - 1, segment_size)
t.left(60)
# 凸起部分
koch_curve(t, order - 1, segment_size)
t.right(120)
# 中间部分
koch_curve(t, order - 1, segment_size)
t.left(60)
# 第三部分
koch_curve(t, order - 1, segment_size)
def draw_koch_snowflake(order=3, size=200):
"""绘制科赫雪花"""
screen = turtle.Screen()
screen.title(f"科赫雪花 (阶数={order})")
screen.bgcolor("white")
pen = turtle.Turtle()
pen.speed(0)
pen.pensize(2)
pen.pencolor("#2c3e50")
pen.penup()
pen.goto(-size/2, -size/(2 * 1.732))
pen.pendown()
for _ in range(3):
koch_curve(pen, order, size)
pen.right(120)
pen.hideturtle()
screen.mainloop()
draw_koch_snowflake(order=3, size=240)
谢尔宾斯基三角形
import turtle
def draw_triangle(t, size, depth):
"""递归绘制谢尔宾斯基三角形"""
if depth == 0:
t.fillcolor("#e74c3c")
t.begin_fill()
for _ in range(3):
t.forward(size)
t.left(120)
t.end_fill()
return
new_size = size / 2
# 顶部子三角形
draw_triangle(t, new_size, depth - 1)
t.penup()
t.forward(new_size)
t.pendown()
# 左下子三角形
t.left(120)
t.forward(new_size)
t.right(120)
draw_triangle(t, new_size, depth - 1)
# 右上子三角形
t.left(120)
t.forward(new_size)
t.right(60)
t.forward(new_size)
t.left(60)
draw_triangle(t, new_size, depth - 1)
# 回到原点
t.penup()
t.backward(new_size)
t.left(60)
t.backward(new_size)
t.right(60)
t.pendown()
def draw_sierpinski(depth=4):
"""绘制谢尔宾斯基三角形"""
screen = turtle.Screen()
screen.title(f"谢尔宾斯基三角形 (深度={depth})")
screen.bgcolor("white")
pen = turtle.Turtle()
pen.speed(0)
pen.pensize(1)
pen.penup()
pen.goto(0, -150)
pen.pendown()
draw_triangle(pen, 300, depth)
pen.hideturtle()
screen.mainloop()
draw_sierpinski(depth=4)
分形树
import turtle
import random
def draw_fractal_tree(branch_length, angle, reduction, depth, pen):
"""递归绘制分形树"""
if depth <= 0 or branch_length < 5:
return
length_variation = random.uniform(0.85, 1.15)
actual_length = branch_length * length_variation
pen.pensize(max(1, depth // 2))
pen.forward(actual_length)
# 左分支
left_angle = angle + random.uniform(-5, 5)
pen.left(left_angle)
draw_fractal_tree(actual_length * reduction, angle, reduction, depth - 1, pen)
# 右分支
right_angle = angle + random.uniform(-5, 5)
pen.right(right_angle)
draw_fractal_tree(actual_length * reduction, angle, reduction, depth - 1, pen)
# 回到原位
pen.left(left_angle)
pen.backward(actual_length)
def draw_tree(depth=9, angle=25):
"""绘制分形树"""
screen = turtle.Screen()
screen.title("分形树")
screen.bgcolor("lightblue")
pen = turtle.Turtle()
pen.speed(0)
pen.pencolor("#5d4037")
pen.penup()
pen.goto(0, -200)
pen.setheading(90)
pen.pendown()
draw_fractal_tree(120, angle, 0.7, depth, pen)
pen.hideturtle()
screen.mainloop()
draw_tree(depth=10, angle=25)
交互与动画
键盘控制海龟
import turtle
class InteractiveTurtle:
"""交互式海龟绘图"""
def __init__(self):
self.screen = turtle.Screen()
self.screen.title("交互式海龟")
self.screen.setup(800, 600)
self.screen.tracer(False)
self.pen = turtle.Turtle()
self.pen.shape("turtle")
self.pen.shapesize(2, 2)
self.pen.speed(0)
self.colors = ["red", "yellow", "green", "cyan",
"magenta", "orange", "purple", "brown"]
self.color_index = 0
self._setup_keys()
self._main_loop()
def _setup_keys(self):
key_map = {
"Up": lambda: self.pen.forward(20),
"Down": lambda: self.pen.backward(20),
"Left": lambda: self.pen.left(15),
"Right": lambda: self.pen.right(15),
"space": lambda: self.pen.undo(),
"c": lambda: self.screen.reset(),
"r": lambda: setattr(self.pen, "pencolor", self.colors[self.__class__.__dict__]),
}
for key, callback in key_map.items():
self.screen.onkey(callback, key)
self.screen.listen()
def _main_loop(self):
while True:
self.screen.update()
InteractiveTurtle()
鼠标追踪画图
import turtle
def draw_on_click():
screen = turtle.Screen()
screen.title("点击画图")
screen.bgcolor("white")
pen = turtle.Turtle()
pen.speed(0)
pen.shapesize(3)
colors = ["red", "blue", "green", "yellow", "purple", "orange"]
color_idx = [0]
def on_click(x, y):
color_idx[0] = (color_idx[0] + 1) % len(colors)
pen.color(colors[color_idx[0]])
pen.dot(40)
pen.write(f"✕ ({x}, {y})", font=("Arial", 10))
screen.onclick(on_click)
screen.listen()
screen.mainloop()
draw_on_click()
正弦波动画
import turtle
import math
def animate_sine_wave(periods=2, amplitude=80):
screen = turtle.Screen()
screen.title("正弦波动画")
screen.bgcolor("white")
screen.setup(800, 400)
screen.tracer(0)
pen = turtle.Turtle()
pen.speed(0)
pen.hideturtle()
pen.pensize(3)
width = screen.window_width() / 2
origin_x = -width
pen.color("#ccc")
pen.penup()
pen.goto(origin_x, 0)
pen.pendown()
pen.forward(width * 2)
pen.color("#2196F3")
pen.penup()
pen.goto(origin_x, 0)
pen.pendown()
for x in range(int(origin_x), int(origin_x + width * 2)):
angle = math.radians((x - origin_x) / width * periods * 360)
y = amplitude * math.sin(angle)
pen.goto(x, y)
screen.update()
screen.mainloop()
animate_sine_wave(periods=3, amplitude=80)
实用工具函数
随机涂鸦生成器
import turtle
import random
def random_drawings(num_shapes=50, max_size=100):
screen = turtle.Screen()
screen.title("随机涂鸦")
screen.bgcolor("white")
screen.tracer(False)
pen = turtle.Turtle()
pen.speed(0)
pen.pensize(2)
shapes = ["circle", "square", "triangle", "hexagon", "star"]
positions = []
for _ in range(num_shapes):
x = random.randint(-350, 350)
y = random.randint(-250, 250)
overlaps = any(abs(px - x) < 50 and abs(py - y) < 50 for px, py in positions)
if overlaps:
continue
positions.append((x, y))
shape = random.choice(shapes)
size = random.randint(10, max_size)
pen.penup()
pen.goto(x, y)
pen.setheading(random.randint(0, 360))
pen.pendown()
color = f"#{random.randint(0,255):02x}{random.randint(0,255):02x}{random.randint(0,255):02x}"
pen.pencolor(color)
pen.fillcolor(color)
pen.begin_fill()
if shape == "circle":
pen.circle(size)
elif shape == "square":
for _ in range(4):
pen.forward(size)
pen.left(90)
elif shape == "triangle":
for _ in range(3):
pen.forward(size)
pen.left(120)
elif shape == "hexagon":
for _ in range(6):
pen.forward(size / 1.5)
pen.left(60)
elif shape == "star":
for _ in range(5):
pen.forward(size * 1.5)
pen.right(144)
pen.end_fill()
screen.update()
pen.hideturtle()
screen.mainloop()
random_drawings(30, 80)
总结
本文系统讲解了 turtle 海龟绘图的核心技能:
- 基础操作 — forward/right/left/goto/circle 等核心命令
- 几何图案 — 螺旋线、对称图案、渐变圆形
- 分形图形 — 科赫雪花、谢尔宾斯基三角形、分形树
- 交互控制 — 键盘输入、鼠标点击、实时响应
- 动画效果 — 正弦波动画、自动绘制
- 创意编程 — 随机涂鸦生成器
turtle 虽简单却强大,适合学习编程思维、创作艺术图案、制作教育演示。
本文是 Python 教程系列的第四十六篇。
