zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    axios baseURL
    TP5 nginx 配置
    Vue
    key
    curl openssl error
    vue use bulma
    《平凡的世界》
    《听听那冷雨》余光中
    心烦意乱
    祝你19岁生日快乐
  • 原文地址:https://www.cnblogs.com/wbsndbf/p/11431396.html
Copyright © 2011-2022 走看看