Scratch编程进阶:从数学原理到算法实现,掌握画圆与几何艺术创作

📅 2026/7/29 7:28:36
Scratch编程进阶:从数学原理到算法实现,掌握画圆与几何艺术创作
1. 从数学课到编程课为什么“画圆”是Scratch进阶的必经之路如果你问一个刚学Scratch的孩子画一个圆难不难他可能会觉得很简单——画笔工具里不是有个画圆的积木吗点一下输入半径一个完美的圆就出现了。这确实是Scratch提供的一种“快捷方式”。但今天我想从一个数学老师的视角和你聊聊在Scratch里“画圆”这件事。它远不止是调用一个积木那么简单而是一个绝佳的、融合了数学思维与编程逻辑的实战项目。当我们抛开那个现成的“画圆”积木尝试用最基础的“移动”和“旋转”指令让角色自己“走”出一个圆时我们实际上是在复现人类理解圆形几何本质的过程。这个过程会逼着我们去思考什么是半径什么是360度为什么角色移动一小段、旋转一小度重复足够多次就能形成一个圆这背后是正多边形的极限思想是角度与弧度的换算是循环与变量的精妙配合。对于学习者尤其是青少年通过编程来“构造”一个圆其价值远超“绘制”一个圆。它能将抽象的数学概念如圆周率π、角度、坐标系转化为可视的、可交互的动态过程。当孩子调整一个参数立刻看到图形发生的变化时那种“原来如此”的顿悟感是任何静态的教科书插图都无法给予的。所以这篇内容就是带你深入这个“构造”的过程。我们会从最朴素的思路开始一步步推导、优化、扩展直到你能游刃有余地控制Scratch画出任意大小、任意精度的圆甚至创作出更复杂的图案。这不仅是学会一个技巧更是掌握一种用计算思维解决几何问题的通用方法。2. 核心原理拆解不用“画圆”积木圆是怎么“走”出来的在深入代码之前我们必须先建立正确的数学模型。Scratch的舞台是一个480x360的坐标系角色画笔的“画圆”本质上是让角色沿着一个圆形路径运动并沿途留下痕迹。2.1 正多边形逼近法理解“圆”的编程本质最核心的思想叫做“正多边形逼近法”。想象一下我们要画一个正三十六边形。让角色执行以下步骤落笔。向前移动一段距离这将是多边形的边长。向右旋转10度因为360度 / 36 10度。将第2、3步重复36次。拾笔。你会发现画出来的是一个非常接近圆形的三十六边形。当边数足够多时比如360条边每次旋转1度肉眼就完全看不出棱角这就是一个完美的“圆”了。这里移动的“一段距离”并不是圆的半径而是正多边形的一条边的长度。那么如何根据我们想要的圆的半径R来计算每次移动的距离即边长记为步长呢这就涉及到一个简单的数学公式步长 ≈ 2 * π * R / 边数。2 * π * R是圆的周长。除以边数就近似得到了正多边形每条边的长度。当边数很大时这个近似就非常精确。在Scratch中我们可以用(2 * 3.14159 * 半径) / 重复次数来计算步长。但这里有一个更巧妙的、不需要预先计算周长的方法它直接利用了半径和角度的关系。2.2 半径旋转法更直观的“画圆”算法另一种更符合直觉的方法是“半径旋转法”。我们不让角色沿着圆的切线方向走而是想象角色始终站在“半径”的末端。角色初始位置在圆心(x0, y0)。角色向0度方向正右方移动半径R的距离到达圆上的一点。落笔。角色以圆心为中心旋转1度。但Scratch角色是围绕自身中心旋转的如何实现绕圆心旋转这里需要一点坐标计算。更简单的方法是角色向圆心方向移动一个微小距离然后再向外移动回圆周但方向已经改变了1度。不过这种方法计算复杂。实际上在编程中更通用且易于理解的是参数方程法。圆上任意一点的坐标(x, y)可以用参数方程表示x x0 R * cos(角度)y y0 R * sin(角度)如果我们让“角度”从0度循环增加到360度并不断计算新的坐标然后让角色移动到(x, y)就能画出圆。Scratch虽然没有直接的cos和sin函数但它有相关的运算积木。然而对于初学者我们完全可以先用“正多边形逼近法”来构建直观理解它所需的数学知识更少更贴近“用动作画图”的思维。注意在向初学者讲解时“正多边形逼近法”因其动作化、流程化的特点更容易被接受。我们可以先教这个方法等他们熟练后再引入坐标和三角函数的概念讲解更强大的“参数方程法”这是一个循序渐进的认知过程。3. 手把手实现从36边形到光滑的圆现在我们进入Scratch实操环节。我将带领你实现一个可调节半径和精度的画圆程序。3.1 基础版本画一个固定半径的圆我们首先实现一个半径为100的圆用360边形来逼近这样最光滑。初始化与变量创建新建一个项目从角色库中添加一个你喜欢的角色比如箭头Arrow1它将成为我们的“画笔”。在“变量”分类中创建以下变量适用于所有角色半径用来设置要画的圆的大小。边数用来控制正多边形的边数边数越多圆越光滑。步长根据半径和边数计算出的每次移动的距离。角度每次旋转的角度由360 / 边数计算得出。将半径设为100边数设为360先固定。核心脚本编写 将以下积木组合在一起通常放在“当绿旗被点击”或“当角色被点击”下面。当绿旗被点击 全部擦除 将 [半径 v] 设为 [100] 将 [边数 v] 设为 [360] 将 [角度 v] 设为 ((360) / (边数)) 将 [步长 v] 设为 (((2) * (3.14159)) * (半径)) / (边数)) 定位到 x: (0) y: (0) // 回到舞台中心作为圆心 面向 (90) 度 // 面朝上起始方向也可以设为0度右 抬笔 移到圆心位置 // 这里假设圆心在(0,0)角色先走到圆周起点 移动 (半径) 步 落笔 重复执行 (边数) 次 移动 (步长) 步 右转 (角度) 度 结束 抬笔关键点解释将 [步长 v] 设为 (((2) * (3.14159)) * (半径)) / (边数))这就是我们前面推导的公式计算每条边的近似长度。使用3.14159作为π的近似值。重复执行 (边数) 次循环边数次每次画一条边并旋转。移动 (步长) 步和右转 (角度) 度这是画图的核心动作。每次画一条很短很短的边因为边数多然后旋转一个很小的角度最终路径闭合成一个圆。运行与观察 点击绿旗你会看到角色从圆心出发移动到圆周然后开始画圆。由于边数设为360画出的圆非常光滑。你可以尝试将边数改为36、72等较小的数观察图形如何从正多边形逐渐逼近圆形。这是一个非常直观的数学演示。3.2 进阶优化制作可交互的画圆工具基础版本只能画固定大小的圆。我们来把它改造成一个可以通过输入框或滑块自由控制参数的工具。添加输入控件在舞台上右键点击半径和边数这两个变量选择“滑杆”。这样舞台上会出现对应的滑块你可以拖动滑块实时改变它们的值。或者你也可以使用“询问并等待”积木在运行前让用户输入。改造脚本实现“一键重画” 我们需要将画圆的逻辑封装成一个自定义积木函数这样可以随时调用并且代码更清晰。在“自制积木”分类中点击“制作新的积木”命名为画圆。在定义画圆积木时添加两个输入项半径参数和边数参数。将之前核心脚本中计算和循环的部分拖到定义 画圆 (半径参数) (边数参数)下面。用输入项半径参数和边数参数替换原来脚本中固定的半径和边数变量。改造后的主脚本和自定义积木定义如下当绿旗被点击 全部擦除 定位到 x: (0) y: (0) 面向 (90) 度 抬笔 画圆 (半径) (边数) // 调用自定义积木使用当前变量值 定义 画圆 (半径参数) (边数参数) 将 [角度 v] 设为 ((360) / (边数参数)) 将 [步长 v] 设为 (((2) * (3.14159)) * (半径参数)) / (边数参数)) 抬笔 定位到 x: (0) y: (0) 移动 (半径参数) 步 // 走到圆周起点 落笔 重复执行 (边数参数) 次 移动 (步长) 步 右转 (角度) 度 结束 抬笔实现动态效果 为了让改变滑块时能实时看到效果我们可以给变量添加“当变量值改变”的监控。对于半径和边数变量在变量上右键选择“勾选”以在舞台上显示。然后我们可以创建一个单独的脚本用来监听变化并重画当 [半径 v] 发生变化 // 这是一个事件需要从“事件”分类中拖出“当变量值改变”并选择“半径” 全部擦除 画圆 (半径) (边数) 当 [边数 v] 发生变化 // 同样处理边数变化 全部擦除 画圆 (半径) (边数)现在你拖动半径或边数的滑块画布会自动擦除并根据新参数重新画圆。你可以清晰地看到边数很小时是多边形变大后就成了圆半径滑块则控制圆的大小。实操心得在封装画圆自定义积木时务必处理好“笔的状态”和“角色的初始位置与方向”。一个常见的坑是连续调用画圆时因为前一次结束时笔可能落下或角色不在圆心导致图形错乱。好的习惯是在自定义积木的开头明确设置笔的状态抬笔和角色的起点归位到圆心并复位方向在结尾再将笔抬起。这样能保证每次调用都是独立的、干净的。4. 问题排查与性能优化为什么我的圆画得慢或不圆在实际操作中你可能会遇到一些意想不到的情况。我们来逐一分析并解决。4.1 常见问题一画出的圆有缺口或不闭合现象圆画完后起点和终点没有完全重合留下一个小缺口。根因分析计算精度误差这是最常见的原因。我们使用的步长 2 * π * R / N和角度 360 / N都是除法运算。Scratch以及所有计算机处理浮点数时存在微小的精度损失。当N不能被360整除时角度可能是一个无限循环小数计算机存储的近似值会导致最后一次旋转后累计角度不是精确的360度。角色初始位置偏差如果角色不是从准确的圆周起点开始画或者移动 (半径) 步这一步因为方向问题有偏差也会导致路径不闭合。解决方案方法A治标增加边数。边数越多每条边的步长越短单次误差的影响越小缺口就越不明显。通常360边已经足够。方法B治本采用“绝对坐标画法”即参数方程法。这种方法直接计算每个点的坐标然后让角色“瞬移”过去不依赖于“移动”和“旋转”的累积从根本上避免了累积误差。虽然对初学者稍难但它是更精确的工业标准方法。其伪代码逻辑如下定义 用坐标画圆 (圆心x) (圆心y) (半径) (边数) 将 [i v] 设为 [0] 抬笔 重复执行 (边数) 次 将 [当前角度 v] 设为 ((i) * ((360) / (边数))) // 计算当前角度 将 [x坐标 v] 设为 ((圆心x) ((半径) * ([cos v] 的 (当前角度)))) // 需要“运算符”里的cos 将 [y坐标 v] 设为 ((圆心y) ((半径) * ([sin v] 的 (当前角度)))) 如果 (i) [0] 那么 // 如果是第一个点先移动过去再落笔 定位到 x: (x坐标) y: (y坐标) 落笔 否则 定位到 x: (x坐标) y: (y坐标) // 否则直接移动到下一点笔已落下会自动画线 结束 将 [i v] 增加 (1) 结束 抬笔方法C实用技巧在“正多边形逼近法”的循环结束后强制让角色面向初始方向并移动一小段距离连接到起点。或者直接让重复执行的次数比边数多1次最后一次只移动不旋转强行闭合。4.2 常见问题二画圆速度太慢尤其是边数很多时现象当边数设置为1000甚至更大时画圆过程变得非常缓慢像慢动作。根因分析Scratch是解释型语言每个积木块的执行都需要时间。重复执行1000次意味着要进行1000次“移动”、“右转”以及背后的屏幕刷新。此外“画笔”功能在绘制大量线段时也会消耗较多资源。优化方案减少不必要的屏幕刷新在画非常复杂的图形前可以使用“全部擦除”积木但更重要的是可以考虑在画图过程中暂时隐藏角色。因为角色的造型渲染也需要时间。使用隐藏积木画完后再显示可以提升速度。使用“自制积木”并选择“运行时不刷新屏幕”这是Scratch里最重要的性能优化技巧在“制作新的积木”时对话框底部有一个复选框“运行时不刷新屏幕”。勾选它之后Scratch会等这个自定义积木里的所有指令都执行完毕后才一次性更新舞台画面。对于画圆这种由大量重复步骤组成的操作速度提升是数量级的。操作修改我们之前创建的画圆自定义积木在定义时勾选“运行时不刷新屏幕”。效果你会看到圆几乎是瞬间出现的而不是一段一段地动画绘制。合理设置边数对于屏幕显示而言边数达到360-720之间人眼已经无法区分多边形和圆。盲目追求上万边数只会浪费性能没有视觉收益。一般设置360或720是一个在效果和性能间很好的平衡点。4.3 常见问题三想画一个实心圆或者彩色圆环怎么办需求延伸我们目前画的是空心圆。如何画一个实心的圆或者一个有粗细、有渐变颜色的圆环解决方案思路实心圆一种方法是画很多个半径递增的同心圆。从半径1开始到目标半径R结束每次画一个圆半径增加1。这样整个圆形区域就被填满了。你可以将这个逻辑放入一个循环中。定义 画实心圆 (半径) 将 [当前半径 v] 设为 [1] 重复执行 (半径) 次 画圆 (当前半径) (360) // 调用之前定义的画圆积木边数固定 将 [当前半径 v] 增加 (1) 结束注意这种方法画大的实心圆会比较慢因为要画很多个圆。另一种更高效的方法是使用Scratch的“图章”功能但“图章”画的是角色造型不是矢量线条。彩色圆环/渐变圆这需要用到“画笔”分类中的将画笔颜色设为和将画笔饱和度设为等积木。我们可以在画圆的循环中动态改变画笔的颜色。例如让颜色值随着循环变量i的增加而改变。将 [颜色 v] 设为 [0] 重复执行 (边数) 次 将画笔颜色设为 (颜色) 移动 (步长) 步 右转 (角度) 度 将 [颜色 v] 增加 ((100) / (边数)) // 让颜色从0渐变到100 结束这样画出来的圆颜色会平滑地过渡形成一个彩虹色的圆环。5. 创意拓展从画圆到构建复杂图案掌握了精确画圆的能力你就拥有了一把创作复杂几何艺术品的钥匙。圆的组合、变形、迭代能产生令人惊叹的视觉效果。5.1 画一组同心圆这是最简单的拓展。只需固定圆心用循环改变半径反复调用画圆积木。当绿旗被点击 全部擦除 定位到 x: (0) y: (0) 将 [r v] 设为 [10] // 起始半径 重复执行 (10) 次 // 画10个同心圆 画圆 (r) (360) 将 [r v] 增加 (20) // 半径每次增加20 结束你可以修改每次半径的增量、圆的个数、甚至每个圆的颜色来创造不同的视觉效果。5.2 画“繁花曲线”旋转中的圆这是一个非常经典的图案。原理是让角色在画一个大圆的同时自身也在缓慢旋转。这需要用到两个嵌套的循环。外层循环控制画多少个“花瓣”或完成多少圈旋转。例如重复360次。内层循环画一个完整的小圆。但这里的小圆半径不大。关键每画完一个小圆角色在外层循环中旋转1度360/3601然后开始画下一个小圆。由于画每个小圆时角色的方向都在变化这些小圆的圆心分布在一个大圆周上从而组合成花朵般的图案。当绿旗被点击 全部擦除 定位到 x: (0) y: (0) 将 [花瓣数 v] 设为 [12] 将 [大半径 v] 设为 [100] // 花朵的“半径” 将 [小半径 v] 设为 [30] // 每个花瓣小圆的半径 抬笔 重复执行 (花瓣数) 次 // 1. 移动到当前花瓣的圆心位置 移动 (大半径) 步 // 2. 画一个小圆 落笔 重复执行 (36) 次 // 用36边形画小圆速度快 移动 (((2) * (3.14159)) * (小半径) / (36)) 步 右转 (10) 度 // 360/3610 结束 抬笔 // 3. 回到大圆中心 定位到 x: (0) y: (0) // 4. 旋转准备画下一个花瓣 右转 ((360) / (花瓣数)) 度 结束调整花瓣数、大半径、小半径你可以得到玫瑰、太阳花、齿轮等各式各样的图案。5.3 结合随机性创造动态艺术让参数随机化可以产生不可预测的、动态的艺术效果。例如一个“随机彩色泡泡”生成器当绿旗被点击 全部擦除 将画笔粗细设为 (5) 重复执行 (20) 次 // 随机位置 定位到 x: (在 (-200) 到 (200) 间随机选一个数) y: (在 (-150) 到 (150) 间随机选一个数) // 随机颜色 将画笔颜色设为 (在 (1) 到 (100) 间随机选一个数) // 随机半径 将 [r v] 设为 (在 (10) 到 (50) 间随机选一个数) // 画圆 落笔 重复执行 (360) 次 移动 (((2) * (3.14159)) * (r) / (360)) 步 右转 (1) 度 结束 抬笔 结束每次运行都会在舞台上随机位置生成20个大小、颜色各异的圆像彩色的泡泡。从理解一个简单的数学原理开始到实现一个可交互的工具再到排查问题、优化性能最后进行创意发散——这就是“跟数学老师学Scratch”系列想传递的学习路径。画圆只是一个起点。当你理解了如何用指令“构造”一个圆你就掌握了用程序描述几何形状的基本能力。这种能力可以迁移到画正方形、画螺旋线、画任何由数学方程定义的曲线。更重要的是你学会了将复杂问题分解画圆 - 画很多短边、模式识别重复移动旋转、抽象用变量表示半径和精度和算法设计正多边形逼近这一套计算思维的核心流程。下次当你再看到Scratch里那个简单的“画圆”积木时你看到的将不再是一个黑箱工具而是一个可以被你拆解、理解和再造的思维过程。这才是编程学习中最宝贵的部分。