当数学公式变成画笔轨迹,代码本身就是艺术
那天,女儿从美术课回来,把画纸拍在桌上:
女儿: "妈妈,老师说我画的树太死板了……"
我: "怎么死板了?"
女儿: "就是……就是每一根树枝都一样长,像电线杆!真正的树是有的长有的短,有的弯有的直……"
爸爸:(从旁边探头)"闺女,让Python帮你画一棵真正的树?"
女儿: "啊?Python还会画画?"
爸爸: "不仅会画,还能画出你画不出来的——分形树,和真树一样,每一枝都不一样,但整体看起来又像!"
十分钟后,女儿看着屏幕上"生长"出来的树,树枝自动分叉、变细、弯曲,惊呆了:
"它在画自己!像真的树一样!"
这就是Turtle的魔法:一只小海龟,听你指挥,用数学的规律,画出自然的美丽。
想象你有一只机器人小海龟:
它拿着一支笔,可以在画布上爬行
forward(100)= 向前爬100步,画出一条线
left(90)= 原地左转90度
penup()= 抬起笔(移动但不画)
pendown()= 放下笔(开始画)
pencolor("red")= 换红笔
speed(0)= 最快速度(0是瞬移,1-10是越来越快)
核心秘密:Turtle画图就是把数学变成视觉——角度、距离、循环、递归,都变成图案。
核心思路:让小海龟边转圈边前进,每次转一点点,画出一个螺旋。
import turtlet = turtle.Pen() # 创建画笔t.speed(0) # 最快速度for x in range(100): # 画100条线t.forward(x) # 线越来越长(第1条线1像素,第100条100像素)t.left(91) # 每次左转91度(不是90度,所以不会闭合)
效果:一个不断向外扩散的方形螺旋!
女儿的发现:"91度不是90度,所以它不会画成正方形,而是转着转着就歪了,像蜗牛壳!"
import turtlet = turtle.Pen()t.speed(0)turtle.bgcolor("black") # 黑色背景,颜色更鲜艳colors = ["red", "yellow", "blue", "green"]for x in range(100):t.pencolor(colors[x % 4]) # 循环使用4种颜色:0%4=0(红), 1%4=1(黄)...t.forward(x)t.left(91)
效果:红→黄→蓝→绿→红→黄……的彩虹螺旋!
核心概念:x % 4是取模运算(除法的余数),让颜色循环使用。这是"周期性变化"的数学表达。
import turtlet = turtle.Pen()t.speed(0)turtle.bgcolor("black")sides = 6 # 改成3是三角形,4是正方形,5是五角星形...colors = ["red", "yellow", "blue", "green", "purple", "orange"]for x in range(360):t.pencolor(colors[x % sides])t.forward(x * 3 / sides + x) # 边数越多,线越短t.left(360 / sides + 1) # 360度÷边数 = 正多边形内角t.width(x * sides / 200) # 线越来越粗
效果:六边形的彩色螺旋,像万花筒!
跨学科连接:
数学:角度、多边形内角和、等差数列(线长递增)
艺术:色彩循环、线条粗细变化、构图平衡
核心思路:树的大枝和小枝形状相似,这叫自相似性(分形)。用递归(函数调用自己)实现。
想象俄罗斯套娃:
大娃娃里有个小娃娃
小娃娃里有个更小的娃娃
直到娃娃太小,停止
递归函数同理:
画一根树枝
在树枝末端画两根小树枝(调用自己)
直到树枝太短,停止
import turtledef 画树(树枝长度, 角度, 深度):"""递归画树函数"""if 树枝长度 > 5: # 停止条件:树枝太短就不画了# 画当前树枝t.forward(树枝长度)# 画右边的小树枝(递归!)t.right(角度)画树(树枝长度 * 0.7, 角度, 深度 + 1) # 长度×0.7,越来越细# 画左边的小树枝(再递归!)t.left(角度 * 2)画树(树枝长度 * 0.7, 角度, 深度 + 1)# 回到原位(像退后一步)t.right(角度)t.backward(树枝长度)# 初始化t = turtle.Pen()t.speed(0)t.left(90) # 朝上画t.penup()t.goto(0, -200) # 从底部开始t.pendown()t.color("brown") # 树干棕色# 画树!画树(100, 20, 0) # 主干100像素长,分叉角度20度turtle.done() # 保持窗口打开
效果:一棵树从底部"生长"出来,自动分叉,越来越细,像真正的树!
女儿的震惊:"它自己调用自己!就像……就像我在镜子里看到镜子里的我!"
核心概念:
递归:函数调用自己,解决"大问题分解成小问题"
分形:自相似的几何形状,自然界到处都是(树、云、海岸线、雪花)
终止条件:if 树枝长度 > 5,防止无限递归
import randomdef 画彩色树(树枝长度, 角度):if 树枝长度 > 5:# 树干棕色,树叶绿色if 树枝长度 < 20:t.color("green") # 小树枝变绿叶else:t.color("brown")t.forward(树枝长度)# 随机变化角度,更自然右角度 = 角度 + random.randint(-10, 10)左角度 = 角度 + random.randint(-10, 10)t.right(右角度)画彩色树(树枝长度 * random.uniform(0.6, 0.8), 角度)t.left(右角度 + 左角度)画彩色树(树枝长度 * random.uniform(0.6, 0.8), 角度)t.right(左角度)t.backward(树枝长度)t.color("brown") # 退回去时恢复棕色
效果:每棵树都不一样!有的枝繁叶茂,有的歪歪扭扭,像真实的树林。
核心思路:用random模块随机决定位置、颜色、大小、形状,让电脑"自由创作"。
import turtleimport randomt = turtle.Pen()t.speed(0)turtle.bgcolor("black")colors = ["red", "yellow", "blue", "green", "orange", "purple", "white"]def 随机螺旋():"""在随机位置画一个随机螺旋"""# 随机位置x = random.randint(-300, 300)y = random.randint(-300, 300)# 随机大小大小 = random.randint(10, 40)# 随机颜色t.pencolor(random.choice(colors))# 移动过去(不画)t.penup()t.setpos(x, y)t.pendown()# 画螺旋for m in range(大小):t.forward(m * 2)t.left(91)# 画50个随机螺旋for n in range(50):随机螺旋()
效果:满屏彩色螺旋,像烟花,像星系,像万花筒!
女儿的评价:"这比我自己画的还好看!因为……因为我不会想到把紫色和绿色放在一起!"
import turtleimport randomt = turtle.Pen()t.speed(0)turtle.bgcolor("black")colors = ["red", "yellow", "blue", "green", "orange", "purple"]def 画螺旋(x, y):"""在鼠标点击的位置画螺旋"""t.pencolor(random.choice(colors))大小 = random.randint(10, 40)t.penup()t.setpos(x, y)t.pendown()for m in range(大小):t.forward(m * 2)t.left(92)# 点击屏幕任意位置,调用画螺旋函数turtle.onscreenclick(画螺旋)turtle.done()
玩法:点击屏幕,就在哪里生成一个彩色螺旋!你可以"种"出一片螺旋花园。
❌ NG镜头1:"窗口一闪就关了,什么都没看到!"
案发现场:程序运行完,窗口瞬间消失。
导演复盘:
忘了写
turtle.done()或screen.mainloop()!程序执行完就退出了,不会保持窗口。
急救方案:在代码最后加:
turtle.done() # 或 screen.mainloop()❌ NG镜头2:"递归树变成一团乱麻,像蜘蛛网!"
案发现场:树的分枝乱飞,不是向下生长,而是向各个方向。
导演复盘:
忘了控制方向!每次递归后,要用
backward退回去,并且用right/left恢复角度。否则海龟就像醉汉,越走越偏。
急救方案:确保每次递归后:
t.right(角度) # 恢复角度t.backward(长度) # 退回去
❌ NG镜头3:"颜色报错,说不是有效颜色!"
案发现场:写了t.pencolor("红色"),程序报错。
导演复盘:
Turtle只认英文颜色名或RGB值。中文"红色"不认识,要写
"red"或(255, 0, 0)。
急救方案:
使用英文颜色名:"red","yellow","blue","green","purple","orange","white","black"
或用RGB元组:t.pencolor((255, 128, 0)) #橙色
(爸爸看着满屏的随机螺旋,在草稿纸上画的图)
闺女,你今天掌握了三种编程范式:
1. 迭代(Iteration):彩色螺旋用for循环,重复+变化创造规律。这是算法艺术的基础——用简单的规则,生成复杂的图案。
2. 递归(Recursion):分形树用函数调用自己,自相似+缩放创造自然形态。这是分形几何的核心——大自然用递归构建万物(树、血管、河流、闪电)。
3. 随机性(Randomness):随机艺术用random引入不可预测性,这是生成艺术(Generative Art)的秘密。计算机的"创造力"不是模仿人,而是探索人想不到的组合。
关于数学与艺术的连接:
角度:91度vs90度,螺旋vs正方形
比例:0.7的缩放因子,决定树的"丰满度"
黄金分割:试试角度 = 137.5度(黄金角),画出向日葵螺旋,这是自然界最优的排布方式!
最后的挑战:你能用L系统(Lindenmayer System)画植物吗?这是一种字符串替换规则:
开始:"F"(向前画)
规则:F → F[+F]F[-F]F(F是画线,[]是保存/恢复位置,+/-是转弯)
迭代3次,得到复杂的植物形态
这是形式文法在图形中的应用,也是现代计算机生成植物的标准方法。
彩色螺旋:至少4种颜色,边数可调(3-8边形)
分形树:棕色树干+绿色树叶,随机角度
随机花园:10个随机位置、随机大小、随机颜色的螺旋
提交方式:Trinket链接,或录制视频展示画图过程(Turtle的慢速模式可以看清每一笔)。
画五角星:用for循环5次,每次forward(100),right(144)度(180-36=144,五角星内角)
画满天星:随机位置画50颗星星,大小不一,颜色从白色到黄色渐变
闪烁效果:用turtle.tracer(0)关闭动画,一次性显示,模拟"瞬间出现"的夜空
数学知识:五角星的角度计算(外角36度,转向144度)。
画一朵花:中心圆+6个花瓣(椭圆或圆)
画花茎:用递归画弯曲的茎(像分形树,但只有一侧分支)
随机花园:3-5朵花,位置、大小、颜色随机,组成"花丛"
工程思维点:封装画一朵花(x, y, 大小, 颜色)函数,复用画多朵。
用递归分割法画迷宫:
1.画一个大方框
2.在中间画一堵墙,留一个缺口(门)
3.在墙的左右/上下两侧,递归画小迷宫
4.直到方框太小,停止
爸爸挑战:这是深度优先搜索(DFS)算法的可视化,真正的迷宫生成器都用这个思路。试着让小海龟边走边画,像真的在"探索"迷宫!
那天晚上,女儿把画的树打印出来,贴在床头:
"妈妈,这棵树是我'种'出来的,不是画出来的。我告诉了它规则,它自己长成了这样。"
我点点头:"对,这就是生成艺术的魅力。你不是在复制自然,你是在模拟自然的规律——分枝、生长、随机、迭代。"
是的,孩子。Turtle不仅教你编程,更教你用数学的眼睛看世界:
螺旋是等差数列的可视化
树是递归的自然形态
随机艺术是概率的美学表达
代码,是你通往艺术与科学的桥梁。
(我们要放下画笔,拿起"文字魔杖"——用条件判断选择路径,用循环探索迷宫,用字典存储宝藏,用函数封装战斗。你将创建一个完整的文字冒险游戏:玩家输入指令,程序描述场景,战斗、寻宝、升级……这是游戏开发的终极篇章,也是编程思维的大综合!)