在“用渐变色绘制科赫雪花”中介绍了用HSV颜色模型生成渐变色的方法。本篇介绍用多支“笔”绘制螺旋效果渐变万花筒。
Python的Turtle可以定义多支“笔”,每支笔都是独立的,因此换笔时就不需要“抬笔”、“移动(旋转)”和“落笔”。
一、生成原理
每支“笔”从0到counts为直径绘制圆或内接正多边形,每一组相隔一定距离绘制相同直径圆或内接正多边形然后再相隔一定距离并转过一定角度再画另一直径的另一组,形成一串直径由小到大的呈螺旋形的圆或内接正多边组成的螺旋图形。
图1 一支笔画的“渐变螺旋图形”
然后,N支“笔”旋转一定转角现画同样的渐变螺旋图形,就可绘制万花筒。
二、turtle的tracer()和update()
为了加快速度,turtle的tracer()方法。
turtle.tracer()方法用于打开或关闭turtle动画并设置更新图纸的延迟。语法如下:
turtle.tracer(n=None, delay=None)
其中:n——非负整型数,如果指定n的值,则只有每第n次屏幕刷新会实际执行(可被用来加速复杂图形的绘制)。 如果调用时不带参数,则返回当前保存的n值(默认为1);delay——非负整型数,设置延迟值(默认为10ms)
turtle.tracer(False)或者turtle.tracer(0):图形将一次性画好
turtle.tracer(1):图形按照正常速度进行,可有可无
turtle.tracer(4):在循环中,图形将一次画出4次循环的图
turtle.update():执行一次TurtleScreen刷新,将缓冲区图像显示在屏幕上。
可以用turtle的tracer(0)方法关闭绘图过程显示,画完之后直接显示,所以超快,但有可能在绘图缓冲区残留图形,需用turtle的update()方法更新,以确保图形完整显示。
三、绘图函数的参数
本篇绘制渐变万花筒的函数使用了多个参数,包括:
back_color:背景色,即画布颜色
speed:Turtle绘图速度,0-10,0最快,1最慢
deg:旋转角度,控制螺旋幅度
pens:画笔数(pens条螺旋图案)
rpt:重复次数,一组图案由多少个直径相同的图案构成
ratio:缩放比例,控制图形大小
counts:一条螺旋图案由多少不同直径组图案组成
edges:用圆还是多边形绘制图案,0为圆,其他为正多边形边数
本篇程序中给出了两组参数,可绘制两种不同效果的“万花筒”图案。读者也可自行调整各个参数值,以获取不同的效果的“万花筒”图案。
四、完整代码
import turtle
from colorsys import hsv_to_rgb
def draw(pen, lt_deg, rt_deg, rpt, ratio, counts, edges=0):
for i in range(counts):
pen_color = hsv_to_rgb(i/counts, 1, 1) # h从0到1,颜色从红渐变到黄、绿、青、洋红、红
pen.color(pen_color) # 设置笔颜色
if edges: # 参数不为0画多边形
for _ in range(rpt): # 一组同直径内拉正多边形组成的图案
pen.circle(i*ratio, steps=edges)
pen.circle(5*i*ratio,lt_deg/2)
pen.circle(i*ratio, steps=edges)
pen.rt(rt_deg/2)
pen.circle(5*i*ratio,lt_deg/2)
pen.lt(lt_deg/2)
else: # 参数为0画圆
for _ in range(rpt): # 一组同直径圆组成的图案
pen.circle(i*ratio)
pen.circle(5*i*ratio,lt_deg/2)
pen.circle(i*ratio)
pen.rt(rt_deg/2)
pen.circle(5*i*ratio,lt_deg/2)
pen.lt(lt_deg/2)
def kaleido(back_color, speed, deg, pens, rpt, ratio, counts, edges=0):
'''参数:
back_color:背景色,即画布颜色
speed:Turtle绘图速度,0-10,0最快,1最慢
deg:旋转角度,控制螺旋幅度
pens:画笔数(pens条螺旋图案)
rpt:重复次数,一组图案由多少个直径相同的图案构成
ratio:缩放比例,控制图形大小
counts:一条螺旋图案由多少不同直径组图案组成
edges:用圆还是多边形绘制图案,0为圆,其他为正多边形边数
'''
turtle.bgcolor(back_color) # 设置背景色(画布颜色)
turtle.screensize(1024, 1024) # 设置画布大小
turtle.ht() # 隐藏海龟形状
turtle.tracer(0) # 不显示绘图过程,画完直接显示
for i in range(pens):
pen = turtle.Pen() # 定义新画笔
pen.speed(speed) # 设置绘图速度
pen.lt(i * 360/pens) # 每支笔的起始角度
draw(pen, deg, deg, rpt, ratio, counts, edges)# 调用一支笔draw绘图
turtle.update() # 防止显示不完整
turtle.done()
if __name__ == "__main__":
#kaleido(back_color="white", speed=0, deg=45, pens=12, rpt=4, ratio=1, counts=40, edges=3)
kaleido(back_color="black", speed=0, deg=30, pens=10, rpt=3, ratio=3, counts=20, edges=5)
五、运行效果
用“kaleido(back_color="black", speed=0, deg=30, pens=10, rpt=3, ratio=3, counts=20, edges=5)”执行程序可获得如下图案:
图2 十支笔用正五边形绘制的黑底“渐变螺旋图形”
用“kaleido(back_color="white", speed=0, deg=45, pens=12, rpt=4, ratio=1, counts=40, edges=3)”执行程序可获得如图3所示图案。
图3 十二支笔用正三边形绘制的折底“渐变螺旋图形”