查看原文
其他

用Python标准库turtle画一只老虎,祝您新年虎虎生威,大吉大利!

IT服务圈儿 2022-09-10

The following article is from Python 碎片 Author 小斌哥r

来源丨经授权转自 Python 碎片(ID:python-suipian)

作者丨小斌哥r



虎年到了,祝大家新年虎虎生威!大吉大利!


去年我用Python画了一头金牛,参考:Python画金牛


今年朋友问我什么时候能画一只老虎。不能辜负朋友的期待,还是一样的流程,在百度图片里下载了一张虎年的图片(原图局部见上图),然后开始肝代码。
我把绘图过程录成了视频,点击视频可以先看到效果。


结果与原图对比




与原图对比,我自己认为还原度是高于95%的。


部分细节无法完全还原,或是代码调试的时间不够。感兴趣的朋友可以联系我获取代码,更进一步优化细节。


用到的方法



使用的都是turtle库中的函数,直接导入turtle库即可调用。


去年的文章已经详细介绍使用的方法了,为了方便,本文将这些方法再列一遍,已经知道的可以直接下滑跳过此部分。


1. 画布设置

setup(width, height, x, y): 设置窗口大小和窗口左上角在屏幕中的位置。title(): 设置窗口的标题。screensize(width, height, color): 设置画布大小,背景颜色。done(): 绘图结束后,不自动关闭窗口。


2. 画笔设置

pencolor(color): 设置画笔颜色。width(): 设置画笔宽度。speed(int): 设置画笔的速度,传入1~10的数字,1最慢,10最快。传入其他值会更快,但是没有鼠标移动的动画效果。penup(): 提起画笔,提起后移动画笔不会留下痕迹。pendown(): 落下画笔,开始绘图前先将画笔落下。setx(value): 设置画笔的x轴坐标。sety(value): 设置画笔的y轴坐标。towards(x, y): 设置画笔指向的点。

setheading(): 设置画笔的方向。与towards()配合可以设置画笔指向某个点,如setheading(towards(0, 0))可以设置画笔指向原点。

pos(): 返回画笔当前的坐标。鼠标移动一段时间后可以print()打印此函数获取鼠标位置。heading(): 返回画笔当前的方向。


3. 画笔操作

circle(radius[, extent=arc]): 画一个圆,传入圆的半径,根据画笔的方向控制圆心的位置,圆心与画笔的方向垂直。传入弧度值可以画出指定弧度的圆弧。left(angle): 画笔左转,传入任意一个目标角度。right(angle): 画笔右转。forward(distance): 画笔前进一段距离。backward(distance): 画笔后退一段距离。goto(x, y): 移动画笔到指定坐标。


4. 颜色填充

begin_fill(): 开始填充。fillcolor(color): 设置图形中填充的颜色。end_fill(): 结束填充。


自定义的函数



为了精简代码,我自己定义了几个函数,在后面的代码中重复利用。
  • 设置画笔到某一个点,每画一部分图形的开头都可以直接调用,COLOR是定义的一个全局变量。


def set_start(x, y, w, c=COLOR):
    penup()
    setx(x)
    sety(y)
    setheading(towards(00))
    width(w)
    pencolor(c)
    pendown()
    speed(0)


  • 将转向和移动的代码封装,转不同角度和移动不同的距离可以画出不同的弧线,封装后会节省非常多的代码。


def left_rotate(time, angle, length):
    for i in range(time):
        left(angle)
        forward(length)


  • 填充颜色定义成装饰器,当某部分图形完成时,加上装饰器即可完成颜色填充。


def fill_color(color):
    def decorator_all(func):
        def wrapper(*args, **kwargs):
            begin_fill()
            func(*args, **kwargs)
            fillcolor(color)
            end_fill()
        return wrapper
    return decorator_all


  • 填充颜色的补丁函数。


turtle库填充颜色时会去关联上一个图形的终点,大部分情况填充颜色都没有问题,但少数情况下填充结果不符合预期。


我没有花时间去翻官方有没有这样的issue,自己写了个补丁函数,重置上一个图形的终点(重点:重置的是上一个),当填充颜色不符合预期时,打上补丁。补丁函数中调用了前面定义的set_start(),在要填充图形的起点画个点。


def fill_color_patch(x, y, c='#fffffb'):
    set_start(x, y, 1, c=c)
    forward(1)


经验总结



  • 画图前先分析一下图形。


先定一个坐标原点,图形的每个部分都根据原点去找位置,这样可以避免图形出现大的偏差。
  • 顺序很重要。


有些部分之间的先后顺序不能反,主要影响的是颜色填充,这点也是图形分析时要注意的,分析好图层顺序。
  • 灵活运用。


目标是最大可能完成图像,如果能画得更好,代码增加很多,也是值得的。自定义的函数,适用就用,不适用的地方就算了。
  • 耐心很重要。


用的是基本库,基本的函数,就那么几个,其实技术没那么重要,重要的是耐心。画得不像不怕,多试几次就行了。


代码拿去吧



我已经尽力精简代码了,但还是超过了1000行,本文就不全贴了。


后台回复“虎虎生威”关键字获取完整代码。




1、Windows11竟然推送1968年的驱动?微软做出回应

2、国外最近突然爆火的「Wordle」是什么鬼?

3、Spring Boot 3.0 M1 发布,正式弃用 Java 8,最低要求 Java 17。。。

4、真正的摸鱼利器,抖音推出PC版!!

5、全公司电脑Alt键被抠掉,就为防员工摸鱼……

点分享

点点赞

点在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存