资讯专栏INFORMATION COLUMN

Python易学就会(五)turtle绘制椭圆与递归

lk20150415 / 2302人阅读

摘要:现实生活中,有很多图形是非常有规律性的,这样的图形如果使用递归算法来实现,程序就会非常简洁,运行效果也会很好。下面我们来用画一棵树,感受一下中的递归算法和的克隆功能。

  前两篇文章基本涵盖了turtle的大部分功能,同时也借由对turtle功能的展示,厘清了Python的一些语法特点,以利于新手入门。但是短短几个例子,阐述得还是有限,这里再展开两个知识点,一方面对turtle做个补遗,另一方面把Python语法的大框架过完一遍。

  第一个是画椭圆。上一节中描述了如何用turtle画一个圆,或者是一段弧线,但是在很多图形中需要用到椭圆,如何画出一段优美的椭圆,是本篇的第一个知识点。

  上节中有提到turtle中的circle()方法,其核心就是割圆术,也就是用正多边形来模拟一个圆。我们知道,正8边形比正6边形肯定要更接近一个圆,正16边形比正8边形又更接近一个圆,如果我们能画出一个正120边形,或者正360边形的话,那是非常接近一个圆的。下面就沿着这个思路,来画一个正120边形。不用说,在普通个人电脑上,“正120边形”在我们眼里肯定它就是一个“圆”了。上代码:

import turtle as t
t.pendown()
t.setheading(90)            # 朝上(正北方向)
for j in range(120):        # 重复执行120次
    t.forward(3)            # 移动3个单位
    t.left(3)               # 左转3度
t.penup()
t.done()

  运行这个例子,可以看到turtle从原点出发,按逆时针方向画了一个圆。如果修改forward()中的参数,可以画出不同半径的圆。

  这个画法跟circle()本质上没有区别。但是,却给了我们更大的自由度,来操控这段曲线,例如,修改代码如下:

import turtle as t
t.pendown()
t.setheading(90) 
for j in range(60):         # 重复执行60次
    t.forward(3)
    t.left(3)
t.penup()
t.done()

  将重复运行的次数改为60次,每次还是转动3度,我们就可以得到一段60*3=180度的弧线。在不同的角度区间内,修改画弧的速度,也即修改forward()走的快慢,我样就可以得到一段椭圆弧,看代码:

import turtle as t
t.pendown()
t.setheading(90)
len = 1                     # 设置初始走的速度为1
for j in range(60):
    if j < 30:              # 当j<30,也就是画前一半的弧线
        len += 0.2          # 让速度越走越快
    else:                   # 画后一半弧线
        len -= 0.2          # 让速度越走越慢
    t.forward(len)
    t.left(3)
t.penup()
t.done()

  运行这段代码,可以看到turtle画出了一段椭圆弧。能画成椭圆弧的关键是if-else条件语言的应用。if-else属于分支语句,跟前面学过的顺序、循环共同构成Python语言的三大控制结构。在这个例子中,我们一共画60步弧线,在前30步,让画弧的速度由慢到快,后30步,速度由快到慢,这样不匀速的画法,就形成了一条椭圆弧。

  接下来完善这段代码,画出一个完整的椭圆来:

import turtle as t
t.pendown()
t.setheading(90)
len = 1
for k in range(2):         # 将相同的动作重复做一遍
    for j in range(60):
        if j < 30:
            len += 0.2
        else:
            len -= 0.2
        t.forward(len)
        t.left(3)

t.penup()
t.done()

  运行这段代码,可以看到turtle画出了一个完美的椭圆。相对于上一个例子,我们只增加了一条语句,即“for k in range(2):”,也就是将画上一半弧的方法,在下一半上重复使用一次即可。当然,你也可以通过改变if-else的方法来实现,只会逻辑上要复杂一点。

  从这里我们也可以看到,turtle绘图用的方法还是比较简单,适合于初学者入门使用,基本上不涉及计算机图形学的内容,要真正好出漂亮和复杂的弧线,turtle库还是不够。

  第二个是用turtle实现递归绘图。

  现实生活中,有很多图形是非常有规律性的,这样的图形如果使用递归算法来实现,程序就会非常简洁,运行效果也会很好。下面我们来用turtle画一棵树,感受一下Python中的递归算法和turtle的克隆功能。树的最大特点就是每个树干都会左右分叉成两枝,而每枝又会再次分叉,这样循环往复一直进行。我们先来画一个树干分叉的小例子:

import turtle
p = turtle.Pen()           # 第一支画笔
p.penup()
p.goto(0, -200)            # 移动到初始位置
p.setheading(90)           # 向上(正北方向)
p.pensize(7)
p.pencolor("green")
p.pendown()                # 落笔
p.forward(200)             # 画第一条树干
q = p.clone()              # 克隆出第二支笔来
p.left(65)                 # 第一支笔往左转
q.right(65)                # 第二支笔往右转
p.forward(200 * 0.65)
q.forward(200 * 0.65)
turtle.done()

  运行这个小例子,可以看到,turtle在界面上画出一个Y形的树支,这个就是我们递归的基础,后面所有的小树枝是都这样画出来。这里用到一个很重要的知识点,就是clone()方法,我们用clone()克隆出第二笔,以便于从树干分别往两边画。

  接下来,改造上面的小例子,应用递归函数,让turtle帮我们不断的画出更多的树枝来,上代码:

#-*- coding:utf-8 –*-
#用递归函数实现turtle画一棵树。
#所有递归函数都可以转化为非递归来实现,
#如果需要非递归方法的代码,请加公众号:see_goal 留言“turtle画树”
import turtle
p = turtle.Pen()
p.penup()
p.goto(0, -200)
p.setheading(90)
p.pensize(7)
p.pencolor("green")
p.pendown()

def branch(plist, len):            # 自定义函数,画树枝
    if (len > 15):                 # 递归的退出条件
        list = []                  # 新画笔列表
        for p in plist:            # 遍历旧画笔列表
            p.forward(len)
            q = p.clone()
            p.left(65)
            q.right(65)
            list.append(p)         # 存入新画笔列表
            list.append(q)         # 存入新画笔列表
        branch(list, len * 0.65)   # 递归,list为新画笔列表,树枝长65%

branch([p], 200)
turtle.done()

  运行这段代码,可以看到turtle在界面上递归的画出一棵树。

  这棵树上的每一个小箭头,都代表着一个turtle的Pen对象。也就是说,我们通过不断的克隆Pen,来实现让每个树枝都能向左右两边伸展。而每一次伸展的长度都是上一个树枝的0.65倍,也就是越伸越短。当短到<15时,递归结束。每次克隆出的新Pen,都通过list.append()方法存到列表中,传递给下一次调用,这样就给人一种树枝不断发芽生长的动画效果。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/43009.html

相关文章

  • Python易学就会(三)turtle绘图入门--初级篇

    摘要:比如把上面画正方形的例子稍做变化重复执行次画正方形开始画正方形结束右转度执行后,可以看到,画出一个非常规整漂亮的组合图案。   turtle图形库源于1966年诞生的Logo语言,是入门Python的有趣工具。因其简单便捷的图形化方法、和立即反馈式的绘画效果,成为众多编程入门者的首选。相对于大多数入门教材中枯燥的语法学习,和函数、方法的演练来说,turtle的趣味性显得别具一格、极富效...

    周国辉 评论0 收藏0
  • Python易学就会(四)turtle绘图入门--高级篇

    摘要:也就是说明这个参数除了表示圆的半径面,其正负性还定义了画圆的方向。入门篇中有个小彩蛋,也就是可以修改的指针外形。通过初始化出多只新,可以同时在一个界面上以不同的绘图。下面给出一段绘制实时时钟的代码,重点部分我已给出注释。   到目前为止我们通过turtle库了解了Python的基本语法,包括顺序与循环、函数的调用与方法的定义、列表与简单的数学运算等;也学习了用turtle库绘图的基本用...

    Miracle 评论0 收藏0
  • Python 送你一棵圣诞树

    摘要:但今年不能老送同样的东西啊,那就给大家送上几棵圣诞树吧。极简版这个可算是最简单的圣诞树了。例如上面这棵圣诞树,每一个树枝又是一个小的圣诞树。这与编程中的递归思想很像顶部五角星略过炫彩版一般圣诞树上都会挂上的小彩灯。 今天是圣诞节,先祝大家圣诞快乐! 有人要说了,圣诞节是耶稣诞生的日子,我又不信基督教,有啥好庆祝的。这你就有所不知了,Python 的诞生也跟圣诞节有关:1989 年,那是...

    miya 评论0 收藏0
  • 除了画佩奇我们还要玩点更高级的

    摘要:啥是佩奇已不重要。佩奇是他用搜集的所有信息,一点一滴的用心创造编织爱的过程。画佩奇的代码已经上传到后台,公众号后台回复社会人即可获取。 你告诉爷爷你需要什么东西呀,爷爷给你准备,佩奇,什么是佩奇呀?... 这是一个发生在大山里的故事,但故事的情节所有人都不会陌生。快过年了,在农村爷爷给城里的孙子打电话,孙子说想要佩奇,为了满足孩子的心愿,爷爷开始满村子找佩奇… 当除夕夜家人团聚,爷爷开...

    Dean 评论0 收藏0
  • 除了画佩奇我们还要玩点更高级的

    摘要:啥是佩奇已不重要。佩奇是他用搜集的所有信息,一点一滴的用心创造编织爱的过程。画佩奇的代码已经上传到后台,公众号后台回复社会人即可获取。 你告诉爷爷你需要什么东西呀,爷爷给你准备,佩奇,什么是佩奇呀?... 这是一个发生在大山里的故事,但故事的情节所有人都不会陌生。快过年了,在农村爷爷给城里的孙子打电话,孙子说想要佩奇,为了满足孩子的心愿,爷爷开始满村子找佩奇… 当除夕夜家人团聚,爷爷开...

    tomener 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<