前兩篇文章基本涵蓋了turtle的大部分功能,同時也藉由對turtle功能的展現,釐清了Python的一些語法特色,以利於新手入門。可是短短几個例子,闡述得仍是有限,這裏再展開兩個知識點,一方面對turtle作個補遺,另外一方面把Python語法的大框架過完一遍。算法
第一個是畫橢圓。上一節中描述瞭如何用turtle畫一個圓,或者是一段弧線,可是在不少圖形中須要用到橢圓,如何畫出一段優美的橢圓,是本篇的第一個知識點。app
上節中有提到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()走的快慢,我樣就能夠獲得一段橢圓弧,看代碼:spa
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步,速度由快到慢,這樣不勻速的畫法,就造成了一條橢圓弧。code
接下來完善這段代碼,畫出一個完整的橢圓來:對象
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()方法存到列表中,傳遞給下一次調用,這樣就給人一種樹枝不斷髮芽生長的動畫效果。