Python 绘制谢尔宾斯基地毯图片(2020年3月23日)
制作背景
大一下学期,疫情时代在家。学习了PIL绘制图案,忽然想到了可以用来绘制以前见过的一些有意思的分型图案,于是就来写了一个绘制谢尔宾斯基地毯的图片
谢尔宾斯基地毯是一个正方形,正中间扣掉九分之一面积大小的正方形,然后再在剩下的8个部分扣掉每个部分正中心的正方形,这样就可以无限扣下去了。但是程序有限,我用的是矢量图来绘制,所以执行的级数有限。根据计算发现,增长的级数和图像边长的大小是指数增长关系。(一级表示只在中间扣一次,最小可以3×3表示)。9级的谢尔宾斯基地毯的图片大小已经是(19683×19683)了,打开这正图片都已经非常卡顿了。
效果图片
源代码
"""
此程序输出一个谢尔宾斯基地毯的图片
2020年3月23日
by littlefean
"""
from PIL import Image
from time import time
def put_color(img, x_p, y_p, long, color):
"""
填充一定范围内的颜色
:param x_p: 填充正方形的x位置
:param y_p: 填充正方形的y位置
:param img: 图片名
:param long: 正方形的边长
:param color: 填充颜色
:return:
"""
if long == 0:
img.putpixel((x_p, y_p), color)
for n in range(long):
for m in range(long):
img.putpixel((x_p + n, y_p + m), color)
if __name__ == '__main__':
t1 = time()
Level = 9
im = Image.new('RGB', (3 ** Level, 3 ** Level), 'black')
for i in range(Level):
k = 0 # 换行计数
px = 3 ** i
py = 3 ** i
for j in range(9 ** (Level - 1 - i)):
put_color(im, px, py, int(3 ** i), (255, 255, 255))
k += 1
px += int(3 ** (i + 1))
if k == int(3 ** (Level - 1 - i)):
# 横向归零,竖向下一
px = int(3 ** i)
py += int(3 ** (i + 1))
k = 0
im.save(f'mat_{Level}.png')
t2 = time()
print(t2 - t1)
input()
反思
现在已经是2020年11月1日了,我发现我之前写的程序并不是很好,首先算法并不好,执行速度很慢。其次填充正方形PIL好像是有内置方法的。而我这样自己造的轮子也一定程度上影响了程序的效率。下次我再改进这个程序的时候或者做类似的程序的时候我会用递归来做。当时还并不会递归。