zoukankan      html  css  js  c++  java
  • Python画樱花树❀

    这篇文章参考了别人的博客《Python:绘制樱花树》

    原文作者:Ambitioner_c。他又参考了作者:沙漏在下雨

    哈哈……

    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 轴正方向。

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

    (二)效果

    整体效果还是挺美的。

    img


    版权声明:本文为CSDN博主「Ambitioner_c」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_41297934/article/details/105349790

  • 相关阅读:
    OpenGL入门学习
    linux下安装sqlite3
    SQLite 之 C#版 System.Data.SQLite 使用
    .net程序运行流程
    一种简单,轻量,灵活的C#对象转Json对象的方案
    C# 获取Windows系统:Cpu使用率,内存使用率,Mac地址,磁盘使用率
    WPF中选择文件及文件夹
    要想创业成功,千万不能在这十个方面走弯路
    [译]Quartz.Net 框架 教程(中文版)2.2.x 之第三课 更多关于Jobs和JobDetails
    [译]Quartz 框架 教程(中文版)2.2.x 之第二课 Quartz API,Jobs和Triggers简介
  • 原文地址:https://www.cnblogs.com/coding365/p/12872248.html
Copyright © 2011-2022 走看看