python之turtle使用:畫一顆美美噠的樹
關於工具介紹這裡小生就不贅述了,這裡附上個人覺得最詳細的文件地址:https://docs.python.org/zh-cn/3/library/turtle.html?highlight=turtle#turtle.TurtleScreen
先看效果圖:
以上就是小生犧牲午休時間搗鼓出來的~雖然不是辣麼好看,但是還是想跟大夥分享一下,進入正題。
程式碼主要分為兩部分:樹程式碼部分,地上花瓣部分
樹程式碼部分
其實程式碼很簡單,主要是我們得知道如何去實現那些關鍵點(我知道這是廢話,但是我總得說點什麼湊字數...):
1,樹幹應該是越往上越細 - 即畫筆越往上 size 尺寸越小
2,枝幹越往上越短 - 枝幹延伸的長度
3,枝幹會分叉 - 即遞迴事件繼續執行的入口
4,枝幹分叉的角度 - 畫筆偏移度
4,要長點什麼 - 遞迴事件的出口
滿足了以上幾點,這棵樹看起來才會正常一點(或者說符合大眾觀念)。總的來說,我們需要一個點來決定遞迴事件
的入口和出口,這裡我用分叉次數來決定,當然還可以用延伸長度等或一個變數,只要我們能找到出入條件,看程式碼:
1 # 畫樹方法: n為枝幹延伸次數,l為枝幹延伸長度 2 def drawTree(n, l): 3 pendown() 4 # 設定畫筆顏色 - 枝幹顏色 5 pencolor('#5d3c3c') 6 # 畫筆尺寸 7 pensize( n / 1.5) 8 # 延伸長度 9 forward(l) 10 # 根據 n 判斷是否繼續遞迴延伸枝幹 或 結束本分支延伸 11 if n > 0: 12 # dr 為畫筆順時針偏移度,dl 為畫筆逆時針偏移度 13 dr = randint(30, 40) 14 dl = randint(30, 40) 15 16 # 本次延伸長度:每一次隨機減少延伸長度(所以也可以根據 l 來設定 pensize等) 17 move = l * (random() * 0.4 + 0.5) 18 19 # 順時針偏移 dr 20 right(dr) 21 # 遞迴呼叫自身,剩餘延伸次數 -1 22 drawTree(n - 1, move) 23 # 因為上面順時針偏移了 dr,所以順時針的偏移度加上逆時針偏移度:dr + dl 才是分叉實際偏移度 24 left(dr + dl) 25 drawTree(n - 1, move) 26 # 順時針偏移dl,回到畫筆原指向 27 right(dl) 28 else: 29 # 本分支延伸結束,呼叫畫花朵方法 30 drawPetal(3) 31 # 提起畫筆 32 penup() 33 # 回到開始延伸的位置 34 backward(l)
花朵程式碼:
枝幹完成指定分叉次數後,為了好看一點,即需要長點什麼,如程式碼:
1 # 花朵繪畫方法: n 為花朵半徑(其實就是圓半徑...) 2 def drawPetal(n): 3 # 指定顏色模式為 rgb 模式 4 colormode(255) 5 # 隨機生成 rgb 色值 6 r = randint(200, 255) 7 g = randint(8, 158) 8 b = randint(8, 158) 9 10 # 畫圓並填充顏色 11 begin_fill() 12 fillcolor(r, g, b) 13 pencolor(r, g, b) 14 circle(n) 15 end_fill()
到這裡如果只是為了畫一棵樹,那我們的工作已經基本完成了,當然我們需要一個啟動方法:
def run(): # 設定畫布比例: 相對顯示屏 setup(1.0, 1.0) penup() # 移動到座標 (-50, -150) goto(-50, -150) # 逆時針旋轉90度,使畫筆指向正上方 left(90) pendown() # 隱藏畫筆 hideturtle() # 是否追蹤繪畫過程:即是否一步一步顯示繪畫過程 tracer(False) # 呼叫樹方法 drawTree(13, 150)
將上訴程式碼複製到編輯器裡,在呼叫 run()方法,一棵樹神奇的樹就會出現了(假設你已經安裝了python執行環境)。
讓我們再給它灑上一些花瓣,這裡花瓣的位置小生將它放在樹起始點下方,其實你完全可以隨意指定位置和範圍以及大小
來展示一張飄落的效果(我已經看過了,很好看):
1 # 花瓣位置生成: m 為花瓣數量,x y 決定繪畫花瓣初始位置 2 # 這裡我將花瓣初始位置設定為樹起點位置附近 3 def petalPlace(m, x, y): 4 penup() 5 goto(x, y) 6 pendown() 7 setheading(0) 8 tracer(False) 9 for i in range(m): 10 # 起始點畫一朵 11 if i == 0: 12 drawPetal(5) 13 else: 14 penup() 15 goto(x, y) 16 # a 為下一朵花瓣水平方向相對起始點距離 17 a = randint(20, 400) 18 # b 為下一朵花瓣垂直方向相對起始點距離 19 b = randint(-50, 50) 20 21 # 將畫筆移動相應距離 22 forward(a) 23 left(90) 24 forward(b) 25 right(90) 26 pendown() 27 28 # 呼叫花瓣繪畫方法 29 drawPetal(5)
到這裡我們的所有程式碼已經完成,下面是所有程式碼(已去掉註釋):
1 from turtle import * 2 from random import * 3 4 # 畫樹方法 5 def drawTree(n, l): 6 pendown() 7 pencolor('#5d3c3c') 8 pensize( n / 1.5) 9 forward(l) 10 if n > 0: 11 dr = randint(30, 40) 12 dl = randint(30, 40) 13 move = l * (random() * 0.4 + 0.5) 14 right(dr) 15 drawTree(n - 1, move) 16 left(dr + dl) 17 drawTree(n - 1, move) 18 right(dl) 19 else: 20 drawPetal(3) 21 penup() 22 backward(l) 23 24 # 花瓣位置生成 25 def petalPlace(m, x, y): 26 penup() 27 goto(x, y) 28 pendown() 29 setheading(0) 30 tracer(False) 31 for i in range(m): 32 if i == 0: 33 drawPetal(5) 34 else: 35 penup() 36 goto(x, y) 37 a = randint(20, 400) 38 b = randint(-50, 50) 39 forward(a) 40 left(90) 41 forward(b) 42 right(90) 43 pendown() 44 drawPetal(5) 45 46 # 花朵繪畫方法 47 def drawPetal(n): 48 colormode(255) 49 r = randint(200, 255) 50 g = randint(8, 158) 51 b = randint(8, 158) 52 begin_fill() 53 fillcolor(r, g, b) 54 pencolor(r, g, b) 55 circle(n) 56 end_fill() 57 58 # 啟動方法 59 def run(): 60 setup(1.0, 1.0) 61 penup() 62 goto(-50, -150) 63 left(90) 64 pendown() 65 hideturtle() 66 tracer(False) 67 drawTree(13, 150) 68 petalPlace(160, -100, -150) 69 70 run() 71 done()
值得注意的是,因為我們使用了很多隨機生成的值,所以每一次生成的樹都一樣,也就是你說,我們可以造一片森林,
有了上面的程式碼,我們需要補充的已經很少了:
大致思路就是隨機生成樹的起始點,再呼叫我們上面的方法就可以了,當然為了美觀,部分數值是需要細調的,
最起碼每棵樹下面的花瓣這個方法不需要了,我們可以換成給整個區域的樹加上花瓣飄落效果,這裡給個森林例子
(沒有改花瓣):
1 # m 對應生成樹的數量 2 def run(m): 3 setup(1.0, 1.0) 4 for i in range(m): 5 penup() 6 x = randint(-500, 500) 7 y = randint(-300, 300) 8 goto(x ,y) 9 left(90) 10 tracer(False) 11 drawTree(10, 150) 12 petalPlace(100, x, y)