学径 LearnPath

编程语言基础

海龟几何

思考几何图形如何被描述为一段过程。

讲解模式

通过本节课,你将理解:

#goal

欧几里得几何谈点、线、角的关系。还有另一种写法,更接近人在地面上走路:让一个带着朝向的点在平面上运动,形状就是它留下的痕迹。

这叫相对几何——你不先给出顶点坐标,而给出「走多远、转几度」。

海龟画图 把这套写法收进一个 模块。在 在线 IDE 里导入之后,画布会出现在编辑区旁边。默认朝向是正东(0∘0^\circ);树和字母 Y 要往上长,起笔先让海龟朝北。

本节课你将学会:forward 与 left 如何成为可执行的几何原语;位置与朝向为何合称状态;以及如何用循环画正方形、用 函数 画字母 Y,并在结束时把姿态还原。

帕尔特让几何变成可以走的思想

#hook

1960 年代,多数人接触计算机仍接近批处理:打孔卡片进机房,隔一段时间取回打印结果。几何若要进入这种机器,通常先被翻译成坐标表。

西摩·帕尔特(Seymour Papert)走了另一条路。他与同事在 Logo 语言里放入一只「海龟」:起初是地板上的真机器人,后来是屏幕上的三角形指针。发出的指令不是「把点画在某格」,而是「沿你正面对的方向走出去,再转向」。

西摩·帕尔特
西摩·帕尔特。Matematicamente.it。来源:Wikimedia Commons,CC BY-SA 3.0。

帕尔特受过皮亚杰发生认识论的训练。他关心的不是「画画软件」,而是一个更硬的主张:有些数学思想,只有当你能用自己的身体去扮演它们时,才真正变得可思考。left(90) 不是抽象的旋转矩阵,而是「朝自己的左边转直角」。

Python 标准库里的 turtle 模块,正是向 Logo 致敬。本课用它,不是为了学一套绘图函数清单,而是为了把相对运动变成可以运行的几何。

前进与转向:可执行的几何原语

#explore-commands

海龟从两条原语开始:沿当前朝向移动一段距离,以及改变朝向。

python
import turtle

t = turtle.Turtle()
t.pencolor("#1d385f")
t.forward(80)
t.left(90)
t.forward(80)

第二行造出一只海龟,默认在画布中央附近,朝向正东,笔是落下的。随后:沿朝东走 80,逆时针转直角,再走 80。画布上应出现一条横线,再接一条竖线。可在 在线 IDE 中运行。

常用指令:

指令作用
t.forward(d) / t.backward(d)沿当前朝向前进或后退 dd
t.left(a) / t.right(a)逆时针或顺时针转 aa 度
t.penup() / t.pendown()抬笔(移动不画)、落笔
t.setheading(90)把朝向设为正北

backward 不是擦除:它沿来路退回,笔若落下会再描一遍,但位置回到分叉点。left(90) 是相对转角;setheading(90) 是绝对朝向。本课的 Y 用相对转角,是为了让「在当前姿态上再转一点」可以叠层。

状态:位置与朝向缺一不可

#explore-state

海龟在任意时刻的状态,至少包括两件事:位置和朝向。二者合称姿态。

forward 沿朝向平移位置,不改朝向。left 改朝向,不改位置。backward 沿来路退回位置,朝向保持——因此从分叉点走出左枝再 backward,位置回到分叉点,朝向仍偏左。若还要把朝向拧回主干,必须再转一次。位置回家与朝向回家,是两步,不是一步。

函数若声称「画了一个 Y」,却把海龟留在右枝顶端,它交出去的就不是可组合的图形,而是弄脏了工作台。验收一段海龟程序,不只看画布像不像,还要问:跑完之后,海龟停在哪里、面朝哪一边?

正方形是重复四次的相对运动

#explore-square

正方形可以写成动的:沿当前方向走边长,左转 90∘90^\circ,做四遍,并且做完后姿态与出发时相同。循环 比抄四遍更接近问题:形状来自同一条规则的反复执行。

python
import turtle

t = turtle.Turtle()
t.pencolor("#1d385f")

for _ in range(4):
    t.forward(80)
    t.left(90)

循环变量写成 _,表示计数本身不进入几何。改 80 就改尺度。走完四边后,海龟应回到起点、朝向与出发时相同——外角和为 360∘360^\circ,四次 90∘90^\circ 转完,朝向闭合;四次等长前进,位置闭合。

把 range(4) 改成 range(3) 再运行,是一次受控的反例:重复次数不再匹配外角和,过程就不再证明正方形。

字母 Y:一枝画完,必须退回分叉

#explore-y

Y 可以看成:一根主干,到顶点向左右各伸出一枝。关键不在会不会画线,而在状态:左枝画完若不退回,右枝就会从错误的地方长出来。

  1. 沿当前方向画主干;海龟停在分叉点。
  2. 左转 30∘30^\circ,画较短的左枝,再原路退回;位置对了,朝向仍偏左 30∘30^\circ。
  3. 右转 60∘60^\circ(相对主干是向右 30∘30^\circ),画右枝,再退回。
  4. 左转 30∘30^\circ,朝向恢复,再沿主干退回起点。

为什么右转到 60∘60^\circ?因为海龟还停在「朝左 30∘30^\circ」上。要从偏左转到偏右,相对自身需要转两角之和。

python
import turtle

t = turtle.Turtle()
t.left(90)


def draw_y(length):
    t.forward(length)
    t.left(30)
    t.forward(length * 0.7)
    t.backward(length * 0.7)
    t.right(60)
    t.forward(length * 0.7)
    t.backward(length * 0.7)
    t.left(30)
    t.backward(length)


draw_y(80)

draw_y 结束时,海龟回到调用前的位置和朝向。这不是装饰,是接口。下一课要把左右两枝换成更小的树——替换能够成立,前提正是每一层都把自己造成的位移和转角撤回去。

本节练习:走一个等边三角形

#practice

在 在线 IDE 里 import turtle,建立一只海龟,先 left(90) 让它朝北。再用循环走三次:每次前进 80,再左转 120∘120^\circ。跑完后它应回到起点,朝向仍朝北。外角三次合计 360∘360^\circ,姿态才算还原。

本节要点

#review
  • 海龟默认朝东;向上画先改变朝向。形状是指令的痕迹。帕尔特把几何写成身体可以跟随的过程,是为了让思想可执行。
  • 位置与朝向合在一起才是状态。forward 改位置,left 改朝向,backward 退回位置但不自动恢复转过的角。
  • 正方形用循环重复「前进 + 转直角」。同一规则执行四次,比四个顶点清单更接近「走一个正方形」。
  • 画 Y 时,一枝画完必须退回分叉点,并恢复朝向。把「画一个 Y」写成函数,是为后续递归做准备。

单选题

默认朝向

本平台海龟的默认朝向是?

单选题

为什么要后退

画完 Y 的左枝后执行 backward,主要是为了什么?

单选题

Y 画完时海龟在哪

draw_y 按课文写完整段后,海龟应停在哪里?

单选题

状态包含什么

对海龟几何而言,「状态」首先必须同时包括哪两项,函数结束时才谈得上把世界还原?

未登录时不会保存学习进度