基于前面学习的turtle模块基本函数,在GitHub及其它网站中找到部分turtle绘制图形的示例,本文选取部分案例,学习案例源码,分析绘图思路,以巩固turtle基本函数的用法。
绘制爱心
网上找到的绘制爱心的例子大部分都是直线和圆弧拼成的爱心(参考文献3-4),这两种画法都是采用的circle函数。
circle函数的声明为turtle.circle(radius, extent=None, steps=None),绘制圆形的话只需给出半径即可,圆心位置在海龟左边 radius 个单位,如果需要画圆弧,则需指定extent,并以当前画笔位置为一个端点绘制圆弧,radius 为正值则朝逆时针方向绘制圆弧,否则朝顺时针方向。steps指定圆内切正多边形的边数。
参考文献3-4中的绘制爱心,都是先从左侧开始左斜上方绘制一段直线,然后绘制圆弧,区别在于参考文献3中是4段圆弧拼成的,而参考文献4只有两段圆弧。相比之下,参考文献3中的爱心看着更柔和。
import turtledef DrawHeart4Arc(): turtle.pendown()turtle.setheading(150)turtle.begin_fill()turtle.fd(25) turtle.circle(25 * -3.745, 45)turtle.circle(25 * -1.431, 165)turtle.left(120)turtle.circle(25 * -1.431, 165)turtle.circle(25 * -3.745, 45)turtle.fd(25)turtle.end_fill()def DrawHeart2Arc():turtle.left(45)turtle.begin_fill()turtle.forward(80) turtle.circle(35,210) turtle.right(150) turtle.circle(35,212) turtle.forward(82)turtle.end_fill()turtle.color('red', 'pink')turtle.pensize(2)turtle.penup();turtle.forward(100)DrawHeart4Arc()turtle.seth(0)turtle.penup()turtle.backward(200)turtle.pendown()DrawHeart2Arc()turtle.hideturtle()
绘制樱花树(不固定层数)
参考文献1中给出的绘制樱花树的代码,使用的都是最基本的绘制直线的函数(主要就是起笔、落笔、左转、右转函数),特别之处在于采用递归方式从下往上、从右向左绘制树干、树枝、树叶,树干、树枝、树叶的长度逐步变小、宽度逐步变窄,最后在树根附近生成指定数量的树叶。由于树干、树枝、树叶、落叶的位置带有一定的随机性,每次程序运行绘制的图像也各不相同。所谓不固定层数是指中止递归的条件为树叶或树枝的长度小于指定值后停止递归。
绘图代码请见参考文献1,本文仅列出以下稍显复杂程序绘图截图,同时录制了相对简单的程序绘图动画,如下所示:
绘制樱花树(固定层数)
参考文献5中给出了多种绘制樱花树的案例,其中一种为上面介绍的非固定层数画法,其余几种都是固定层数的画法,即樱花树有n层,其中n-1曾为树干和树枝,第n层是树叶,其余绘图思路都差不多,即从下往上、从右向左递归绘制树干、树枝、树叶。
绘制层数超过5层之后,带绘图动作的话,程序运行就很耗时,因此案例程序中调用turtle.tracer函数以便直接显示绘图结果(输入参数为0的话会禁用海龟动画并设置刷新图形频率为0,帮助文档中没有明确些,个人感觉为0的话应该是不主动刷新)。本文展示绘图层数为10层的绘图效果,具体代码详见参考文献5(这三组绘制樱花树的代码类似,不同之处仅是具体的权重值、参数值不同而已,代码逻辑是一样的)。
绘制哆啦A梦
参考文献2和参考文献5中都有绘制哆啦A梦的案例,其中参考文献2绘制的是全身,而参考文献5中只绘制了头部。本文主要分析参考文献2中的绘制逻辑,绘制程序运行结果如下图所示。
首先是头部,多啦A梦的头是个弧形,不是圆形,且起笔位置不在绘图原点处,由于turtle的circle函数不支持起始弧度和结束弧度,参考文献2绘制头部弧形时,先是提笔移动到圆的逆时针的40度,再落笔逆时针绘制280度的圆弧。
其次绘制红色围巾时,参考文献2采用多个1/4圆弧和直线方式绘制圆角矩形。绘制眼睛时,由于眼睛是个椭圆,circle函数无法绘制椭圆 ,用圆弧拼椭圆的话也不好拼。参考文献2中采用120段短直线模拟椭圆(类似的代码也用于绘制小猪佩奇的鼻子),具体的代码片段如下所示。
其余的代码都是通过移动到指定位置后组合绘制线段、圆弧拼出哆啦A梦的身体、胡须、嘴巴、手、脚等位置,在此不再赘述,有兴趣的可以直接参考参考文献2中的代码。
for i in range(120):if 0 <= i < 30 or 60 <= i < 90:a -= 0.05lt(3)fd(a)else:a += 0.05lt(3)fd(a)
上述几个案例,尤其是绘制哆啦A梦的代码,最麻烦的不是绘图思路,而是计算各个关键点的位置、圆弧的半径和弧度、线段长度等数据,确定每个值都很麻烦,不知道有没有比较好的软件或工具能测量位置、角度或半径等信息。除此之外,才是一些绘图技巧,例如实现turtle模块不支持的一些绘图功能(椭圆等)。后续还会继续找案例学习turtle的用法。
参考文献:
[1]/niubiqigai/turtle
[2]/PerpetualSmile/Python-Painting-Doraemon
[3]/article/221611.htm
[4]/article/229943.htm
[5]/July__July/article/details/99543992?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-2-99543992-blog-127901584.pc_relevant_landingrelevant&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-2-99543992-blog-127901584.pc_relevant_landingrelevant&utm_relevant_index=2
[6]/zh-cn/3/library/turtle.html