Scratch:海龟绘图(九)
在本课的前导部分,我们说到怎么做才能成为一个负责任的“程序猿”。我认为,负责任的程序员决不会草率的处理任何“函数接口”。
比如这个“画圆”函数,程序员就会认真推敲“哪些参数是必要的、哪些参数又是多余的”,并设身处地的思考“如果我是用户,一个什么样的函数才是我最需要的”。最终,他会从“圆的本质”出发,得出结论:用户画圆时最需要考虑的是“圆的半径”,“半径”定了,圆也就确定下来了。因此,把“半径”作为“画圆”函数的参数,无疑是最适合不过的。
如果有了这个以“半径”为参数的画圆函数,用户就轻松多了。而作为程序猿的我们,就要来思考除“半径”以外,画圆时的所有细节——用多少边形去近似模拟一个圆?每边的边长是多少?画完每一边要转多少度?等等等等。
虽然问题很多,但这是“程序猿”义不容辞的责任。我们不会被这些问题吓倒,就来“个个击破”吧!
首先需要考虑的是正多边形的“边数”。下图展示了半径相同时,不同边数的多边形效果。
从上图可以发现:边数太少不行,这样画出的圆不够“圆”,“正多边形”的痕迹过于明显;增加边数,圆倒是更“圆”了,但程序需要更多的时间去“画”,效率降低了。
30边形看起来已经很像个“圆”了,为了使效果更好一些,我们姑且把边数定为“60”吧,似乎已经足够了,而且也不至于对效率产生太大影响。
然而,“固定的边数”会引发另一个问题,如下图:
对于边数相同、半径不同的多边形,如果用户把“半径”设置的很长,圆就会很大,那么每边的边长也必然增大,这又会导致“正多边形”的痕迹过于明显;如果用户把“半径”设置的很短,圆就会很小,那么每边的边长也必然减小,甚至会小到只有“1个像素”,这是完全没有必要的,白白浪费了运行时间和系统资源。看来“边数”不是那么好确定,“固定边数”的路好像走不通。
不要紧,我们再来试试“边长”。通过上面的分析我们知道,边长过长,会使“正多边形”的痕迹过于明显;边长过短,会浪费时间和资源。那么边长设为多少合适呢?前人经过大量的实验,得出的结论是:只要边长不大于“3个像素”,人眼就会把“正多边形”认作是“圆”。那么好,为了提高效率,我们就把边长设置为“3”好了。
“边长”确定了,“边数”就好办了。我们知道了圆的“半径”,小学数学老师曾经告诉我们,要计算圆的“周长”,只要使用公式“2πr”就好了。算出了“周长”,又知道“边长”,自然也就能算出“边数”了。
“边长”和“边数”都定下来了,再画起“圆”来就易如反掌了。您问“为什么”?因为我们有现成的“绘制边长为 length 的正 n 边形”这个函数啊!
至此,问题迎刃而解。理清了思路,代码写起来就容易多了。
Step1:制作新的积木,取名为“画半径为r的圆”
Step2:定义变量“周长”,并使用公式“2πr”计算周长
Step3:计算边数。由于边数必须为整数,所以这里我们使用系统提供的“取整函数”来得到整数边数
注意:这里使用的是“向上取整”,即不管小数点后的第1位数是几,都向上“进一”。
Step4:计算边长
可能您会问了:不都说好了边长是“3”吗,怎么还要计算边长呢?
要回答这个问题,我们得把刚才计算的过程重新捋一下:我们先用2πr算出了周长,然后“假设”边长为3,用周长除以边长3来计算边数。由于我们估计这样算出的边数极有可能不是个整数(比如是20.65),因此对它进行了“向上取整”(把20.65向上取整为21)。我们用2πr算出的周长本来刚好等于“3✖️20.65”,取整后周长变成了“3✖️21”,周长变长了!虽然只长了不到一条边的距离,但仍然是长了。周长变长就会导致半径增大,我们画出的圆就会比用户想画的圆大上那么“一丢丢”。
虽然这“一丢丢”非常小,但作为一个严谨的、负责任的程序猿,我们不允许在“算法”上存在任何缺陷。为此,我们再用周长除以边数,计算出精确的边长(边长可以是小数)。使我们的圆与用户心目中的完全吻合。
至此,我们已打通了最后一个“心结”,赶快用上面的积木组合出我们最终的画圆函数吧。函数的最终成果如下图所示:
下节课,我们即将迎来“海龟绘图”部分的终极挑战,绘制下面图中的“花”:
提示:这朵“花”看似复杂,其实单看每一个“花瓣”,都是由两条对称的“圆弧”组成的。所以,解决了圆弧的问题,“花”也就完成了一大半。今天的课程里我们已经学会了画“圆”,那么圆弧该怎么画呢?
项目小结:
在今天的项目中,我们:
1. 从“圆的本质”出发,写出了以“圆的半径r”为参数的“画圆函数”;
2 在设计“画圆函数”的过程中,进一步熟悉、理解了“接口设计”的思路、过程和意义;
3. 知道了在定义一个新的函数(积木)时,可以“重复利用”之前已经定义过的函数(积木);
4. 在设计“画圆函数”方面,成为了一名负责任、有担当的“程序猿”。
Scratch:海龟绘图(九)的更多相关文章
- Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 7. 条件循环
条件循环能够让程序在条件成立时(即为真时)重复执行循环体中的语句.如果条件一直成立(即永远不会为假),则循环会一直进行下去,不会停止.如果初始时,条件不成立,则循环 1 次也不会执行.Python 中 ...
- Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 6. 条件
前面的教程中,我们已经可以让小海龟绘制出各种图形了.但是,所有绘图的代码都是预先编好的,程序一旦运行起来,运行结果(绘制的图形)就是固定不变的.这一节中,咪博士将教大家如何让海龟响应用户的输入. im ...
- Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 5. 参数
上一个教程中,咪博士带大家学习了函数的使用.例如,line_without_moving 函数,可以让海龟先画出一条线段,然后再回来起点. def line_without_moving(): tur ...
- Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 4. 函数
什么样的程序员才是优秀的程序员?咪博士认为“慵懒”的程序员才是真正优秀的程序员.听起来不合逻辑?真正优秀的程序员知道如何高效地工作,而不是用不止境的加班来完成工作任务.函数便是程序员高效工作的利器之一 ...
- Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 3. 循环
在前面的教程中,咪博士留了一道练习题给大家—-画正方形,相信聪明的你应该已经画出来了. 下面是咪博士实现的代码. 是不是跟你的代码很像呢? import turtle turtle.forward(2 ...
- Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 2. 变量
大家在中学就已经学过变量的概念了.例如:我们令 x = 100,则可以推出 x*2 = 200 试试下面这段 Python 代码 import turtle turtle.shape("tu ...
- Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 1. 神秘朋友
Python (Windows 下) 自带了一个非常有趣的 海龟绘图程序 (turtle),它是本系列课程的主角. 在 PyCharm 中,新建一个项目,然后在代码编辑器中输入 import turt ...
- Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 0. 准备工作
一.关于 Python Python 是全球使用人数增长最快的编程语言!它易于入门.功能强大,从 Web 后端 到 数据分析.人工智能,到处都能看到 Python 的身影. Python 有两个主要的 ...
- python海龟绘图
最近学了python,看了几本书之后,才明白python的强大,python是一种解释型的语言,即每写一行程序就执行一行. 而且在科学计算方面,处理的能力特别的方便. 比如python中的字典dict ...
随机推荐
- 小程序 image跟view标签上下会有间隙
图片文字等inline元素默许是跟父级元素的baseline对齐,而baseline又和父级底边有必定间距 我是使用: 加上这个消除了间隙,如果没有解决,你可以分别用 vertical-align:t ...
- 【spark 算子案例】
package spark_example01; import java.io.File; import java.io.FileWriter; import java.io.IOException; ...
- JS 定时器的4种写法及介绍
JS提供了一些原生方法来实现延时去执行某一段代码,下面来简单介绍一下setTiemout.setInterval.setImmediate.requestAnimationFrame. 一.什么是定时 ...
- OpenJudge数据结构与算法-计算点的距离并排序
/*================================================================== 距离排序 总时间限制: 1000ms 内存限制: 65536k ...
- SM30维护视图屏蔽按钮
标准维护视图 GUI状态 ESLG 编辑按钮 AEND 达到效果 DATA: l_act TYPE char1, l_name TYPE dd02v-tabname. DATA: lt_vimex ...
- HmacSHA256算法(C# 和 Java)
Java代码: /** * HmacSHA256算法,返回的结果始终是32位 * @param key 加密的键,可以是任何数据 * @param content 待加密的内容 * @return 加 ...
- 过滤emoji表情的方法
public static function replaceEmoji($str) { $str = preg_replace_callback( '/./u', function (array $m ...
- $(this).addClass('class').siblings('class').removeClass('class')的作用
$(this).addClass('class'):为当前元素添加'class'类(供选择器使用 - - ) $(this).siblings('class'):查找当前元素的所有类名为 " ...
- Selenium ? 也要学...!
一.selenium 简介 Selenium是ThroughtWorks公司一个强大的开源Web功能测试工具系列,包括Selenium-IDE.Selenium-RC.Selenium-Webdriv ...
- WebGL学习之纹理盒
原文地址:WebGL学习之纹理盒 我们之前已经学习过二维纹理 gl.TEXTURE_2D,而且还使用它实现了各种效果.但还有一种立方体纹理 gl.TEXTURE_CUBE_MAP,它包含了6个纹理代表 ...