为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 3.x 连接数据库示例(pymysql 方式)
Jan 19 Python
python将每个单词按空格分开并保存到文件中
Mar 19 Python
浅述python中深浅拷贝原理
Sep 18 Python
Python开发虚拟环境使用virtualenvwrapper的搭建步骤教程图解
Sep 19 Python
python3 pygame实现接小球游戏
May 14 Python
python实现将文件夹内的每张图片批量分割成多张
Jul 22 Python
Python调用钉钉自定义机器人的实现
Jan 03 Python
python sorted函数原理解析及练习
Feb 10 Python
超全Python图像处理讲解(多模块实现)
Apr 13 Python
Python代码执行时间测量模块timeit用法解析
Jul 01 Python
基于Python实现全自动下载抖音视频
Nov 06 Python
详解Python中openpyxl模块基本用法
Feb 23 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生成xml简单实例代码
2009/12/16 PHP
php+mysql事务rollback&commit示例
2010/02/08 PHP
JSON PHP中,Json字符串反序列化成对象/数组的方法
2018/05/31 PHP
php时间戳转换代码详解
2019/08/04 PHP
thinkphp 框架数据库切换实现方法分析
2020/05/18 PHP
利用onresize使得div可以随着屏幕大小而自适应的代码
2010/01/15 Javascript
jquery三个关闭弹出层的小示例
2013/11/05 Javascript
jQuery实现图片上传和裁剪插件Croppie
2015/11/29 Javascript
js倒计时简单实现代码
2016/08/11 Javascript
原生js获取浏览器窗口及元素宽高常用方法集合
2017/01/18 Javascript
js实现时间轴自动排列效果
2017/03/09 Javascript
利用JavaScript在网页实现八数码启发式A*算法动画效果
2017/04/16 Javascript
Vue动态实现评分效果
2017/05/24 Javascript
为什么我们要做三份 Webpack 配置文件
2017/09/18 Javascript
详解React native fetch遇到的坑
2018/08/30 Javascript
vue + any-touch实现一个iscroll 实现拖拽和滑动动画效果
2019/04/08 Javascript
JavaScript定时器设置、使用与倒计时案例详解
2019/07/08 Javascript
解决jquery validate 验证不通过后验证正确的信息仍残留在label上的方法
2019/08/27 jQuery
[51:10]VP vs VGJ.S 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
Python中使用haystack实现django全文检索搜索引擎功能
2017/08/26 Python
python gensim使用word2vec词向量处理中文语料的方法
2019/07/05 Python
Flask项目中实现短信验证码和邮箱验证码功能
2019/12/05 Python
python中的垃圾回收(GC)机制
2020/09/21 Python
Python对excel的基本操作方法
2021/02/18 Python
绝对令人的惊叹的CSS3折叠效果(3D效果)整理
2012/12/30 HTML / CSS
酒店管理专业学生求职信
2013/09/27 职场文书
植树节口号
2014/06/21 职场文书
小学安全工作总结2015
2015/05/18 职场文书
毕业生学校组织意见
2015/06/04 职场文书
初中生物教学随笔
2015/08/15 职场文书
校园广播稿范文
2015/08/19 职场文书
2016年秋季运动会加油稿
2015/12/21 职场文书
python引入其他文件夹下的py文件具体方法
2021/05/23 Python
Python标准库pathlib操作目录和文件
2021/11/20 Python
MySQL 计算连续登录天数
2022/05/11 MySQL
ubuntu开机后ROS程序自启动问题
2022/12/24 Servers