Python:绘制樱花树

Viveka ·
更新时间:2024-11-13
· 836 次阅读

这篇文章参考了别人的博客《三月桃花开,用python给你带来你的桃花运,详细解析画一棵表白树》[1],原文作者:沙漏在下雨,这里简单记录一下学习过程。

这里使用的是 python turtle 模块,如果读者使用的是 Pycharm ,在使用 turtle 时会存在一些问题,可以看我的另一篇博客《Ubuntu:解决PyCharm中turtle模块无法使用的问题》[2]

目录

一、代码详解

(一)绘制画幕

(二)绘制落花

(三)绘制树枝与花瓣

(四)绘制多棵树

 二、完整代码

(一)完整代码

(二)效果

一、代码详解 (一)绘制画幕

首先绘制画幕,命令说明如下:

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):画一个半径为 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() (二)效果

整体效果还是挺美的。 

[1] https://blog.csdn.net/qq_45906219/article/details/104721978

[2] https://blog.csdn.net/qq_41297934/article/details/105331153

[3] https://blog.csdn.net/qq_36804363/article/details/88374263


作者:Ambitioner_c



Python 樱花

需要 登录 后方可回复, 如果你还没有账号请 注册新账号