這篇文章參考了別人的博客《Python:繪制櫻花樹》
原文作者:Ambitioner_c。他又參考了作者:沙漏在下雨
哈哈……
一、代碼詳解
(一)繪制畫幕
首先繪制畫幕,命令說明如下:
screensize(width, height, bg=color):設置畫幕大小及顏色
setup(p1, p2):設置畫幕大小,當 p1、p2 為小數時表示屏幕占比;當 p1、p2 為整數時表示像素
tracer(speed):設置繪制速度,speed越大表示繪制速度越快
def get_screen(width, height, color, speed):
# 創建畫幕
screen_obj = turtle.Screen()
# 畫布大小:(width, height),顏色:color
screen_obj.screensize(width, height, bg=color)
screen_obj.setup(1.0, 1.0)
# speed倍加速
screen_obj.tracer(speed)
return screen_obj
(二)繪制落花
在確定落花數量的情況下,我們首先要評估落花的范圍,這里通過兩句語句來約束落花的范圍(落花數量越多,當然地落花范圍也就越大):
# 有正有負就可以讓畫筆往二個方向走
x = flower - 4 * flower * random()
# 花瓣整體寬度(-10, 10)
y = 10 - 20 * random()
然后我們來講講 turtle 常用的幾個命令吧:
首先,我們得明確,對於 turtle 畫布來說,其為一個 xOy 的平面,畫布中心為原點 O ;對於 turtle 畫筆來說,其有一個初始方向,指向 x 軸正方向。
- penup():起筆(可以想象成畫畫的時候沾墨之后提筆)
- forward():向前移動
- backward():向后移動
- left(degree):逆時針旋轉 degree 度
- right(degree):順時針旋轉 degree 度
- pendown():落筆
- pencolor(color):筆墨顏色為 color
- circle®:畫一個半徑為 r 的圓
代碼如下:
def draw_petal(turtle_obj, flower):
# 繪制掉落的花瓣
for i in range(int(flower / 2)):
# 有正有負就可以讓畫筆往二個方向走
x = flower - 2 * flower * random()
# 花瓣整體寬度(-10, 10)
y = 10 - 20 * random()
# 提筆,向前y,左轉90,走x,落筆
turtle_obj.penup()
turtle_obj.forward(y)
turtle_obj.left(90)
turtle_obj.forward(x)
turtle_obj.pendown()
# 珊瑚色
turtle_obj.pencolor("lightcoral")
# 畫圓
turtle_obj.circle(1)
# 回到起點
# 提筆,后退x,右轉90,后退y,落筆
turtle_obj.penup()
turtle_obj.backward(x)
turtle_obj.right(90)
turtle_obj.backward(y)
turtle_obj.pendown()
(三)繪制樹枝與花瓣
讀者會發現,在 drwa_tree 方法中,又出現了兩次 drwa_tree 方法,這是一個遞歸的方法,可以簡單理解為一棵樹最下面的樹枝最少且最粗,越往上樹枝數量增加但是變細了。如果讀者看不懂如下代碼的話,可以查看《Turtle(python)畫分形樹理解遞歸》[3]文章。
def draw_tree(turtle_obj, branch, tree_color):
# 設置一個最小分支長度
min_branch = 4
if branch > min_branch:
if branch < 8:
# 以0.5的概率,向左、右分支
if randint(0, 1) == 0:
# 左為白色
turtle_obj.pencolor("snow")
else:
# 右為珊瑚色
turtle_obj.pencolor("lightcoral")
# 枝干
turtle_obj.pensize(branch / 2)
elif 8 <= branch <= 16:
# 以0.33的概率,分為左、中、右分支
if randint(0, 2) == 0:
# 左為白色
turtle_obj.pencolor("snow")
else:
# 中、右為珊瑚色
turtle_obj.pencolor("lightcoral")
# 樹枝
turtle_obj.pensize(branch / 4)
else:
# 褐色
turtle_obj.pencolor(tree_color)
# 細枝
turtle_obj.pensize(branch / 10)
# 最開始的樹干長度
turtle_obj.forward(branch)
# 隨機度數因子
a = 1.5 * random()
# 順時針旋轉隨機角度(0~30度)
turtle_obj.right(20 * a)
# 隨機長度因子
b = 1.5 * random()
# 往右畫,直到畫不動為止
draw_tree(turtle_obj, branch - 10 * b, tree_color)
# 左轉隨機角度
turtle_obj.left(40 * a)
# 往左畫,直到畫不動位置
draw_tree(turtle_obj, branch - 10 * b, tree_color)
# 右轉一定角度
turtle_obj.right(20 * a)
# 提筆
turtle_obj.penup()
# 遞歸結束回到起點
turtle_obj.backward(branch)
turtle_obj.pendown()
(四)繪制多棵樹
這部分代碼的前半部分是用來約束樹根的位置的,為了使樹可以在圖像中顯示地較為完成,較大的樹根應該更靠近於畫幕底端,且不能太靠近兩邊,其余部分代碼就很容易理解了。
def trees(tree_num):
# 顏色
color = ['brown', 'tan', 'black']
for j in range(tree_num):
# 樹干顏色
tree_color = color[randint(0, len(color) - 1)]
# 畫筆大小
pensize = randint(2, 5)
# 前進像素
forward = ((-1) ** pensize) * pensize * randint(20, 50)
# 后退像素
if pensize <= 3:
backward = ((-1) ** pensize) * (5 - pensize) * randint(10, 15)
else:
backward = pensize * randint(45, 50)
# 創建畫筆
turtle_obj = turtle.Turtle()
# 畫筆粗細
turtle_obj.pensize(pensize)
# 提筆,向前forward,左轉90,backward,落筆
turtle_obj.penup()
turtle_obj.forward(forward)
turtle_obj.left(90)
turtle_obj.backward(backward)
turtle_obj.pendown()
# 畫筆顏色:褐色
turtle_obj.pencolor(tree_color)
# 枝干粗細
branch = pensize * 15
# 落花數
flowers = branch
# 第j棵樹
draw_tree(turtle_obj, branch, tree_color)
# 花瓣
draw_petal(turtle_obj, flowers)
二、完整代碼
(一)完整代碼
給出完整代碼:
import turtle
from random import random
from random import randint
def draw_petal(turtle_obj, flower):
# 繪制掉落的花瓣
for i in range(int(flower)):
# 有正有負就可以讓畫筆往二個方向走
x = flower - 4 * flower * random()
# 花瓣整體寬度(-10, 10)
y = 10 - 20 * random()
# 提筆,向前y,左轉90,走x,落筆
turtle_obj.penup()
turtle_obj.forward(y)
turtle_obj.left(90)
turtle_obj.forward(x)
turtle_obj.pendown()
# 珊瑚色
turtle_obj.pencolor("lightcoral")
# 畫圓
turtle_obj.circle(1)
# 回到起點
# 提筆,后退x,右轉90,后退y,落筆
turtle_obj.penup()
turtle_obj.backward(x)
turtle_obj.right(90)
turtle_obj.backward(y)
turtle_obj.pendown()
# 畫樹枝部分
def draw_tree(turtle_obj, branch, tree_color):
# 設置一個最小分支長度
min_branch = 4
if branch > min_branch:
if branch < 8:
# 以0.5的概率,向左、右分支
if randint(0, 1) == 0:
# 左為白色
turtle_obj.pencolor("snow")
else:
# 右為珊瑚色
turtle_obj.pencolor("lightcoral")
# 枝干
turtle_obj.pensize(branch / 2)
elif 8 <= branch <= 16:
# 以0.33的概率,分為左、中、右分支
if randint(0, 2) == 0:
# 左為白色
turtle_obj.pencolor("snow")
else:
# 中、右為珊瑚色
turtle_obj.pencolor("lightcoral")
# 樹枝
turtle_obj.pensize(branch / 4)
else:
# 褐色
turtle_obj.pencolor(tree_color)
# 細枝
turtle_obj.pensize(branch / 10)
# 最開始的樹干長度
turtle_obj.forward(branch)
# 隨機度數因子
a = 1.5 * random()
# 順時針旋轉隨機角度(0~30度)
turtle_obj.right(20 * a)
# 隨機長度因子
b = 1.5 * random()
# 往右畫,直到畫不動為止
draw_tree(turtle_obj, branch - 10 * b, tree_color)
# 左轉隨機角度
turtle_obj.left(40 * a)
# 往左畫,直到畫不動位置
draw_tree(turtle_obj, branch - 10 * b, tree_color)
# 右轉一定角度
turtle_obj.right(20 * a)
# 提筆
turtle_obj.penup()
# 遞歸結束回到起點
turtle_obj.backward(branch)
turtle_obj.pendown()
def get_screen(width, height, color, speed):
# 創建畫幕
screen_obj = turtle.Screen()
# 畫布大小:(width, height),顏色:color
screen_obj.screensize(width, height, bg=color)
screen_obj.setup(1.0, 1.0)
# speed倍加速
screen_obj.tracer(speed)
return screen_obj
def trees(tree_num):
# 顏色
color = ['brown', 'tan', 'black']
for j in range(tree_num):
# 樹干顏色
tree_color = color[randint(0, len(color) - 1)]
# 畫筆大小
pensize = randint(2, 5)
# 前進像素
forward = ((-1) ** pensize) * pensize * randint(20, 50)
# 后退像素
if pensize <= 3:
backward = ((-1) ** pensize) * (5 - pensize) * randint(10, 15)
else:
backward = pensize * randint(45, 50)
# 創建畫筆
turtle_obj = turtle.Turtle()
# 畫筆粗細
turtle_obj.pensize(pensize)
# 提筆,向前forward,左轉90,backward,落筆
turtle_obj.penup()
turtle_obj.forward(forward)
turtle_obj.left(90)
turtle_obj.backward(backward)
turtle_obj.pendown()
# 畫筆顏色:褐色
turtle_obj.pencolor(tree_color)
# 枝干粗細
branch = pensize * 15
# 落花數
flowers = branch
# 第j棵樹
draw_tree(turtle_obj, branch, tree_color)
# 花瓣
draw_petal(turtle_obj, flowers)
if __name__ == '__main__':
# 創建畫幕
my_screen_width = 800
my_screen_height = 600
my_screen_color = 'wheat'
my_screen_speed = 5
my_screen_obj = get_screen(my_screen_width, my_screen_height,
my_screen_color, my_screen_speed)
# 櫻花樹
# 棵數
my_tree_num = 5
trees(my_tree_num)
# 點擊關閉畫布
my_screen_obj.exitonclick()
(二)效果
整體效果還是挺美的。
版權聲明:本文為CSDN博主「Ambitioner_c」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_41297934/article/details/105349790