到目前爲止咱們經過turtle庫瞭解了Python的基本語法,包括順序與循環、函數的調用與方法的定義、列表與簡單的數學運算等;也學習了用turtle庫繪圖的基本用法,包括座標與角度、落筆擡筆、顏色與填充等。編程
可是咱們所繪的全部內容僅限於直線,對於曲線的繪製,一直沒有涉及。從如今開始,咱們就來了角一下用turtle庫怎麼畫曲線,首先咱們來畫一個圓,看代碼:ide
import turtle as t t.circle(100) # 畫一個半徑爲100的圓 t.mainloop() # 等效於t.done()
運行這個例子,咱們能夠看到,turtle從座標原點開始,按逆時針方向畫出了一個圓。很是簡單,一條語句就實現了。函數
第一個問題是,若是有但願turtle按順時針方向畫,應該怎樣實現?嗯,將t.circle(100)中的參數100改成-100便可,也就是t.circle(-100)。也就是說明這個參數除了表示圓的半徑面,其正負性還定義了畫圓的方向。修改一下上面的代碼:oop
import turtle as t t.circle(100) # 從原點開始按逆時針方向畫圓,直徑爲100 t.circle(-100) # 從鼠標所在點開始按順時針方向畫圓,直徑爲100 t.mainloop()
運行這段代碼,能夠看到turtle在界面上畫出一個8字形,先逆時針方向畫圓,再順時針方向畫圓。能夠看到turtle畫這兩個圓中的第一個時,至關於從圓的下底開始畫(也即圓的-90度位置);畫第二個圓至關於從上頂位置開始畫(也即90度的位置)。學習
那麼,第二個問題來了,若是我但願從圓的0度位置開始畫,或者180度位置開始畫,應該怎麼操做?修改一下上面的實例代碼:spa
import turtle as t t.setheading(90) # 設置turtle的方向爲正北(向上)方向 t.circle(100) # 逆時針畫 t.circle(-100) # 順時針畫 t.mainloop()
運行一下例子,能夠看到,第一個圓是從0度位置開始畫的,而第二個圓是從180度位置開始畫的。經過這個小改動,咱們能夠看到,turtle畫圓時,沒有明確的「圓心」概念,而是以「初始方向+半徑」來決定一個圓的位置和大小。其核心原理等同於割圓術。設計
接下來,咱們來看一下怎樣畫一段弧線,而不是完整的圓。t.circle()的第一個參數是半徑,第二個參數就是圓弧的角度,默認是360度。修改一下上面的例子:指針
import turtle as t t.setheading(90) t.circle(100, 120) # 畫一段120度的弧線 t.penup() # 擡起筆來 t.goto(0, 0) # 回到圓點位置 t.setheading(90) # 向上畫 t.pendown() # 落筆,開始畫 t.circle(-100, 120) # 畫一段120度的弧線 t.mainloop()
運行這例子,能夠看到turtle在界面上向左和向右各畫了兩段弧,即120度長度的弧線。中間增長的擡筆、回圓點、設置初始方向、落筆,主要是爲了從新初始化繪圖的前提條件,以便於跟前面的例子作對比。調試
因而可知,turtle畫曲線的方法仍是比較簡陋的,須要配合其它的方向、座標、位移等來一塊兒實現。接下來,咱們來畫一個稍微複雜一點,可是很是有趣的小蛇,看代碼:code
import turtle as t t.penup() t.goto(-150, 0) # 到起始點 t.pensize(25) # 設置畫筆粗細 t.pencolor('green') # 設置畫筆顏色 t.setheading(45) # 向45度方向畫 t.pendown() t.circle(-50, 90) # 順時針方向畫90度的弧線 t.circle(50, 90) # 繼續按逆時針方向畫弧 t.circle(-50, 90) t.circle(50, 45) t.setheading(0) # 繼續向0度方向畫 t.forward(50) t.circle(10, 160) # 繼續畫一個160度的小弧 t.setheading(160) # 面向小弧的最後角度 t.forward(8) # 再向前伸一點 t.mainloop()
運行這個小例子,能夠看到,turtle在界面上畫出了一條彎彎曲曲的小綠蛇。經過編程,能夠清晰的展示出用turtle庫畫弧線,就是要配合方向、座標、位移等來一塊兒實現。接下來,咱們再配合上初級篇中的函數定義,來畫一隻小篩子,來模擬咱們「師高編程」的LOGO,上代碼:
import turtle as t def hair(): # 畫頭髮 t.penup() t.goto(-50, 150) t.pendown() t.fillcolor('#a2774d') t.begin_fill() for j in range(10): # 重複執行10次 t.setheading(60 - (j * 36)) # 每次調整初始角度 t.circle(-50, 120) # 畫120度的弧 t.end_fill() def face(): # 畫臉 t.penup() t.goto(0, 100) t.pendown() t.fillcolor('#f2ae20') t.begin_fill() t.setheading(180) t.circle(85) t.end_fill() #下巴 t.circle(85, 120) t.fillcolor('white') t.begin_fill() t.circle(85, 120) t.setheading(135) t.circle(100, 95) t.end_fill() def ears(dir): # 畫眼睛,dir用來設置方向,左右眼對稱 t.penup() t.goto((0-dir)*30, 90) t.setheading(90) t.pendown() t.fillcolor('#f2ae20') t.begin_fill() t.circle(dir*30) t.end_fill() t.penup() t.goto((0-dir)*40, 85) t.setheading(90) t.pendown() t.fillcolor('white') t.begin_fill() t.circle(dir*17) t.end_fill() def nose(): # 畫鼻子 t.penup() t.goto(20, 0) t.setheading(90) t.pendown() t.fillcolor('#a2774d') t.begin_fill() t.circle(20) t.end_fill() def eye(dir): # 畫耳朵,dir用來設置方向,左右耳對稱 t.penup() t.goto((0-dir)*30, 20) t.setheading(0) t.pendown() t.fillcolor('black') t.begin_fill() t.circle(10) t.end_fill() def mouth(): # 畫嘴巴 t.penup() t.goto(0, 0) t.setheading(-90) t.pendown() t.forward(50) t.setheading(0) t.circle(80, 30) t.penup() t.goto(0, -50) t.setheading(180) t.pendown() t.circle(-80, 30) hair() ears(1) ears(-1) face() eye(1) eye(-1) mouth() nose() t.done()
運行這段代碼,能夠看到turtle在界面上畫出一個小獅子的頭像。綜合運用方向、座標、位移,加上一點耐心和對座標位置的調試,用turtle的確能夠畫出任何你想像的圖形。
入門篇中有個小彩蛋,也就是能夠修改Python的turtle指針外形。默認的指針就是一個小箭頭,咱們能夠經過t.shape('turtle'),將這個小箭頭改爲一隻真正的小烏龜,增長編程的趣味性。
可是,咱們還能夠進一步,來設定本身的指針外形,將指針改爲咱們但願的任何樣式,這一過程主要經過如下幾個方法的組合來實現:
t.begin_poly() # 開始繪製 # 繪製指針過程省略 t.end_poly() # 結束繪製 poly = t.get_poly() # 獲取繪製 t.register_shape('name', ploy) # 註冊一個名爲'name'的shape newPoint = t.Pen() # 初始化一隻新turtle newPoint.shape('name') # 讓這隻turtle使用名爲'name'的shape
可見,重點是turtle庫中提供了一個t.register_shape()方法,以供咱們註冊本身的shape,有了這個方法,在特定的條件下,就能夠極大的方便咱們的程序設計。經過初始化出多隻新turtle,能夠同時在一個界面上以不一樣的shape繪圖。下面給出一段繪製實時時鐘的代碼,重點部分我已給出註釋。
#-*- coding:utf-8 –*- #用turtlr畫時鐘 #以自定義shape的方式實現 #固然,使用多隻turtle來徹底重繪的方法實現,也沒有問題。 #若是須要重繪方法的代碼,請加公衆號:see_goal 留言「turtle時鐘」 import turtle as t import datetime as d def skip(step): # 擡筆,跳到一個地方 t.penup() t.forward(step) t.pendown() def drawClock(radius): # 畫表盤 t.speed(0) t.mode("logo") # 以Logo座標、角度方式 t.hideturtle() t.pensize(7) t.home() # 回到圓點 for j in range(60): skip(radius) if (j % 5 == 0): t.forward(20) skip(-radius-20) else: t.dot(5) skip(-radius) t.right(6) def makePoint(pointName, len): # 鐘的指針,時針、分針、秒針 t.penup() t.home() t.begin_poly() t.back(0.1*len) t.forward(len*1.1) t.end_poly() poly = t.get_poly() t.register_shape(pointName, poly) # 註冊爲一個shape def drawPoint(): # 畫指針 global hourPoint, minPoint, secPoint, fontWriter makePoint("hourPoint", 100) makePoint("minPoint", 120) makePoint("secPoint", 140) hourPoint = t.Pen() # 每一個指針是一隻新turtle hourPoint.shape("hourPoint") hourPoint.shapesize(1, 1, 6) minPoint = t.Pen() minPoint.shape("minPoint") minPoint.shapesize(1, 1, 4) secPoint = t.Pen() secPoint.shape("secPoint") secPoint.pencolor('red') fontWriter = t.Pen() fontWriter.pencolor('gray') fontWriter.hideturtle() def getWeekName(weekday): weekName = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'] return weekName[weekday] def getDate(year, month, day): return "%s-%s-%s" % (year, month, day) def realTime(): curr = d.datetime.now() curr_year = curr.year curr_month = curr.month curr_day = curr.day curr_hour = curr.hour curr_minute = curr.minute curr_second = curr.second curr_weekday = curr.weekday() t.tracer(False) secPoint.setheading(360/60*curr_second) minPoint.setheading(360/60*curr_minute) hourPoint.setheading(360/12*curr_hour + 30/60*curr_minute) fontWriter.clear() fontWriter.home() fontWriter.penup() fontWriter.forward(80) # 用turtle寫文字 fontWriter.write(getWeekName(curr_weekday), align="center", font=("Courier", 14, "bold")) fontWriter.forward(-160) fontWriter.write(getDate(curr_year, curr_month, curr_day), align="center", font=("Courier", 14, "bold")) t.tracer(True) print(curr_second) t.ontimer(realTime, 100) # 每隔100毫秒調用一次realTime() def main(): t.tracer(False) drawClock(160) drawPoint() realTime() t.tracer(True) t.mainloop() if __name__ == '__main__': main()
運行這個例子,能夠看到turtle在界面上實時展現出一個時鐘。咱們從新編寫過的這段代碼仍是比較簡潔,以前沒有介紹到的就是用turtle怎麼輸出文字,詳細能夠看例子中的write()方法。