一场大雪,覆盖了华北、华东。天地连成一片,城市银装素裹,处处诗情画意、人人兴高采烈。朋友圈被雪景图和调侃路滑摔跤的段子刷屏,气氛比过年还要热烈几分。我也来凑个热闹,用python为2020年的第一场雪锦上添花。

绘制雪花图案,网上有很多文章介绍,但几乎都是用 Python 的内置模块 turtle 绘制的,这个模块适合用来引导孩子学习编程,很难真正用在项目开发上。也有用 pygame 实现的,不过 pygame 追求的是动画效果,雪花图案是随机生成的圆,效果很一般。

用 matplotlib 绘制雪花,重点是生成科赫曲线(Koch Curve)。科赫曲线是一种分形,其形态似雪花,又称科赫雪花、雪花曲线。给定线段pq,k阶科赫曲线可以由以下步骤生成:

  1. 找出三等分点u、v
  2. 以线段uv为底,向外(或内外)画等边三角形uwv
  3. 将线段uv移除
  4. 对pq之间的每一段重复上述操作k-1次

科赫雪花是以等边三角形三边生成的科赫曲线组成的。基于上述分析,我们可以很容易地写出科赫雪花的生成函数:给定一个等边三角形,和科赫曲线阶数k,返回科赫雪花图案中的所有点。

import numpy as npplt.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False #解决中文显示为方块的问题def rotate(p, d):"""返回点p绕原点逆时针旋转d度的坐标"""a = np.radians(d)m = np.array([[np.cos(a), np.sin(a)],[-np.sin(a), np.cos(a)]])return np.dot(p, m)def koch_curve(p, q):"""将线段pq生成科赫曲线,返回uvw三个点"""p, q = np.array(p), np.array(q)u = p + (q-p)/3 # 三等分点u的坐标v = q - (q-p)/3 # 三等分点V的坐标w = rotate(v-u, 60) + u # 线段uv绕u点逆时针旋转60°得到点w的坐标return u.tolist(), v.tolist(), w.tolist()def snow(triangle, k):"""给定三角形,生成封闭的科赫雪花"""for i in range(k):result = list()t_len = len(triangle)for j in range(t_len):p = triangle[j]q = triangle[(j+1)%t_len]u, v, w = koch_curve(p, q)result.extend([p, u, w, v])triangle = result.copy()triangle.append(triangle[0])return triangle

有了雪花图案的数据,接下来使用 matplotlib 绘图就非常轻松了:

import numpy as np
import matplotlib.pyplot as pltdef plot_snow(snow_list):"""绘制雪花"""for triangle, k in snow_list:data = np.array(snow(triangle, k))x, y = np.split(data, 2, axis=1)plt.plot(x, y)plt.axis('equal') plt.show()snow_list = [([(0,0), (0.5,0.8660254), (1,0)], 5),([(1.1,0.4), (1.35,0.8330127), (1.6,0.4)], 4),([(1.1,-0.1), (1.25,0.15980761), (1.4,-0.1)], 3)
]
plot_snow(snow_list)

来看看我们的雪花效果。从小到大,3片雪花分别对应的是3阶、4阶、5阶的科赫雪花。

更进一步,我们还可以把雪花画在背景图上,配合大小浓淡的变化,画出另一种韵味的雪景图。

import numpy as np
import matplotlib.pyplot as plt
from PIL import Imagedef draw_scenery():"""绘制雪景图"""im = Image.open('brage.png')bg = np.array(im)plt.imshow(bg) # 绘制背景图for i in range(80):x = np.random.randint(80, im.size[0]-80)y = np.random.randint(30, im.size[1]-30)r = np.random.randint(5, 20)a = np.random.random()*0.6 + 0.2v = np.array((x-r/2, y))u = np.array((x+r/2, y))w = rotate(v-u, 60) + udata = np.array(snow([(u[0],u[1]),(w[0],w[1]),(v[0],v[1])], 5))x, y = np.split(data, 2, axis=1)plt.plot(x, y, c='#AABBCC', lw=1, ls='-', alpha=a)plt.axis('equal') plt.show()draw_scenery()

为2020年的第一场雪锦上添花:用 matplotlib 绘制雪花和雪景相关推荐

  1. “北京今年入冬的第一场雪”,纪念博客园写日志一年了

    今天是2009年11月1日,北京下了入冬以来的第一场雪,就在昨天我还以为北京还是秋季,可是今天早上醒来看到外面飘落的大雪,已经意识到北京的冬天已经到来了 来博客园写博客一年了,结识了很多朋友,也为社区 ...

  2. 巴黎市中心降下2019年第一场雪

    当地时间1月22日,法国巴黎市中心降下2019年第一场雪,气温也随之下降,街上的行人和车辆均有所减少.中新社记者 李洋 摄 一对情侣在埃菲尔铁塔前合影留念. 无家可归者在长椅上睡觉. 游客在卢浮宫前拍 ...

  3. 【英语天天读】第一场雪

    作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ --Henry Wadsworth Longfellow The first snow came. How be ...

  4. hpuoj 1715: 感恩节KK专场——2015年的第一场雪 (暴力)

    1715: 感恩节KK专场--2015年的第一场雪 时间限制: 1 Sec  内存限制: 128 MB 提交: 884  解决: 82 [提交][状态][讨论版] 题目描述 下雪了,KK学长站在三教门 ...

  5. 2005年沈阳入冬第一场雪

    今天翻看图片文件夹,这才想起今年还有些雪景的照片.说起今年冬天,的确和往年不同,大连下了五十几年来罕见的大雪,山东烟台.威海也大雪封城-- 沈阳入冬的第一场雪也是不简单,甚是壮观! http://ai ...

  6. 2006年的第一场雪

    雪,冷酷,没有冰霜惨烈, 轻飘舞,是那般温柔,那般纯洁. 从天上降落人间,一尘不染, 始终保持固有的高风亮节. 你把江山变得更加壮丽, 赐予人类来年丰收的喜悦. 2006年的第一场雪,其实这应该是今年 ...

  7. 2010年东京的第一场雪

    今天是2010年2月的第一天,傍晚时分,东京终于下了入冬以来的第一场雪. 旧版的<标日初上>中有这样几句话:冬は北京より東京のほうが暖かいです.東京の冬は北京ほど寒くないです. 这本书是人 ...

  8. 2014年的第一场雪

    期待着,期盼着,东风来了,雪花的脚步也近了. 好不容易盼来了,今年的第一场雪.北方的气候干的要命,跨年小感冒现在仍旧流行着,田地里也是干的不行了,是时候滋润一下干涸的土地了. 雪中的小狗狗 对面的超市 ...

  9. 2009年成都的第一场雪

    2009年成都的第一场雪比以往来得更早一些 有报道说是9年来最早的一场雪,只是有点水,没飘多久,而且落下来立马就化了,不过已经着实让我们这些来成都7年没见下雪的高兴了一把 附上来自网络的打油诗一首 - ...

最新文章

  1. Java求n以内素数_求0到n之间素数个数的序列(Java)
  2. swiper轮播后hover无效问题解决案例
  3. pythontemp_python 临时文件夹 的 tempfile模块学习
  4. mysql怎么获取系统_MySQL获取系统性能和状态代码
  5. C++_选择结构_循环结构_for循环_敲桌子案例_嵌套循环_乘法口诀案例_跳转语句break---C++语言工作笔记018
  6. 多线程设计模式(二):Future模式
  7. dos.ORM配置和使用
  8. 哪些场景应用了dsrc通信标准_如何提高量子通信系统的实用性,制约了量子通信系统的应用场景...
  9. Atiitt 管理方面的误区总结 attilax总结
  10. 08cms cecore.cls.php,动态分析小示例|08CMS SQL 注入分析
  11. 计算机推免经验分享——中科院信工所
  12. 华为OD机试题:统计射击比赛成绩
  13. kubernetes部署kubesphere
  14. 详解爬虫模拟登陆的三种方法
  15. Mysql-计算两个时间之间的差值
  16. python线程和c++线程的区别_Python、线程、吉尔和C++
  17. JAVA电影院售票网站计算机毕业设计Mybatis+系统+数据库+调试部署
  18. web上传文件到ftp服务器,web 上传文件到ftp服务器上
  19. git重置用户git账号金与密码
  20. 神经科学探索脑第二章答案

热门文章

  1. 从本子文件名中提取本子的名字
  2. Latex中自动引用参考文献的方法,一分钟搞定
  3. Fintech公开课丨黄嵩:数字化转型本质论
  4. java网络加载协议JNLP的应用
  5. 申请国外博士后的好网站
  6. 实例003:完全平方数 一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
  7. 聊聊身边的嵌入式,自拍神器自拍杆
  8. 【c#】键盘事件(keypress keydown keyup)
  9. 2017年java笔试题_初级java程序员笔试题
  10. Godfather POJ - 3107 树的重心