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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM