Python 画樱花树(樱花树下的约定)

前言

      樱花原产北半球温带环喜马拉雅山地区,在世界各地都有生长,主要在日本国生长。花每枝3到5朵,成伞状花序,花瓣先端缺刻,花色多为白色、粉红色。花常于3月与叶同放或叶后开花,随季节变化,樱花花色幽香艳丽,常用于园林观赏。樱花可分单瓣和复瓣两类,单瓣类能开花结果,复瓣类多半不结果。

       Python是一种跨平台的计算机程序设计语言。 是一个高层次的结合了解释性、译性、互动性和面向对象的脚本语言。最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。

       Turtle库是Python语言中一个很流行的绘制图像的函数库。

       想象一个小乌龟,在一个横轴为x、纵轴为y的坐标系原点,(0,0)位置开始,它根据一组函数指令的控制。

目录

一、代码详解

(一)绘制画幕

(二)绘制落花

(三)绘制树枝与花瓣

(四)绘制多棵树

 二、完整代码

(一)完整代码

(二)效果

在这个平面坐标系中移动,从而在它爬行的路径上绘制了图形。

一、代码详解
(一)绘制画幕
首先绘制画幕,命令说明如下:

1.screensize(width, height, bg=color):设置画幕大小及颜色
2.setup(p1, p2):设置画幕大小,当 p1、p2 为小数时表示屏幕占比;当 p1、p2 为整数时表示像素
3.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 轴正方向。

1.penup():起笔(可以想象成画画的时候沾墨之后提笔)
2.forward():向前移动
3.backward():向后移动
4.left(degree):逆时针旋转 degree 度
5.right(degree):顺时针旋转 degree 度
6.pendown():落笔
7.pencolor(color):笔墨颜色为 color
8.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()

(二)效果

整体效果还是挺美的。 

  • 9
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值