为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景


Posted in Python onJanuary 05, 2021

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

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

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

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

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

import numpy as np

plt.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 plt

def 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阶的科赫雪花。

为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景

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

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

def 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.2
    v = np.array((x-r/2, y))
    u = np.array((x+r/2, y))
    w = rotate(v-u, 60) + u
    
    data = 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()

为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景

到此这篇关于为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景的文章就介绍到这了,更多相关matplotlib绘制雪花和雪景内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python中zfill()方法的使用教程
May 20 Python
Python3实现从指定路径查找文件的方法
May 22 Python
Python3 处理JSON的实例详解
Oct 29 Python
Python cookbook(数据结构与算法)从字典中提取子集的方法示例
Mar 22 Python
django解决跨域请求的问题详解
Jan 20 Python
Python单例模式的四种创建方式实例解析
Mar 04 Python
python异常处理、自定义异常、断言原理与用法分析
Mar 23 Python
对python中list的五种查找方法说明
Jul 13 Python
如何基于python实现年会抽奖工具
Oct 20 Python
python 制作网站筛选工具(附源码)
Jan 21 Python
python中pandas.read_csv()函数的深入讲解
Mar 29 Python
Pytorch中的数据集划分&正则化方法
May 27 Python
Matplotlib中rcParams使用方法
Jan 05 #Python
matplotlib常见函数之plt.rcParams、matshow的使用(坐标轴设置)
Jan 05 #Python
matplotlib运行时配置(Runtime Configuration,rc)参数rcParams解析
Jan 05 #Python
matplotlib制作雷达图报错ValueError的实现
Jan 05 #Python
python实现三种随机请求头方式
Jan 05 #Python
scrapy实践之翻页爬取的实现
Jan 05 #Python
python里glob模块知识点总结
Jan 05 #Python
You might like
php计算数组不为空元素个数的方法
2014/01/27 PHP
浅析PHP微信支付通知的处理方式
2014/05/25 PHP
Laravel如何实现适合Api的异常处理响应格式
2020/06/14 PHP
nodejs实用示例 缩址还原
2010/12/28 NodeJs
Javascript继承机制的设计思想分享
2011/08/28 Javascript
JavaScript闭包 懂不懂由你反正我是懂了
2011/10/21 Javascript
Jquery实现仿腾讯娱乐频道焦点图(幻灯片)特效
2015/03/06 Javascript
JavaScript SweetAlert插件实现超酷消息警告框
2016/01/28 Javascript
js简单实现图片延迟加载的方法
2016/07/19 Javascript
详解JS-- 浮点数运算处理
2016/11/28 Javascript
AngularJS实现表单验证功能
2017/01/09 Javascript
解决给dom元素绑定click等事件无效问题的方法
2017/02/17 Javascript
vue实现登陆登出的实现示例
2017/09/15 Javascript
微信小程序实现换肤功能
2018/03/14 Javascript
详解vantUI框架在vue项目中的应用踩坑
2018/12/06 Javascript
JS简单判断是否在微信浏览器打开的方法示例
2019/01/08 Javascript
详解javascript中的Error对象
2019/04/25 Javascript
JavaScript实现网页跨年倒计时
2020/12/02 Javascript
[02:27]《DAC最前线》之附加赛征程
2015/01/29 DOTA
[50:58]2018DOTA2亚洲邀请赛 4.1 小组赛 B组 Mineski vs EG
2018/04/03 DOTA
Python实现递归遍历文件夹并删除文件
2016/04/18 Python
Python制作简易注册登录系统
2016/12/15 Python
python3+dlib实现人脸识别和情绪分析
2018/04/21 Python
Python中的异常处理try/except/finally/raise用法分析
2019/02/28 Python
django迁移数据库错误问题解决
2019/07/29 Python
使用Python脚本zabbix自定义key监控oracle连接状态
2019/08/28 Python
pytorch forward两个参数实例
2020/01/17 Python
python实现Oracle查询分组的方法示例
2020/04/30 Python
联想新西兰官方网站:Lenovo New Zealand
2018/10/30 全球购物
英国最受欢迎的平价女士时装零售商:Roman Originals
2019/11/02 全球购物
高中课程设置方案
2014/05/28 职场文书
大学生学习面向未来的赶考思想汇报
2014/09/12 职场文书
小学生成绩单评语
2014/12/31 职场文书
浅谈Golang 嵌套 interface 的赋值问题
2021/04/29 Golang
解读MySQL的客户端和服务端协议
2021/05/10 MySQL
十大最强岩石系宝可梦,怪颚龙实力最强,第七破坏力很强
2022/03/18 日漫