python canvas画弧度_用Python画樱花?想得美就能画得美(下)

上一篇我们介绍了一种手绘玫瑰的方法,你当然也可以用类似的方法画一朵或者几朵樱花 咯,看你的艺术底子了。

不过今天我们用优美的数学方法来画樱花,也会很漂亮的。

先画朵太阳花暖暖身吧。

import turtle                           # 导入海龟作图函数库
from mylib.myflowers import *           # 导入自定义的画花函数库

tt = turtle.Turtle()                    # 产生一个海龟,名叫tt
sunflower(tt,"orange")                  # 调用自定义的画太阳花的函数
tt.hideturtle()                         # 隐藏海龟箭头

turtle.done()                           # 画画结束

画出来的效果是这样的:

5d4d78193c24a324b07a34c95554d373.png

哇,这么有格局的太阳花,也只要五六行代码么?哦哦,没那么简单,我们只是把画花的部分自定义了一个函数sunflower( ),并且把它放到了另外一个文件里而已。注意到这句话了吗:

from mylib.myflowers import *          

它的意思就是从mylib.myflowers模块里,导入自定义的画花函数库。这个模块是一个名为myflowers.py文件,放在mylib目录下,如下图所示:

8d847fb9bebb1146454a4b87026068aa.png

这是在Pycharm里面的项目目录结构,其它平台上可能有所不同。并且,myflowers.py还用到了mymath.py,后者定义了最大公约数和最小公倍数怎么算(不要觉得脑壳疼,这是小学数学的内容而已喔)。这两个文件的源代码,请见本文附录,里面的数学公式看不懂略过亦无妨。

为什么要用到这些数学知识呢?因为我们是用一种叫做hypotrochoid(内转轨迹线)的方法在画图。名字很拗口,其实就是用一个小圈套在大圈里滚动作图而已。若有兴趣探究一下可以看看这个网站(Hypotrochoid)。

通过调整公式和参数,可以得到不同的轨迹线,也就可以组合出各种“花”来了。

下面我们画樱花,也是用到这种线中的一类,叫“玫瑰线”,名字好听一点吧?主程序如下:

import turtle
from random import *
from mylib.myflowers import *                               # 导入自定义的画花的函数库

win = turtle.Screen()
win.bgcolor('#8A5370')                                      # 背景设为深紫色
tt = turtle.Turtle()
color_table = ['#EBD6D9', '#C46C98', '#DB91B2']
size_table = [1, 1, 1, 1, 2, 2, 2, 3, 4]

N = 25                                                      # 一共画N朵樱花
for i in range(N):
    size = size_table[randint(0,len(size_table)-1)]         # 随机选择一种花瓣大小
    color = color_table[randint(0,len(color_table)-1)]      # 随机选择一种花瓣颜色
    angle = pi * random()                                   # 随机选择花瓣方向
    x0 = randint(0, 600) - 300                              # 随机选择位置横坐标
    y0 = randint(0, 600) - 300                              # 随机位置纵坐标
    sakura(tt, size, x0, y0, angle, color, 'fastest')       # 调用自定义画花函数库中的"樱花"函数

tt.hideturtle()                                             # 隐藏海龟箭头
turtle.done()

同样,我们用到了自定义画花函数模块中的一个函数,叫sakura( ),使用了很多参数,因为我们要画好多樱花,每一朵的位置、大小、方向、颜色都是随机产生的。这样更真实嘛!

8eb94413fd2614b1819f8b8fc16d3774.png
Python落樱图https://www.zhihu.com/video/1239311228306190336

好了,这就是我们今天画的“落樱图”。哈哈,我的艺术水平就止步于此了,看看你有没有更好的创意吧?

动手练习:

  1. 拷贝或到下面的github网址下载源代码,放到你的编程平台上,注意两个函数库模块文件,要保持原来的目录结构。调试运行无误。
  2. 随意调节myflowers.py文件中sunflower( )函数中的r、R、d三个参数,看看你会得到什么样不同的“花”。
  3. 自己写代码,画一个五角星,并填上金色。(提示:​你可以Google搜索“Python五角星”找现成的代码加以改造,或者完全自己写——例如画五条线段,每次转弯144度,或者严谨一点,画十条线段,转弯方法你得琢磨一下。)

Python自然学习法全部源代码网址:

  • https://github.com/globien/easy-python
  • https://gitee.com/globien/easy-python

相关阅读:用Python画樱花?想得美就能画得美(上)

这里是《简单又好玩的Python》,欢迎关注。


附录一:myflowers.py源代码

from math import *
from mylib.mymath import *              # 导入自定义的数学函数库

# 自定义太阳花函数
def sunflower(tt, color = 'orange'):
    r = 25
    R = 120
    d = 50
    tt.penup()
    tt.color(color)
    tt.pensize("2")
    tt.begin_fill()
    theta = 0
    while theta <= 2 * pi * least_common_multiple(r, R)/R + 0.01:  # 多画0.01弧度避免有缺陷
        x = (R-r) * cos(theta) + d * cos((R - r) / r * theta)
        y = (R-r) * sin(theta) - d * sin((R - r) / r * theta)
        tt.goto(x, y)
        tt.pendown()
        theta += pi/100
    tt.end_fill()



# 自定义樱花函数
def sakura(tt, size = 3, x0 = 0, y0 = 0, angle = 0, color ='#EBD6D9', speed = 'fastest'):

    # 画花瓣
    p = 5
    q = 3
    R = size * 15
    tt.penup()
    tt.color(color)
    tt.pensize("2")
    tt.begin_fill()
    tt.speed(speed)
    theta = 0
    while theta <= pi * q + 0.01:       # 多画0.01弧度避免缺陷
        x = R * cos(p / q * theta + angle) * cos(theta + angle) + x0
        y = R * cos(p / q * theta + angle) * sin(theta + angle) + y0
        tt.goto(x, y)
        tt.pendown()
        theta += pi/R
    tt.penup()
    tt.end_fill()

    # 画花蕊
    tt.color('#B17085')
    tt.begin_fill()
    r = size
    R = size * 5
    d = r * 1.3
    angle = angle * pi/5
    theta = 0
    while theta <= 2 * pi * least_common_multiple(r, R) / R + 0.01:  # 多画0.01弧度避免有缺陷
        x = (R - r) * cos(theta + angle) + d * cos((R - r) / r * theta + angle) + x0
        y = (R - r) * sin(theta + angle) - d * sin((R - r) / r * theta + angle) + y0
        tt.goto(x, y)
        tt.pendown()
        theta += pi / R
    tt.end_fill()
    tt.penup()


if __name__ == '__main__':                          # 测试用,仅在本文件为主程序时,才会执行下面的代码
    import turtle
    tt = turtle.Turtle()
    sunflower(tt,'orange')

    win = turtle.Screen()
    win.bgcolor('#8A5370')
    sakura(tt, 3, 0, 0, 0, "pink", 'fastest')

    tt.hideturtle()
    turtle.done()

附录二:mymath.py源代码

def greatest_common_divisor(m,n):
    while m!=n:
        if m > n :
            m = m - n
        else:
            n = n - m
    return m

def least_common_multiple(m,n):
    return m * n // greatest_common_divisor(m,n)

if __name__ == "__main__" :
    m,n = eval(input('请输入两个正整数(逗号隔开):'))
    print('m =',m, ', n =',n)
    print('它们的最大公约数是:', greatest_common_divisor(m,n))
    print('它们的最小公倍数是:', least_common_multiple(m,n))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值