Python易學就會(四)turtle繪圖入門--高級篇

  到目前爲止咱們經過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()方法。

相關文章
相關標籤/搜索